Skip to content

Commit 77f9210

Browse files
committed
fix stdio permission error for runc run with detach
Signed-off-by: lifubang <[email protected]>
1 parent 69e6b27 commit 77f9210

File tree

3 files changed

+14
-9
lines changed

3 files changed

+14
-9
lines changed

libcontainer/init_linux.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,7 @@ func setupConsole(socket *os.File, config *initConfig, mount bool) error {
374374
// used to change the owner of the slave path, but since the /dev/pts mount
375375
// can have gid=X set (at the users' option). So touching the owner of the
376376
// slave PTY is not necessary, as the kernel will handle that for us. Note
377-
// however, that setupUser (specifically fixStdioPermissions) *will* change
377+
// however, that setupUser (specifically FixStdioPermissions) *will* change
378378
// the UID owner of the console to be the user the process will run as (so
379379
// they can actually control their console).
380380

@@ -503,7 +503,7 @@ func setupUser(config *initConfig) error {
503503

504504
// Before we change to the container's user make sure that the processes
505505
// STDIO is correctly owned by the user that we are switching to.
506-
if err := fixStdioPermissions(execUser); err != nil {
506+
if err := FixStdioPermissions(execUser.Uid); err != nil {
507507
return err
508508
}
509509

@@ -550,10 +550,10 @@ func setupUser(config *initConfig) error {
550550
return nil
551551
}
552552

553-
// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
553+
// FixStdioPermissions fixes the permissions of STDIO within the container to the specified user.
554554
// The ownership needs to match because it is created outside of the container and needs to be
555555
// localized.
556-
func fixStdioPermissions(u *user.ExecUser) error {
556+
func FixStdioPermissions(uid int) error {
557557
var null unix.Stat_t
558558
if err := unix.Stat("/dev/null", &null); err != nil {
559559
return &os.PathError{Op: "stat", Path: "/dev/null", Err: err}
@@ -566,7 +566,7 @@ func fixStdioPermissions(u *user.ExecUser) error {
566566

567567
// Skip chown if uid is already the one we want or any of the STDIO descriptors
568568
// were redirected to /dev/null.
569-
if int(s.Uid) == u.Uid || s.Rdev == null.Rdev {
569+
if int(s.Uid) == uid || s.Rdev == null.Rdev {
570570
continue
571571
}
572572

@@ -576,7 +576,7 @@ func fixStdioPermissions(u *user.ExecUser) error {
576576
// that users expect to be able to actually use their console. Without
577577
// this code, you couldn't effectively run as a non-root user inside a
578578
// container and also have a console set up.
579-
if err := file.Chown(u.Uid, int(s.Gid)); err != nil {
579+
if err := file.Chown(uid, int(s.Gid)); err != nil {
580580
// If we've hit an EINVAL then s.Gid isn't mapped in the user
581581
// namespace. If we've hit an EPERM then the inode's current owner
582582
// is not mapped in our user namespace (in particular,

tty.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,16 @@ func setupProcessPipes(p *libcontainer.Process, containerUID, containerGID int)
6363
return t, nil
6464
}
6565

66-
func inheritStdio(process *libcontainer.Process) {
66+
func inheritStdio(process *libcontainer.Process, containerUID int) error {
67+
if containerUID != os.Getuid() {
68+
if err := libcontainer.FixStdioPermissions(containerUID); err != nil {
69+
return err
70+
}
71+
}
6772
process.Stdin = os.Stdin
6873
process.Stdout = os.Stdout
6974
process.Stderr = os.Stderr
75+
return nil
7076
}
7177

7278
func (t *tty) initHostConsole() error {

utils_linux.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,7 @@ func setupIO(process *libcontainer.Process, containerUID, containerGID int, crea
137137
// when runc will detach the caller provides the stdio to runc via runc's 0,1,2
138138
// and the container's process inherits runc's stdio.
139139
if detach {
140-
inheritStdio(process)
141-
return &tty{}, nil
140+
return &tty{}, inheritStdio(process, containerUID)
142141
}
143142
return setupProcessPipes(process, containerUID, containerGID)
144143
}

0 commit comments

Comments
 (0)