Skip to content

Commit 76aeaf8

Browse files
committed
libcontainer: init: fix unmapped console fchown
If the stdio of the container is owned by a group which is not mapped in the user namespace, attempting to fchown the file descriptor will result in EINVAL. Counteract this by simply not doing an fchown if the group owner of the file descriptor has no host mapping according to the configured GIDMappings. Signed-off-by: Aleksa Sarai <[email protected]>
1 parent f0876b0 commit 76aeaf8

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

libcontainer/init_linux.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ func setupUser(config *initConfig) error {
277277

278278
// before we change to the container's user make sure that the processes STDIO
279279
// is correctly owned by the user that we are switching to.
280-
if err := fixStdioPermissions(execUser); err != nil {
280+
if err := fixStdioPermissions(config, execUser); err != nil {
281281
return err
282282
}
283283

@@ -312,7 +312,7 @@ func setupUser(config *initConfig) error {
312312
// fixStdioPermissions fixes the permissions of PID 1's STDIO within the container to the specified user.
313313
// The ownership needs to match because it is created outside of the container and needs to be
314314
// localized.
315-
func fixStdioPermissions(u *user.ExecUser) error {
315+
func fixStdioPermissions(config *initConfig, u *user.ExecUser) error {
316316
var null syscall.Stat_t
317317
if err := syscall.Stat("/dev/null", &null); err != nil {
318318
return err
@@ -326,10 +326,20 @@ func fixStdioPermissions(u *user.ExecUser) error {
326326
if err := syscall.Fstat(int(fd), &s); err != nil {
327327
return err
328328
}
329+
329330
// Skip chown of /dev/null if it was used as one of the STDIO fds.
330331
if s.Rdev == null.Rdev {
331332
continue
332333
}
334+
335+
// Skip chown if s.Gid is actually an unmapped gid in the host. While
336+
// this is a bit dodgy if it just so happens that the console _is_
337+
// owned by overflow_gid, there's no way for us to disambiguate this as
338+
// a userspace program.
339+
if _, err := config.Config.HostGID(int(s.Gid)); err != nil {
340+
continue
341+
}
342+
333343
// We only change the uid owner (as it is possible for the mount to
334344
// prefer a different gid, and there's no reason for us to change it).
335345
// The reason why we don't just leave the default uid=X mount setup is

0 commit comments

Comments
 (0)