[kde-freebsd] virtualbox file dialog problem

Andriy Gapon avg at FreeBSD.org
Wed Aug 28 12:24:29 UTC 2013


on 28/08/2013 15:09 Andriy Gapon said the following:
> Now a description of the problem.
> 
> 1. VirtualBox executable is installed setuid root.  Apparently, when it is run
> it does some privileged things and then drops all of the uids and gids (real,
> effective and saved) back to what they should have been originally.
> VirtualBox does not do any (re-)exec of itself after the above manipulations.
> 
> 2. issetugid(2) (which is apparently a BSD extension) on FreeBSD does not
> consider the above manipulations as sufficient to mark an executable as
> untainted.  So it would return 1 for the VirtualBox process.
> 
> 3. dbus code seems to impose some limitations on communication by such "tainted"
> processes.  It has the following code:
> http://cgit.freedesktop.org/dbus/dbus/tree/dbus/dbus-sysdeps-unix.c#n4139
> For web-impaired :) the gist is that on BSD systems the code uses issetugid but
> on other systems (like Linux) it uses getresuid and getresgid and checks that
> all 3 uids are the same and all 3 gids are the same.
> 
> As a result, on FreeBSD the dbus code would consider the VirtualBox process
> tainted and that impairs its communication with KDE components.
> On systems without issetugid or those that implement it differently, dbus would
> work as for a normal process and all the communications are OK.
> 
> I've also verified this conclusion by forcing dbus to use the alternative logic
> on FreeBSD.
> 
> So, possible solutions:
[snip]
> B. change VirtualBox to be friendly to FreeBSD issetugid(2) and exec itself
> after dropping the privileges
[snip]

BTW, I've just found this "interesting" code in the VirtualBox sources (forgive
me a full paste, but I couldn't resist):

#if defined(RT_OS_DARWIN)
# include <dlfcn.h>
# include <sys/mman.h>
# include <iprt/asm.h>
# include <iprt/system.h>

/** Really ugly hack to shut up a silly check in AppKit. */
static void ShutUpAppKit(void)
{
    /* Check for Snow Leopard or higher */
    char szInfo[64];
    int rc = RTSystemQueryOSInfo (RTSYSOSINFO_RELEASE, szInfo, sizeof(szInfo));
    if (   RT_SUCCESS (rc)
        && szInfo[0] == '1') /* higher than 1x.x.x */
    {
        /*
         * Find issetguid() and make it always return 0 by modifying the code.
         */
        void *addr = dlsym(RTLD_DEFAULT, "issetugid");
        int rc = mprotect((void *)((uintptr_t)addr & ~(uintptr_t)0xfff), 0x2000,
PROT_WRITE|PROT_READ|PROT_EXEC);
        if (!rc)
            ASMAtomicWriteU32((volatile uint32_t *)addr, 0xccc3c031); /* xor
eax, eax; ret; int3 */
    }
}
#endif /* DARWIN */


-- 
Andriy Gapon


More information about the freebsd-standards mailing list