On Sun, Jan 15, 2012 at 4:07 PM, Andrew Lutomirski <luto@xxxxxxx> wrote: > On Sun, Jan 15, 2012 at 1:32 PM, Casey Schaufler <casey@xxxxxxxxxxxxxxxx> wrote: >> On 1/15/2012 12:59 PM, Andrew Lutomirski wrote: >>> >>> On Sun, Jan 15, 2012 at 12:16 PM, Casey Schaufler >>> <casey@xxxxxxxxxxxxxxxx> wrote: >>>> >>>> On 1/14/2012 12:22 PM, Linus Torvalds wrote: >>>>> >>>>> And yes, I really seriously do believe that is both safer and simpler >>>>> than some model that says "you can drop stuff", and then you have to >>>>> start making up rules for what "dropping" means. >>>>> >>>>> Does "dropping" mean allowing setuid(geteuid()) for example? That *is* >>>>> dropping the uid in a _POSIX_SAVED_IDS environment. And I'm saying >>>>> that no, we should not even allow that. It's simply all too "subtle". >>>> >>>> >>>> I am casting my two cents worth behind Linus. Dropping >>>> privilege can be every bit as dangerous as granting privilege >>>> in the real world of atrocious user land code. Especially in >>>> the case of security policy enforcing user land code. >>> >>> Can you think of *any* plausible attack that is possible with my patch >>> (i.e. no_new_privs allows setuid, setresuid, and capset) that would be >>> prevented or even mitigated if I blocked those syscalls? I can't. >>> (The sendmail-style attack is impossible with no_new_privs.) >> >> >> I am notoriously bad at coming up with this sort of example. >> I will try, I may not hit the mark, but it should be close. >> >> The application is running with saved uid != euid when >> no-new-privs is set. It execs a new binary, which keeps >> the saved and effective uids. The program calls setreuid, >> which succeeds. It opens the saved userid's files. > > If you don't trust that binary, then why are you execing it with saved > uid != euid in the first place? If you are setting no_new_privs, then > you are new code and should have at least some basic awareness of the > semantics. The exact same "exploit" is possible if you have > CAP_DAC_OVERRIDE with either no_new_privs semantics -- if you have a > privilege and you run untrusted code, then you had better remove that > privilege somehow for the untrusted code. > > IOW, *drop privileges if you are a sandbox*. Otherwise you're screwed > with or without no_new_privs. One consideration could be to add do_exit()s at known DAC transitions (set*id, fcaps). I don't know if that'd be wise, but it would remove some described ambiguity. The same could be done with exec when the (e)uid/gid/fcaps change. However, none of that helps with the opaque LSM data, so that'd have to be left up to the LSMs and the LSM_* flag you've added. This does seem subject to bitrot though, and your current approach certainly suits the needs of the general don't-do-something-stupid-on-exec that seccomp filter, unprivileged chroot, unshare, etc all need (which is really nice). > Another way of saying this is: no_new_privs is not a sandbox. It's > just a way to make it safe for sandboxes and other such weird things > processes can do to themselves safe across execve. If you want a > sandbox, use seccomp mode 2, which will require you to set > no_new_privs. And even with system call filtering, you'll need to have appropriately set up accessible files, file descriptors, memory maps, etc if you want a proper sandbox. There's no single sandbox-equivalent kernel feature. no_new_privs would be an excellent addition to the sandbox toolkit. (I've tried to synthesize it in userspace with an empty capability bounding set, SECURE_NOROOT, and MNT_NOSUID. Having this in a future-proof task_struct bit form would be amazing.) cheers! will -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html