Skip to content

Commit ff5075c

Browse files
committed
init: correctly handle unmapped stdio with multiple mappings
Previously we would handle the "unmapped stdio" case by just doing a simple check, however this didn't handle cases where the overflow_uid was actually mapped in the user namespace. Instead of doing some userspace checks, just try to do the fchown(2) and ignore EINVAL (unmapped) or EPERM (lacking privilege over inode) errors. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 74a1729 commit ff5075c

File tree

1 file changed

+9
-8
lines changed

1 file changed

+9
-8
lines changed

libcontainer/init_linux.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -348,21 +348,22 @@ func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
348348
continue
349349
}
350350

351-
// Skip chown if s.Gid is actually an unmapped gid in the host. While
352-
// this is a bit dodgy if it just so happens that the console _is_
353-
// owned by overflow_gid, there's no way for us to disambiguate this as
354-
// a userspace program.
355-
if _, err := config.Config.HostGID(int(s.Gid)); err != nil {
356-
continue
357-
}
358-
359351
// We only change the uid owner (as it is possible for the mount to
360352
// prefer a different gid, and there's no reason for us to change it).
361353
// The reason why we don't just leave the default uid=X mount setup is
362354
// that users expect to be able to actually use their console. Without
363355
// this code, you couldn't effectively run as a non-root user inside a
364356
// container and also have a console set up.
365357
if err := unix.Fchown(int(fd), u.Uid, int(s.Gid)); err != nil {
358+
// If we've hit an EINVAL then s.Gid isn't mapped in the user
359+
// namespace. If we've hit an EPERM then the inode's current owner
360+
// is not mapped in our user namespace (in particular,
361+
// privileged_wrt_inode_uidgid() has failed). In either case, we
362+
// are in a configuration where it's better for us to just not
363+
// touch the stdio rather than bail at this point.
364+
if err == unix.EINVAL || err == unix.EPERM {
365+
continue
366+
}
366367
return err
367368
}
368369
}

0 commit comments

Comments
 (0)