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

Re: [PATCH] libs/light: make it build without setresuid()

On Wed, Jan 20, 2021 at 05:10:36PM +0000, Ian Jackson wrote:
> Manuel Bouyer writes ("Re: [PATCH] libs/light: make it build without 
> setresuid()"):
> > On Wed, Jan 20, 2021 at 03:32:29PM +0000, Ian Jackson wrote:
> > > Yes, the dm is qemu.  If qemu restriction is not supported, that makes
> > > a big difference.  The complex situation here is to do with trying to
> > > kill a possibly hostile qemu.
> > 
> > Hum, I'll have to check this (how to check, BTW ?).
> > I assumed qemu was running as root but it may not be completely true.
> > Especially as I notice, now that I'm re-reading the patch, that
> > we're doing a kill to -1. If we were doing so as root, user processes
> > would be killed.
> It may well be that this whole piece of code won't be executed on
> NetBSD becauwe dm restriction will be off.
> The background: dm restriction is a set of arrangements for trying to
> run qemu without given it any more privilege than it needs, and
> certainly not ultimate privilege over the host.  This is quite
> complicated and includes running it as a non-root user, chroot, and so
> on.
> On Linux it's run in its own network namespace, so that a qemu
> compromised by the guest cannot access host daemons.  IDK what
> facilities one might want to use on NetBSD to try to contain qemu.
> This seems to me all a matter for future work.  I'm sorry that code
> for a feature you're not going to be benefiting from is getting in
> your way.

On NetBSD we could start with a different uid and a chroot. This would
limit damages.

> > > right answer.)
> > 
> > This would have to be checked, but I don't think a non-root process
> > can ptrace a process whose saved-user-id is root.
> If I remember rightly the saved-set-id is reset by setuid.  But I
> could be wrong.  This stuff is all quite complex :-/.

yes, setuid() resets the saved-user-id

> > Actually I think I could mimic the setresuid() with setreuid() and 
> > seteuid().
> My last mail had in it a thing that claims to be a proof that this is
> not possible.

This code:
        if (setreuid(375,0) < 0) {
                err(1, "setreuid");
        if (seteuid(374) < 0) {
                err(1, "seteuid");
        if (kill(-1, 9)) {
                err(1, "kill");
        printf("kill done\n");
        if (seteuid(0) < 0) {
                err(1, "setreuid2");

actually works on NetBSD. processes from 375 are killed, and the
seteuid(0) call succeeds (showing that the saved used id is still 0).

> > 
> > Actually I don't see how I could split this in a different file, without
> > lot of duplicate code (even in just kill_device_model_uid_child(),
> > we're talking of about 7 lines of code out of 75). So some guidance here
> > would be welcome.
> I think splitting it out at precisely the function needed is probably
> better.
> Can you try this experiment: what happens if you replace the call to
> setresuid with abort() ?  I think you may find it all works, because
> you're not using that code path.
> If so then I suggest introducing
>   int libxl__setresuid(uid_t ruid, uid_t euid, uid_t suid);
> which would call setresuid on Linux and on NetBSD would do this
>   assert(!"setresuid is not available on NetBSD, and dm restrction is not 
> supported, so this code path should not have been reached")
> What do you think ?

As this is supported by Xen, I hope I can make at last run qemu with a
non-zero uid.

Manuel Bouyer <bouyer@xxxxxxxxxxxxxxx>
     NetBSD: 26 ans d'experience feront toujours la difference



Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.