tech-kern archive

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

Re: /sbin/reboot and secmodel



der Mouse wrote:

As stated, this doesn't provide a way for something like reboot(8) to
prevent itself from being killed partway through its job.  As I wrote
upthread recently, I'm not sure this is as much of a problem in the
case of reboot as it's being made out to be, but the basic point is
valid: that when a nonprivileged user starts a complex privileged
operation, it should not necessarily be able to nuke it partway
through.  Traditional set-ID bits solve this as a side effect of the
"you can't kill(2) processes that aren't yours" restriction; I'm not
sure what should replace that.

Perhaps I am missing something, but looking at earlier code (earlier
being "before kauth/secmodel integration"), I see this in kern_sig.c:

/*
 * Can process p, with pcred pc, send the signal signum to process q?
 */
#define CANSIGNAL(p, pc, q, signum) \
        ((pc)->pc_ucred->cr_uid == 0 || \
            (pc)->p_ruid == (q)->p_cred->p_ruid || \
            (pc)->pc_ucred->cr_uid == (q)->p_cred->p_ruid || \
            (pc)->p_ruid == (q)->p_ucred->cr_uid || \
            (pc)->pc_ucred->cr_uid == (q)->p_ucred->cr_uid || \
            ((signum) == SIGCONT && (q)->p_session == (p)->p_session))

(FWIW, this is what done today still.)

So, for example, I don't see how a setgid program would be protected
against taking a signal if the same user is running it and sending the
signal.

Testing this, I wrote the following program:

        #include <stdio.h>
        #include <unistd.h>

        int
        main(void)
        {
                printf("pid %u\n", getpid());

                while (1) {
                        printf("running, uid=%u, euid=%u, gid=%u,"
                            " egid=%u\n", getuid(), geteuid(), getgid(),
                            getegid());
                        sleep(1);
                }

                return (0);
        }

And made two copies of the binary, owned by root:kmem, with the suid and
sgid bit set, respectively:

        phyre:sigs {62} ls -l set[ug]id
        -rwxr-sr-x  1 root  kmem  9488 Mar 18 16:06 setgid*
        -rwsr-xr-x  1 root  kmem  9488 Mar 18 16:05 setuid*
        phyre:sigs {63}

Running it as my own user (not a member of kmem and definitely not root)
worked as expected, producing lines like:

        running, uid=1000, euid=0, gid=1000, egid=1000 [for suid]
        running, uid=1000, euid=1000, gid=1000, egid=2 [for sgid]

I could kill both processes from a different terminal, logged in as my
own user again. So I'm not 100% sure on what you're referring to with
saying that the set-id bits solve this problem.

-e.


Home | Main Index | Thread Index | Old Index