File access race - Unix

This is a discussion on File access race - Unix ; Hello, I need to create a suid-root chown program. Not to create a security hole, I want it to drop the permissins on the file so that nobody gets more permissions than he had before. The code is something like: ...

+ Reply to Thread
Results 1 to 4 of 4

Thread: File access race

  1. File access race

    Hello,

    I need to create a suid-root chown program. Not to create a security hole, I
    want it to drop the permissins on the file so that nobody gets more
    permissions than he had before. The code is something like:

    chmod(file_name, safe_mode);
    chown(file_name, user, group);

    However, there's a race condition between chmod and chown. An attacker might
    change the permissions right after the chmod back (and maybe set some
    su/gid bits) which would sort of circumvent the whole thing.

    Any ideas how to make it work?

    Regards
    Jiri Palecek


  2. Re: File access race

    On Apr 7, 9:34 am, Jiri Palecek wrote:
    > I need to create a suid-root chown program. Not to create a
    > security hole, I want it to drop the permissins on the file so
    > that nobody gets more permissions than he had before. The
    > code is something like:
    >
    > chmod(file_name, safe_mode);
    > chown(file_name, user, group);
    >
    > However, there's a race condition between chmod and chown.
    > An attacker might change the permissions right after the
    > chmod back (and maybe set some su/gid bits) which would
    > sort of circumvent the whole thing.
    >
    > Any ideas how to make it work?


    On most UNIX systems, the chown() call will clear the setuid and
    setgid bits as part of its operation. The POSIX/SUS standard requires
    that behavior when the invoker isn't root ("has appropriate
    privileges") but leaves it implementation-defined for root, so check
    your system's docs. If they do strip the setuid/setgid bits, then
    you're fine if you do the operations in the reverse order: chown then
    chmod.

    On a system where chown() by root doesn't clear those bits, I don't
    see any 100% safe way to do the change.

    Oh, and you should open the file and use fchown() and fchmod() instead
    of chown() and chmod() so that the user can't rename or otherwise
    change the referenced file between the calls. (I.e., open() it, then
    use fstat() to verify that it's the correct file, then use fchown()
    and fchmod().)


    Philip Guenther

  3. Re: File access race

    In article ,
    Jiri Palecek wrote:

    > Hello,
    >
    > I need to create a suid-root chown program. Not to create a security hole, I
    > want it to drop the permissins on the file so that nobody gets more
    > permissions than he had before. The code is something like:
    >
    > chmod(file_name, safe_mode);
    > chown(file_name, user, group);
    >
    > However, there's a race condition between chmod and chown. An attacker might
    > change the permissions right after the chmod back (and maybe set some
    > su/gid bits) which would sort of circumvent the whole thing.
    >
    > Any ideas how to make it work?


    How about this:

    chown(file_name, nobody_user, group);
    chmod(file_name, safe_mode);
    chown(file_name, user, group);

    If the file has unsafe permissions, they won't be very dangerous when
    the owner becomes nobody.

    --
    Barry Margolin, barmar@alum.mit.edu
    Arlington, MA
    *** PLEASE don't copy me on replies, I'll read them in the group ***

  4. Re: File access race

    Barry Margolin wrote:

    > In article ,
    > Jiri Palecek wrote:
    >
    >> Hello,
    >>
    >> I need to create a suid-root chown program. Not to create a security
    >> hole, I want it to drop the permissins on the file so that nobody gets
    >> more permissions than he had before. The code is something like:
    >>
    >> chmod(file_name, safe_mode);
    >> chown(file_name, user, group);
    >>
    >> However, there's a race condition between chmod and chown. An attacker
    >> might change the permissions right after the chmod back (and maybe set
    >> some su/gid bits) which would sort of circumvent the whole thing.
    >>
    >> Any ideas how to make it work?

    >
    > How about this:
    >
    > chown(file_name, nobody_user, group);
    > chmod(file_name, safe_mode);
    > chown(file_name, user, group);
    >
    > If the file has unsafe permissions, they won't be very dangerous when
    > the owner becomes nobody.


    Except if the attacker is nobody, he will be able to revert that chmod...
    And if the file was suid before, the attacker can become nobody by
    executing it...

    I'm starting to believe the only way is to remove the old file, create a
    brand new file in its place and copy the data.

    Regards
    Jiri Palecek


+ Reply to Thread