mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Merge pull request #2894 from haircommander/chdir-fix-2
libct/init_linux: retry chdir to fix EPERM (regression in rc93)
This commit is contained in:
@@ -131,6 +131,26 @@ func finalizeNamespace(config *initConfig) error {
|
||||
return errors.Wrap(err, "close exec fds")
|
||||
}
|
||||
|
||||
// we only do chdir if it's specified
|
||||
doChdir := config.Cwd != ""
|
||||
if doChdir {
|
||||
// First, attempt the chdir before setting up the user.
|
||||
// This could allow us to access a directory that the user running runc can access
|
||||
// but the container user cannot.
|
||||
err := unix.Chdir(config.Cwd)
|
||||
switch {
|
||||
case err == nil:
|
||||
doChdir = false
|
||||
case os.IsPermission(err):
|
||||
// If we hit an EPERM, we should attempt again after setting up user.
|
||||
// This will allow us to successfully chdir if the container user has access
|
||||
// to the directory, but the user running runc does not.
|
||||
// This is useful in cases where the cwd is also a volume that's been chowned to the container user.
|
||||
default:
|
||||
return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
|
||||
}
|
||||
}
|
||||
|
||||
caps := &configs.Capabilities{}
|
||||
if config.Capabilities != nil {
|
||||
caps = config.Capabilities
|
||||
@@ -152,10 +172,8 @@ func finalizeNamespace(config *initConfig) error {
|
||||
if err := setupUser(config); err != nil {
|
||||
return errors.Wrap(err, "setup user")
|
||||
}
|
||||
// Change working directory AFTER the user has been set up.
|
||||
// Otherwise, if the cwd is also a volume that's been chowned to the container user (and not the user running runc),
|
||||
// this command will EPERM.
|
||||
if config.Cwd != "" {
|
||||
// Change working directory AFTER the user has been set up, if we haven't done it yet.
|
||||
if doChdir {
|
||||
if err := unix.Chdir(config.Cwd); err != nil {
|
||||
return fmt.Errorf("chdir to cwd (%q) set in config.json failed: %v", config.Cwd, err)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ function teardown() {
|
||||
|
||||
# Verify a cwd owned by the container user can be chdir'd to,
|
||||
# even if runc doesn't have the privilege to do so.
|
||||
@test "runc create sets up user before chdir to cwd" {
|
||||
@test "runc create sets up user before chdir to cwd if needed" {
|
||||
requires rootless rootless_idmap
|
||||
|
||||
# Some setup for this test (AUX_DIR and AUX_UID) is done
|
||||
@@ -56,3 +56,19 @@ function teardown() {
|
||||
runc run test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
# Verify a cwd not owned by the container user can be chdir'd to,
|
||||
# if runc does have the privilege to do so.
|
||||
@test "runc create can chdir if runc has access" {
|
||||
requires root
|
||||
|
||||
mkdir -p rootfs/home/nonroot
|
||||
chmod 700 rootfs/home/nonroot
|
||||
|
||||
update_config ' .process.cwd = "/root"
|
||||
| .process.user.uid = 42
|
||||
| .process.args |= ["ls", "/tmp"]'
|
||||
|
||||
runc run test_busybox
|
||||
[ "$status" -eq 0 ]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user