From: Ian Jackson (iwj@cam-orl.co.uk) Subject: Re: clearing SUID bit on writes Date: 2 Sep 1992 10:03:40 GMT
In article <1992Sep1.170221.17317@athena.mit.edu>
tytso@ATHENA.MIT.EDU (Theodore Ts'o) writes:
>When System V does is whenever you write to a setuid file (not just when
>you append to it), it clears the setuid and setgid bits. This prevents
>a security hole if you have a setuid program which is group or world
>writeable. I don't think anything would break if we added this behavior
>to Linux. On the other hand, there's a much simpler way of avoiding the
>security hole, which is to simply don't create group or world writeable
>setuid files.
Careful! I don't know if you want to support mandatory record locking,
but if you do you need to keep the sgid bit set on writes if all the
execute bits are clear. I don't know anybody who's ever used mandatory
locking, so this may be a red herring, but it's worth thinking about.
I'll enclose some manpage extracts for lockf(3), stat(2) & write(2)
(SunOS 4.1.2). They are a little unclear, but I tried it (small
transcript also enclosed) and it only clears the sgid bit if one of
the execute bits is set.
==========
LOCKF(3) C LIBRARY FUNCTIONS LOCKF(3)
NAME
lockf - record locking on files
SYNOPSIS
#include <unistd.h>
int lockf(fd, cmd, size)
int fd, cmd;
long size;
DESCRIPTION
lockf() places, removes, and tests for exclusive locks on
sections of files. These locks are either advisory or man-
datory depending on the mode bits of the file. The lock is
mandatory if the set-GID bit (S_ISGID) is set and the group
execute bit (S_IXGRP) is clear (see stat(2V) for information
about mode bits). Otherwise, the lock is advisory.
If a process holds a mandatory exclusive lock on a segment
of a file, both read and write operations block until the
lock is removed (see WARNINGS).
An advisory lock does not affect read and write access to
the locked segment. Advisory locks may be used by cooperat-
ing processes checking for locks using F_GETLCK and volun-
tarily observing the indicated read and write restrictions.
[ ... ]
WARNINGS
Mandatory record locks are dangerous. If a runaway or oth-
erwise out-of-control process should hold a mandatory lock
on a file critical to the system and fail to release that
lock, the entire system could hang or crash. For this rea-
son, mandatory record locks may be removed in a future SunOS
release.n Use advisory record locking whenever possible.
[ ... ]
BUGS
lockf() locks do not interact in any way with locks granted
by flock(), but are compatible with locks granted by
fcntl().
Sun Release 4.1 Last change: 21 January 1990
==========
WRITE(2V) SYSTEM CALLS WRITE(2V)
NAME
write, writev - write output
SYNOPSIS
[ ... ]
DESCRIPTION
[ ... ]
If the real user is not the super-user, then write() clears
the set-user-id bit on a file. This prevents penetration of
system security by a user who "captures" a writable set-
user-id file owned by the super-user.
[ ... - there is no mention of the set-group-id bit - iwj ]
Sun Release 4.1 Last change: 21 January 1990
==========
STAT(2V) SYSTEM CALLS STAT(2V)
NAME
stat, lstat, fstat - get file status
SYNOPSIS
[ ... ]
DESCRIPTION
[ ... - including stat structure layout - ... ]
The status information word st_mode is bit-encoded using the
following masks and bits:
S_ISUID Set user ID on execution. The process's
effective user ID is set to that of the owner
of the file when the file is run as a program
(see execve(2V)). On a regular file, this
bit should be cleared on any write.
S_ISGID Set group ID on execution. The process's
effective group ID is set to that of the file
when the file is run as a program (see
execve(2V)). On a regular file, this bit
should be cleared on any write.
Sun Release 4.1 Last change: 21 January 1990
==========
Script started on Wed Sep 2 10:55:32 1992
$ rm -f foo; touch foo
$ chmod 2666 foo; ls -lg foo
-rw-rwSrw- 1 iwj other 0 Sep 2 10:55 foo
$ echo >>foo; ls -lg foo
-rw-rwSrw- 1 iwj other 1 Sep 2 10:55 foo
$ chmod 2766 foo; ls -lg foo
-rwxrwSrw- 1 iwj other 1 Sep 2 10:55 foo
$ echo >>foo; ls -lg foo
-rwxrw-rw- 1 iwj other 2 Sep 2 10:55 foo
$ chmod 2676 foo; ls -lg foo
-rw-rwsrw- 1 iwj other 2 Sep 2 10:55 foo
You have mail in /usr/spool/mail/iwj
$ echo >>foo; ls -lg foo
-rw-rwxrw- 1 iwj other 3 Sep 2 10:56 foo
$ rm foo
$ exit
Script done on Wed Sep 2 10:56:48 1992
--
Ian Jackson The opinions expressed here are my own.
iwj@cam-orl.co.uk / ...!mcsun!uknet!cam-orl!iwj