qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] Add syscalls for -runas and -chroot tothe secco


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH] Add syscalls for -runas and -chroot tothe seccomp sandbox
Date: Mon, 05 Oct 2015 07:23:53 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

"Namsun Ch'o" <address@hidden> writes:

>> Our intention since the beginning was to protect the host from the
>> illegal guest operations. But you do have an interesting point about
>> flaws on qemu itself. Perhaps this might be something I could work on to
>> improve (start a bigger whitelist and get it tighter before guest
>> launches).
>
> The seccomp filters are always passed on through execve(), so it would not be
> possible to have the parent have chroot() whitelisted to chroot, then spawn a
> child without it. As far as I know, even a root process cannot chroot another
> process, even its child, so if the process is to chroot at all, it must have
> the chroot syscall whitelisted. What can be done, however, is using the
> argument passed to -chroot as the filter. The same could be done with setuid,
> by having it only whitelist the uid which is given at -runas.
>
> An example, using chdir (I presume QEMU uses chdir(dir) then chroot(".")):
>
>   sh# mkdir /tmp/chroot
>   sh# cat | gcc -lseccomp -x c -
>   #include <stdio.h>
>   #include <fcntl.h>
>   #include <seccomp.h>
>
>   void main(void)
>   {
>         const char *dir = "/tmp/chroot";
>
>         scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_TRAP);
>
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mkdir), 0);
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fchdir), 0);
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0);
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chdir), 1,
>                 SCMP_A0(SCMP_CMP_EQ, dir));
>         seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(chroot), 1,
>                 SCMP_A0(SCMP_CMP_EQ, "."));
>
>         seccomp_load(ctx);
>
>         chdir(dir);
>         chroot(".");
>
>         /* evil code starts here */
>         const int fd = open(".", O_DIRECTORY);
>         mkdir("foo");
>         chroot("foo");
>         fchdir(fd);
>         chdir("..");
>         chdir("..");
>         chdir("..");
>         chroot(".");
>   }^D^D
>   sh# strace -qq -e open,mkdir,chdir,chroot ./a.out 2>&1 | fold -s -w 80
>   chdir("/tmp/chroot")                    = 0
>   chroot(".")                             = 0
>   open(".", O_RDONLY|O_DIRECTORY)         = 3
>   mkdir("foo", 0200000)                   = 0
>   --- SIGSYS {si_signo=SIGSYS, si_code=SYS_SECCOMP, 
> si_call_addr=0x34400a7d397,
>   si_syscall=161, si_arch=3221225534} ---
>   +++ killed by SIGSYS +++
>   Bad system call
>   sh# grep 161 /usr/include/asm/unistd_64.h
>   #define __NR_chroot 161
>
> So there's really no need to disable chroot() or setuid(), just filter the
> arguments based on command line input to make them impossible to abuse.

Drawback: complexity.  If we decide to limit ourselves to the original
threat model (rogue guest), and enter the sandbox only after setup, we
can keep things simpler.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]