Full_Name: Hallvard B Furuseth Version: Many... OS: HPUX URL: Submission from: (NULL) (129.240.202.105) Submitted by: hallvard Indented text is copied from Howard's mail to openldap-committers, mostly for completeness. [There are] security issues with the implementation of ldapi on platforms that don't explicitly provide for passing the socket peer's credentials. On those platforms we create a pipe and use descriptor passing to send the pipe descriptor to the server, which then fstat's the descriptor to obtain the uid and gid of the client. Users can give away file ownership on HPUX (at least the box I am using, I don't know HP in general). fchown(pipe descriptor, 0, 0) lets me Bind as root. There is a slight escape: fchown(regular file) resets the setuid bit, so the server could require a regular file with the setuid bit. It does not reset a pipe's setuid bit. And I think resetting the setuid bit is an OS feature which differs between OSes, so at the very best we'd need some research, and I think it'll take a tmpfile() call and 7-8 system calls to create a regular file and descriptor just right. Note: The current server code requires (a) that the descriptor is a pipe, and (b) that group/other permissions are 0, so the user cannot use a descriptor from opening someone else's named pipe. Anyway, maybe this is the place to stop reading and skip to "Server-side descriptor handling bugs" below. I'd already written up this ITS when I noticed the fchown issue, so I'm sending it all off anyway. The first issue is that it's possible for a user program to inherit root-owned descriptors from a number of sources. cron on Linux is an example of this case (although since Linux provides explicit identity passing, it is not vulnerable for that example). Another more pressing problem is on HPUX: the ssh daemon spawns non-interactive children with root-owned pipes for their stdio descriptors. So it's possible to write an ldapi client on HPUX that allows any user to authenticate as Unix root. The second issue is that the credentials can be reused indefinitely by the server to talk to another ldapi server. If the directories leading up to the ldapi socket are not adequately protected, this could allow a man-in-the-middle to receive credentials from any number of users and then connect to another ldapi service using any of those credentials. Or a user could provide some info/service at an ldapi socket of his own, announce it, and collect credentials. Others are not supposed to need to know or trust him just for browsing his server. Another issue is that it's possible for a client to use a gid for groups that it doesn't actually belong to. This requires the existence of a world-writable directory in the filesystem, with its setgid bit set. Or that a root person gives the user a directory (presumably under a directory the user cannot write), but forgets to change the gid. I think the probability of this situation arising is pretty low, and the risk exposure is probably pretty low too. Just mentioning it for completeness. For the first issue, we can fix this by requiring that unusual, non-default permission bits be set on the passed descriptor. That will distinguish pipes explicitly created for this authentication purpose from pipes arbitrarily inherited from other programs. For the second issue, we can fix this by requiring that the client perform a stat of the Unix domain socket, and send the stat result buffer over the pipe. The server will then read this buffer and compare the results to its own stat of the socket. If the stat data is missing or doesn't match, we know that the credentials were sent by a man-in-the-middle. This one gets a bit complicated. We must use stat(socket filename) and not fstat(socket descriptor). The latter returns different inodes for server socket, server connection and client connection - at least on HPUX and Linux. That does leave a window where the naughty server's owner can swap a hard link to his server socket for a hard link to the server he attacks, maybe back and forth in a loop. A client can detect it by doing fstat(connection) as well and compare the uid and gid of the stat results. Unless there are systems where the connection will have uid 0, like HPUX's socketpair()s? We can send st_ino and st_dev (and st_rdev?). Do not send st_uid, st_gid and st_mode, since the admin might do chown/chmod at just the wrong time. It won't hurt to #define a magic number (or rather magic octet string) and send that as well while we are at it, in case some other application also uses descriptor passing tricks for authentication. One can run programs in 32-bit and 64-bit mode on the same machine, and (at least on PowerPC) with different endianness too. So the data should be sent in a host-independent format. Network byte order, maybe 64-bit integers in these 64-bit days. How big can an inode/device number get? The client should to write the stat data before passing the descriptor, so the server can read it in non-blocking mode and not worry about clients that do not write send any stat data. Besides, write() can cancel the setuid bit, so it should be done before the fchmod(). At present we haven't come up with any resolution for the 3rd issue. Some options: - Do nothing. - Remove gidNumber from the DN. Loses some functionality and causes version compatibility problems for programs that use the DN. - Partial solution: Reject named pipe descriptors if a system provides a way to tell them from pipe()s. Except I don't know of a way. - Find some file descriptor type which is not affected by a directory's gid (maybe not associated with the filesystem). Likely unportable and more complicated, thus a poor fallback solution for the problem of transferring client credentials. Also, HPUX socketpair() returns descriptors with uid=gid=0, so maybe disassociated from the file system also can mean disassociated from file properties like uids... ======================================================================== Server-side descriptor handling bugs. These open for denial of service attacks and OS upgrade problems. The fixes should be invisible to clients. Fourth issue, a HPUX client can inject a file descriptor leak into the server by sending two descriptors instead of one: The server-side code with struct msghdr.msg_accrights in liblutil/getpeereid.c accepts up to two descriptors, but only closes one and only if just one was received. Fifth issue, the same code assumes a descriptor is sent. If a client connects and sends nothing, one server thread will block. And if it just sends a normal PDU, the server will throw away its first 8 octets when MSG_PEEK is not used, expecting these to be a dummy Abandon Request the descriptor is attached to. This can happen if a newer OS version gains support for real peer credentials. A new client will not send a descriptor, this breaks when used with an old server. However the HPUX box I'm using has an OS bug: recvmsg(,,MSG_PEEK) may return two descriptor numbers, 0 and a garbage number. So the potential descriptor leak above protects the server from doing close(0). Removing MSG_PEEK helps, but I still see strange behavior. Thus if removing descriptor passing is removed, clients should still send a dummy Abandon (with msgId=abandonId=0, thus harmless), to avoid breakage with older servers. getpeerid.c also supports reading credentials with recvmsg() and SCM_CREDS, but I can't see corresponding code in libldap/os-local.c? I'm not sure how SCM_CREDS works - if the client must send them, I assume they too can block a server thread. A fix would be to read them at the time when normal PDUs are read. Set a flag which says to use recvmsg() for the next data to read. Also, if the client sends a descriptor but the server checks for SCM_CREDS, will the server receive the descriptor? If so that must be close()d.
h.b.furuseth@usit.uio.no wrote: > Users can give away file ownership on HPUX (at least the box I am using, > I don't know HP in general). fchown(pipe descriptor, 0, 0) lets me Bind > as root. > > There is a slight escape: fchown(regular file) resets the setuid bit, so > the server could require a regular file with the setuid bit. > > It does not reset a pipe's setuid bit. And I think resetting the setuid > bit is an OS feature which differs between OSes, so at the very best > we'd need some research, and I think it'll take a tmpfile() call and 7-8 > system calls to create a regular file and descriptor just right. POSIX requires that the setuid bit is cleared by chown if the file had its execute bit set. So we may be able to take advantage of this fact by requiring both the execute and the setuid bit to be set. > Note: The current server code requires (a) that the descriptor is a > pipe, and (b) that group/other permissions are 0, so the user cannot use > a descriptor from opening someone else's named pipe. > For the first issue, we can fix this by requiring that unusual, > non-default permission bits be set on the passed descriptor. That will > distinguish pipes explicitly created for this authentication purpose > from pipes arbitrarily inherited from other programs. > > For the second issue, we can fix this by requiring that the client > perform a stat of the Unix domain socket, and send the stat result > buffer over the pipe. The server will then read this buffer and compare > the results to its own stat of the socket. If the stat data is missing > or doesn't match, we know that the credentials were sent by a > man-in-the-middle. > > This one gets a bit complicated. > > We must use stat(socket filename) and not fstat(socket descriptor). The > latter returns different inodes for server socket, server connection and > client connection - at least on HPUX and Linux. That does leave a > window where the naughty server's owner can swap a hard link to his > server socket for a hard link to the server he attacks, maybe back and > forth in a loop. A client can detect it by doing fstat(connection) as > well and compare the uid and gid of the stat results. Unless there are > systems where the connection will have uid 0, like HPUX's socketpair()s? Comparing the st_ino would be more effective, if you're worried about swapping hardlinks. > At present we haven't come up with any resolution for the 3rd issue. > > Some options: > > - Do nothing. I'm in favor of this; I don't see it as a meaningful threat. It requires some other security misconfiguration to already exist before it can be a problem. > - Remove gidNumber from the DN. Loses some functionality and causes > version compatibility problems for programs that use the DN. > > - Partial solution: Reject named pipe descriptors if a system provides > a way to tell them from pipe()s. Except I don't know of a way. > > - Find some file descriptor type which is not affected by a directory's > gid (maybe not associated with the filesystem). Likely unportable and > more complicated, thus a poor fallback solution for the problem of > transferring client credentials. Also, HPUX socketpair() returns > descriptors with uid=gid=0, so maybe disassociated from the file > system also can mean disassociated from file properties like uids... > > > ======================================================================== > > Server-side descriptor handling bugs. > > These open for denial of service attacks and OS upgrade problems. The > fixes should be invisible to clients. > > Fourth issue, a HPUX client can inject a file descriptor leak into the > server by sending two descriptors instead of one: The server-side code > with struct msghdr.msg_accrights in liblutil/getpeereid.c accepts up to > two descriptors, but only closes one and only if just one was received. > > Fifth issue, the same code assumes a descriptor is sent. > If a client connects and sends nothing, one server thread will block. > And if it just sends a normal PDU, the server will throw away its first 8 > octets when MSG_PEEK is not used, expecting these to be a dummy Abandon > Request the descriptor is attached to. This can happen if a newer OS > version gains support for real peer credentials. A new client will not > send a descriptor, this breaks when used with an old server. > > However the HPUX box I'm using has an OS bug: recvmsg(,,MSG_PEEK) may > return two descriptor numbers, 0 and a garbage number. So the potential > descriptor leak above protects the server from doing close(0). Removing > MSG_PEEK helps, but I still see strange behavior. The fix here will be to check for the credentials message on the first protocol message received on a sockbuf, and cache the message there. (We should have a sockbuf control command to enable this behavior.) Then the getpeereids() function will just parse the cached message if it's found. > Thus if removing descriptor passing is removed, clients should still > send a dummy Abandon (with msgId=abandonId=0, thus harmless), to avoid > breakage with older servers. Maintaining that is going to be difficult, unless we simply add the dummy message to all platforms across the board. I.e., if some new release of HPUX or AIX adds support for one of the existing peer cred mechanisms, autoconf isn't going to tell us that we still need to send the old dummy message. > getpeerid.c also supports reading credentials with recvmsg() and > SCM_CREDS, but I can't see corresponding code in libldap/os-local.c? > I'm not sure how SCM_CREDS works - if the client must send them, I > assume they too can block a server thread. A fix would be to read them > at the time when normal PDUs are read. Set a flag which says to use > recvmsg() for the next data to read. Also, if the client sends a > descriptor but the server checks for SCM_CREDS, will the server receive > the descriptor? If so that must be close()d. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
moved from Incoming to Software Bugs
h.b.furuseth@usit.uio.no wrote: > Server-side descriptor handling bugs. These are now fixed in HEAD. > These open for denial of service attacks and OS upgrade problems. The > fixes should be invisible to clients. > > Fourth issue, a HPUX client can inject a file descriptor leak into the > server by sending two descriptors instead of one: The server-side code > with struct msghdr.msg_accrights in liblutil/getpeereid.c accepts up to > two descriptors, but only closes one and only if just one was received. The code only accepts a single descriptor now. In fact I have no idea what happens if the rest of the message is ignored, but I'm assuming that the descriptor is discarded by the OS. Will have to play with lsof a bit and see what shows up. > Fifth issue, the same code assumes a descriptor is sent. > If a client connects and sends nothing, one server thread will block. > And if it just sends a normal PDU, the server will throw away its first 8 > octets when MSG_PEEK is not used, expecting these to be a dummy Abandon > Request the descriptor is attached to. This can happen if a newer OS > version gains support for real peer credentials. A new client will not > send a descriptor, this breaks when used with an old server. > > However the HPUX box I'm using has an OS bug: recvmsg(,,MSG_PEEK) may > return two descriptor numbers, 0 and a garbage number. So the potential > descriptor leak above protects the server from doing close(0). Removing > MSG_PEEK helps, but I still see strange behavior. I've reworked the getpeereid function to save the data that it receives so that it can be stuffed back into the sockbuf structure and read out again. So whatever the first protocol message is will not be lost. > Thus if removing descriptor passing is removed, clients should still > send a dummy Abandon (with msgId=abandonId=0, thus harmless), to avoid > breakage with older servers. I don't think this is worth dealing with. Since there is a security problem in the old code, nobody should be installing a new client without also upgrading the server. > getpeerid.c also supports reading credentials with recvmsg() and > SCM_CREDS, but I can't see corresponding code in libldap/os-local.c? > I'm not sure how SCM_CREDS works - if the client must send them, I > assume they too can block a server thread. A fix would be to read them > at the time when normal PDUs are read. Set a flag which says to use > recvmsg() for the next data to read. Also, if the client sends a > descriptor but the server checks for SCM_CREDS, will the server receive > the descriptor? If so that must be close()d. SCM_CREDS needs to be sent explicitly, the same as the other message-based code. It's definitely odd that there's no client-side code to send this message. LukeH committed that for NetBSD, we'll have to ask him what happened to that. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
h.b.furuseth@usit.uio.no wrote: > Full_Name: Hallvard B Furuseth > Version: Many... > OS: HPUX > URL: > Submission from: (NULL) (129.240.202.105) > Submitted by: hallvard > Users can give away file ownership on HPUX (at least the box I am using, > I don't know HP in general). fchown(pipe descriptor, 0, 0) lets me Bind > as root. > > There is a slight escape: fchown(regular file) resets the setuid bit, so > the server could require a regular file with the setuid bit. > > It does not reset a pipe's setuid bit. And I think resetting the setuid > bit is an OS feature which differs between OSes, so at the very best > we'd need some research, and I think it'll take a tmpfile() call and 7-8 > system calls to create a regular file and descriptor just right. > > Note: The current server code requires (a) that the descriptor is a > pipe, and (b) that group/other permissions are 0, so the user cannot use > a descriptor from opening someone else's named pipe. The solution is a lot simpler. The client now just sends its socket descriptor to the server. And for completeness' sake we require the descriptor to have its setuid bit set, along with rwx user and no access to anyone else. Also, in the server, we compare the server socket's name (using getsockname) with the client socket's peer's name. The two of them must match exactly. > Anyway, maybe this is the place to stop reading and skip to "Server-side > descriptor handling bugs" below. I'd already written up this ITS when I > noticed the fchown issue, so I'm sending it all off anyway. > > The first issue is that it's possible for a user program to inherit > root-owned descriptors from a number of sources. cron on Linux is an > example of this case (although since Linux provides explicit identity > passing, it is not vulnerable for that example). Another more pressing > problem is on HPUX: the ssh daemon spawns non-interactive children with > root-owned pipes for their stdio descriptors. So it's possible to write > an ldapi client on HPUX that allows any user to authenticate as Unix root. The sockname checks will prevent arbitrarily inherited sockets from being used. > The second issue is that the credentials can be reused indefinitely by > the server to talk to another ldapi server. If the directories leading > up to the ldapi socket are not adequately protected, this could allow a > man-in-the-middle to receive credentials from any number of users and > then connect to another ldapi service using any of those credentials. > Or a user could provide some info/service at an ldapi socket of his own, > announce it, and collect credentials. Others are not supposed to need > to know or trust him just for browsing his server. The sockname checks will also prevent a socket from being reused with some other server. It still isn't foolproof - if the directory where the socket resides is world-writable, somebody can rename the existing socket and put their own in its place. But I think that's a doc issue; you need to protect the directories in the path up to the socket. (And we've already documented this fact, as I recall...) > Another issue is that it's possible for a client to use a gid for groups > that it doesn't actually belong to. This requires the existence of a > world-writable directory in the filesystem, with its setgid bit set. > > Or that a root person gives the user a directory (presumably under a > directory the user cannot write), but forgets to change the gid. > > I think the probability of this situation arising is pretty low, and > the risk exposure is probably pretty low too. Just mentioning it for > completeness. Using a socket completely avoids this problem, because sockets can't be opened in the filesystem. The new behavior is completely incompatible with the old, so SASL/EXTERNAL simply won't work across versions. Since this is a security issue, that seems to be unavoidable. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
changed notes changed state Open to Test
hyc@highlandsun.com writes: > POSIX requires that the setuid bit is cleared by chown if the file had > its execute bit set. So we may be able to take advantage of this fact by > requiring both the execute and the setuid bit to be set. As long as we check that we are running on such a POSIX box... But it only requires that for a _regular_ file, if "the process does not have appropriate privileges". (Which no longer means something as simple as "root", though I don't know what it means nowadays). (I'm reading IEEE Std 1003.1, 2004 Edition, if that makes a difference.) And fchown(connection,,) which you are using now does reset it on my HPUX box. But I assume this means the client or configure needs to check that fchown(connection) does clear the setuid bit. >> We must use stat(socket filename) and not fstat(socket descriptor). The >> latter returns different inodes for server socket, server connection and >> client connection - at least on HPUX and Linux. That does leave a >> window where the naughty server's owner can swap a hard link to his >> server socket for a hard link to the server he attacks, maybe back and >> forth in a loop. A client can detect it by doing fstat(connection) as >> well and compare the uid and gid of the stat results. Unless there are >> systems where the connection will have uid 0, like HPUX's socketpair()s? > > Comparing the st_ino would be more effective, if you're worried about > swapping hardlinks. Except that the connection and the filename have different st_ino. >> At present we haven't come up with any resolution for the 3rd issue. >> >> Some options: >> >> - Do nothing. > > I'm in favor of this; I don't see it as a meaningful threat. It requires > some other security misconfiguration to already exist before it can be a > problem. I don't know which option I favor. But now that I think of it, it's not necesarily misconfiguration. Sharing access is what groups are for, after all. It's rare for the user not to be a member of the group, but I've done that deliberately once or twice. >> Thus if removing descriptor passing is removed, clients should still >> send a dummy Abandon (with msgId=abandonId=0, thus harmless), to avoid >> breakage with older servers. > > Maintaining that is going to be difficult, unless we simply add the > dummy message to all platforms across the board. Then I suggest we do that. Seems simple enough. -- Regards, Hallvard
Howard Chu writes: >> These open for denial of service attacks and OS upgrade problems. The >> fixes should be invisible to clients. >> >> Fourth issue, a HPUX client can inject a file descriptor leak into the >> server by sending two descriptors instead of one: The server-side code >> with struct msghdr.msg_accrights in liblutil/getpeereid.c accepts up to >> two descriptors, but only closes one and only if just one was received. > > The code only accepts a single descriptor now. In fact I have no idea > what happens if the rest of the message is ignored, but I'm assuming > that the descriptor is discarded by the OS. I tested before posting the ITS. It leaks. If you read it with a recvmsg() which can accept descriptors, you get the descriptor and must close it. After all you just pick it up from memory afterwards. You don't use another OS call after recvmsg(), so the OS doesn't know that you didn't use it. >> Thus if removing descriptor passing is removed, clients should still >> send a dummy Abandon (with msgId=abandonId=0, thus harmless), to avoid >> breakage with older servers. > > I don't think this is worth dealing with. Since there is a security > problem in the old code, nobody should be installing a new client > without also upgrading the server. If the client library comes from the same installation as the server, yes. But it's not unusual for users to grab the Newest and Bestest code and use that, in particular when the admin is slower. > SCM_CREDS needs to be sent explicitly, the same as the other > message-based code. It's definitely odd that there's no client-side code > to send this message. LukeH committed that for NetBSD, we'll have to ask > him what happened to that. Hopefully we can switch from descriptor passing to that where both is supported, then. -- Regards, Hallvard
Hallvard B Furuseth wrote: > Howard Chu writes: >>> These open for denial of service attacks and OS upgrade problems. The >>> fixes should be invisible to clients. >>> >>> Fourth issue, a HPUX client can inject a file descriptor leak into the >>> server by sending two descriptors instead of one: The server-side code >>> with struct msghdr.msg_accrights in liblutil/getpeereid.c accepts up to >>> two descriptors, but only closes one and only if just one was received. >> The code only accepts a single descriptor now. In fact I have no idea >> what happens if the rest of the message is ignored, but I'm assuming >> that the descriptor is discarded by the OS. > > I tested before posting the ITS. It leaks. You misunderstand. I mean: the code only provides a buffer large enough to accept a single descriptor. If more descriptors are passed, the received message is truncated. In this case, the other descriptors never arrive in the process. The descriptors don't leak. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
h.b.furuseth@usit.uio.no wrote: > getpeerid.c also supports reading credentials with recvmsg() and > SCM_CREDS, but I can't see corresponding code in libldap/os-local.c? > I'm not sure how SCM_CREDS works - if the client must send them, I > assume they too can block a server thread. A fix would be to read them > at the time when normal PDUs are read. Set a flag which says to use > recvmsg() for the next data to read. Also, if the client sends a > descriptor but the server checks for SCM_CREDS, will the server receive > the descriptor? If so that must be close()d. Googling found some details here. http://julipedia.blogspot.com/2006/08/localcreds-socket-credentials.html http://julipedia.blogspot.com/2006/08/more-on-localcreds.html In short, on NetBSD this doesn't require any action on the client side. But the server must enable it on the listening side, and the credentials will be sent with every message from the client until it's disabled again. So it looks like there's some missing setsockopt calls here to turn this on on the listening socket and turn it off again on a client socket after the creds have been received. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
hyc@highlandsun.com wrote: > h.b.furuseth@usit.uio.no wrote: >> getpeerid.c also supports reading credentials with recvmsg() and >> SCM_CREDS, but I can't see corresponding code in libldap/os-local.c? > So it looks like there's some missing setsockopt calls here to > turn this on on the listening socket and turn it off again on a client > socket after the creds have been received. Actually turning it on is already done in daemon.c, so it's just turning it off again that's missing. -- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc/ Chief Architect, OpenLDAP http://www.openldap.org/project/
We are reinventing the answer to a comp.security.unix FAQ. Whatever we do, we should ask them too. (Maybe a not so well-known OpenLDAP person should ask, in case it occurs to a c.s.u reader to check his projects... Don't know how much paranoia makes sense:-) Two other answers I've found: - Solaris: One can use "doors". - STREAMS pipes: SysV supports receiving file descriptors via a STREAMS pipe. Source uid and gid are passed with it. So the server creates a pipe. The client opens it and sends some fd over it with ioctl I_SENDFD. The server grabs it and the credentials with ioctl I_RECVFD, and closes the fd without using it for anything. For some reason the examples I've seen say the server creates a unique named pipe which it asks the client to open, rather than passing a pipe() descriptor to the client. Also the I_SENDFD doc says the uid/gid which are sent are the pipe owner's uid/gid, while the I_RECVFD doc says the sender process' uid/gid are received. Haven't tested or checked what's going on, maybe the two issues are related. Could have a look at code for the same thing, I think e.g. at openssh and postgresql use it. Haven't have time to look, and might not for some days. I wrote: > hyc@highlandsun.com writes: >> POSIX requires that the setuid bit is cleared by chown if the file had >> its execute bit set. So we may be able to take advantage of this fact by >> requiring both the execute and the setuid bit to be set. > > As long as we check that we are running on such a POSIX box... > > But it only requires that for a _regular_ file, if "the process does not > have appropriate privileges". (Which no longer means something as simple > as "root", though I don't know what it means nowadays). > (I'm reading IEEE Std 1003.1, 2004 Edition, if that makes a difference.) > > And fchown(connection,,) which you are using now does reset it on my > HPUX box. But I assume this means the client or configure needs to > check that fchown(connection) does clear the setuid bit. Oops - s/client or configure/server or configure/. And it must be tested as non-root, since (f)chown need not remove the setuid bit if root is doing it. >>> We must use stat(socket filename) and not fstat(socket descriptor). The >>> latter returns different inodes for server socket, server connection and >>> client connection - at least on HPUX and Linux. That does leave a >>> window where the naughty server's owner can swap a hard link to his >>> server socket for a hard link to the server he attacks, maybe back and >>> forth in a loop. A client can detect it by doing fstat(connection) as >>> well and compare the uid and gid of the stat results. Unless there are >>> systems where the connection will have uid 0, like HPUX's socketpair()s? >> >> Comparing the st_ino would be more effective, if you're worried about >> swapping hardlinks. > > Except that the connection and the filename have different st_ino. And it doesn't work anyway when running client and server as different users. Oops. -- Regards, Hallvard
The FreeBSD, OpenBSD and NetBSD mkfifo(2) manpages say The fifo's group ID is set to that of the parent directory in which it is created. Similar for open(). Standard BSD feature. Using the process gid is a SysV feature. I can't test it, but unless there is something special about /tmp it looks like the BSD norm that anyone can create a named pipe with the gid of /tmp. -- Regards, Hallvard
changed state Test to Closed
moved from Software Bugs to Archive.Software Bugs
fixed in HEAD