Re: Someone help me understand this...?

From: Robert Watson (rwatson_at_freebsd.org)
Date: 08/30/03

  • Next message: Christoph Kukulies: "su in free(): warning: chunk is already free"
    Date: Sat, 30 Aug 2003 12:23:35 -0400 (EDT)
    To: Jilles Tjoelker <jilles@stack.nl>
    
    

    On Sat, 30 Aug 2003, Jilles Tjoelker wrote:

    > On Thu, Aug 28, 2003 at 11:34:09AM -0400, Robert Watson wrote:
    > > > > Clearly, unbreaking applications like Diablo by default is desirable. At
    > > > > least OpenBSD has similar protections to these turned on by default, and
    > > > > possibly other systems as well. As 5.x sees more broad use, we may well
    > > > > bump into other cases where applications have similar behavior: they rely
    > > > > on no special protections once they've given up privilege. I wonder if
    > > > > Diablo can run unmodified on OpenBSD; it could be they don't include
    > > > > SIGALRM on the list of "protect against" signals, or it could be that they
    > > > > modify Diablo for their environment to use an alternative signaling
    > > > > mechanism. Another alternative to this patch would simply be to add
    > > > > SIGARLM to the list of acceptable signals to deliver in the
    > > > > privilege-change case.
    >
    > OpenBSD does not consider a process 'tainted' if it changes credentials
    > while running. From the issetugid(2) manpage:
    >
    > The status of issetugid() is only affected by execve().

    In OpenBSD, two flags are used to represent the credential change notion:
    P_SUGIDEXEC, and P_SUGID. issetugid() checks the first of these, but
    signal delivery checks P_SUGID. P_SUGIDEXEC is set during execve(). In
    FreeBSD, we have a combined notion used by both, since the same
    protections generally apply. You can find a comment comparing our use of
    P_SUGID to the OpenBSD approach in our issetugid() implementation:

            /*
             * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time,
             * we use P_SUGID because we consider changing the owners as
             * "tainting" as well.
             * This is significant for procs that start as root and "become"
             * a user without an exec - programs cannot know *everything*
             * that libc *might* have put in their data segment.
             */

    Regarding specific signals: inspection of the OpenBSD implementation
    reveals that the following signals are permitted in the P_SUGID case,
    assuming a reasonable credential match:

                    case 0:
                    case SIGKILL:
                    case SIGINT:
                    case SIGTERM:
                    case SIGALRM:
                    case SIGSTOP:
                    case SIGTTIN:
                    case SIGTTOU:
                    case SIGTSTP:
                    case SIGHUP:
                    case SIGUSR1:
                    case SIGUSR2:

    In FreeBSD, we permit:

                    case 0:
                    case SIGKILL:
                    case SIGINT:
                    case SIGTERM:
                    case SIGSTOP:
                    case SIGTTIN:
                    case SIGTTOU:
                    case SIGTSTP:
                    case SIGHUP:
                    case SIGUSR1:
                    case SIGUSR2:

    So they permit SIGALRM in addition to the signals we support. In light of
    this thread, I think it would be reasonable to add SIGALRM to our list as
    well.

    > > In most cases, fail-stop is a reasonable behavior for unexpected security
    > > behavior from the system, but ignore is likely to shoot you later. :-) I
    > > tend to wrap even kill() calls as uid 0 in an assertion check, just to be
    > > on the safe side. If nothing else, it helps detect the case where the
    > > other process has died, and you're using a stale pid. It's particular
    > > useful if the other process has died, the pid has been reused, and it's
    > > now owned by another user, which is a real-world case where kill() as a
    > > non-0 uid can fail even when you're sure it can't :-).
    >
    > This can be avoided by careful programming: do not use SA_NOCLDWAIT and
    > don't pass pids to kill() when they have been returned by wait() or
    > similar functions. If the process has terminated in between, it's a
    > zombie. In that case, FreeBSD probably returns ESRCH but SUSv3 mandates
    > returning success (but performing no action).

    There's still a race possible here, it just becomes more narrow with
    conservative programming. And in the classic use of pids for signalling
    (/var/run/foo.pid, or kill -9 pid), these approaches won't help. The only
    way to close this sort of race is to have a notion of a unique process
    identifier that lasts beyond the lifetime of the process itself -- i.e.,
    the ability to return EMYSINCERESTREGRESTS if you try to signal a process
    after it has died, and have a guarantee that the handle won't be reused.

    Robert N M Watson FreeBSD Core Team, TrustedBSD Projects
    robert@fledge.watson.org Network Associates Laboratories

    _______________________________________________
    freebsd-current@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-current
    To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org"


  • Next message: Christoph Kukulies: "su in free(): warning: chunk is already free"

    Relevant Pages

    • [UNIX] OpenBSD Bug Allows Unprivileged Users to Send SIGURG and SIGIO Signals
      ... OpenBSD Bug Allows Unprivileged Users to Send SIGURG and SIGIO Signals ... Which process is notified depends on the ownership of the file descriptor. ... calls the socket function in the case of sockets). ...
      (Securiteam)
    • OpenBSD bug
      ... default behaviour in OpenBSD is to ignore these signals, ... arrives to an specific file descriptor, ... calls the socket function in the case of sockets). ...
      (Bugtraq)
    • Re: Is fork() hook ever possible?
      ... child's pid is needed. ... Currently OpenBSD does almost that checking getpid() every time ... the child? ... Calling getpidas OpenBSD ...
      (freebsd-current)
    • Re: kern.randompid
      ... >> The kern.randompid sysctl is not a boolean flag, ... >> of the random value that will be added to each newly created pid. ... It's a slight generalization of the algorithm which OpenBSD use (they ... the sysctl to whatever value they use, ...
      (FreeBSD-Security)
    • Re: posix_spawn: Whats going on with it?
      ... think it both prevents reusing of the PID as well as it would ... On OpenBSD 5.5 PID_MAX is 32766. ... I agree the race is largely an academic concern. ... BSD flock because it allows me to attempt to take the lock before I ...
      (comp.unix.programmer)