Skip to content

Commit c0c8edb

Browse files
committed
console: don't chown(2) the slave PTY
Since the gid=X and mode=Y flags can be set inside config.json as mount options, don't override them with our own defaults. This avoids /dev/pts/* not being owned by tty in a regular container, as well as all of the issues with us implementing grantpt(3) manually. This is the least opinionated approach to take. This patch is part of the console rewrite patchset. Reported-by: Mrunal Patel <[email protected]> Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 244c9fc commit c0c8edb

File tree

5 files changed

+20
-14
lines changed

5 files changed

+20
-14
lines changed

libcontainer/console_freebsd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ import (
88

99
// newConsole returns an initialized console that can be used within a container by copying bytes
1010
// from the master side to the slave that is attached as the tty for the container's init process.
11-
func newConsole(uid, gid int) (Console, error) {
11+
func newConsole() (Console, error) {
1212
return nil, errors.New("libcontainer console is not supported on FreeBSD")
1313
}

libcontainer/console_linux.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
// newConsole returns an initialized console that can be used within a container by copying bytes
1313
// from the master side to the slave that is attached as the tty for the container's init process.
14-
func newConsole(uid, gid int) (Console, error) {
14+
func newConsole() (Console, error) {
1515
master, err := os.OpenFile("/dev/ptmx", syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_CLOEXEC, 0)
1616
if err != nil {
1717
return nil, err
@@ -26,12 +26,6 @@ func newConsole(uid, gid int) (Console, error) {
2626
if err := unlockpt(master); err != nil {
2727
return nil, err
2828
}
29-
if err := os.Chmod(console, 0600); err != nil {
30-
return nil, err
31-
}
32-
if err := os.Chown(console, uid, gid); err != nil {
33-
return nil, err
34-
}
3529
return &linuxConsole{
3630
slavePath: console,
3731
master: master,

libcontainer/console_solaris.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import (
66

77
// newConsole returns an initialized console that can be used within a container by copying bytes
88
// from the master side to the slave that is attached as the tty for the container's init process.
9-
func newConsole(uid, gid int) (Console, error) {
9+
func newConsole() (Console, error) {
1010
return nil, errors.New("libcontainer console is not supported on Solaris")
1111
}

libcontainer/console_windows.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package libcontainer
22

33
// newConsole returns an initialized console that can be used within a container
4-
func newConsole(uid, gid int) (Console, error) {
4+
func newConsole() (Console, error) {
55
return &windowsConsole{}, nil
66
}
77

libcontainer/init_linux.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,14 @@ func finalizeNamespace(config *initConfig) error {
157157
// issues related to that). This has to be run *after* we've pivoted to the new
158158
// rootfs (and the users' configuration is entirely set up).
159159
func setupConsole(pipe *os.File, config *initConfig, mount bool) error {
160-
// At this point, /dev/ptmx points to something that we would expect.
161-
console, err := newConsole(0, 0)
160+
// At this point, /dev/ptmx points to something that we would expect. We
161+
// used to change the owner of the slave path, but since the /dev/pts mount
162+
// can have gid=X set (at the users' option). So touching the owner of the
163+
// slave PTY is not necessary, as the kernel will handle that for us. Note
164+
// however, that setupUser (specifically fixStdioPermissions) *will* change
165+
// the UID owner of the console to be the user the process will run as (so
166+
// they can actually control their console).
167+
console, err := newConsole()
162168
if err != nil {
163169
return err
164170
}
@@ -309,11 +315,17 @@ func fixStdioPermissions(u *user.ExecUser) error {
309315
if err := syscall.Fstat(int(fd), &s); err != nil {
310316
return err
311317
}
312-
// skip chown of /dev/null if it was used as one of the STDIO fds.
318+
// Skip chown of /dev/null if it was used as one of the STDIO fds.
313319
if s.Rdev == null.Rdev {
314320
continue
315321
}
316-
if err := syscall.Fchown(int(fd), u.Uid, u.Gid); err != nil {
322+
// We only change the uid owner (as it is possible for the mount to
323+
// prefer a different gid, and there's no reason for us to change it).
324+
// The reason why we don't just leave the default uid=X mount setup is
325+
// that users expect to be able to actually use their console. Without
326+
// this code, you couldn't effectively run as a non-root user inside a
327+
// container and also have a console set up.
328+
if err := syscall.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
317329
return err
318330
}
319331
}

0 commit comments

Comments
 (0)