COMMAND
sockets
SYSTEMS AFFECTED
Solaris 2.6
PROBLEM
Wojciech Tryc posted following about the strange things happening
under Solaris 2.6 (final release). Any Unix socket created by ANY
application has permissions 4777!!!!
srwxrwxrwx 1 root root 0 Oct 3 21:22 mysql.sock
Here is a sample code (by Nirva):
#include <stdio.h>
#include <stdlib.h>
#include <sys/un.h>
#include <sys/socket.h>
main(int argc, char *argv[])
{
struct sockaddr_un addr;
int s;
s = socket(AF_UNIX, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, "/tmp/yoursocket");
if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("bind");
exit(1);
}
sleep(100);
exit(0);
}
Thamer Al-Herbish brought up the issue on bugtraq before about
Solaris' UNIX domain sockets. The permissions actually have no
effect (atleast not on Solaris 2.5) so EVEN if you had mode 000
on them, people would still be able to connect and send arbritary
data.
SOLUTION
This is not the case with most BSD variants out there. The
solution was to create it under a directory with an executable
permission only for yourself. Check for strange stuff under your
/tmp.
Traditionally, unix domain sockets were created mode 777; the mode
was also ignored. Later BSD releases have been changed to
consider the mode. When scuh changes were considered for
Solaris, it was found that some software depended on Solaris
ignoring the permissions.
Xnet sockets did get changed to honor the permissions. FreeBSD
will fix that in 2.2.5-RELEASE. OpenBSD fixed this a while back.
Below is how did they do it:
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
...
revision 1.3
date: 1996/06/25 21:26:11; author: deraadt; state: Exp; lines: +2 -2
consider umask for AF_UNIX bind()
Index: uipc_usrreq.c
==================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- uipc_usrreq.c 1996/03/03 17:20:22 1.2
+++ uipc_usrreq.c 1996/06/25 21:26:11 1.3
@@ -418,7 +418,7 @@
}
VATTR_NULL(&vattr);
vattr.va_type = VSOCK;
- vattr.va_mode = ACCESSPERMS;
+ vattr.va_mode = ACCESSPERMS &~ p->p_fd->fd_cmask;
VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_CREATE(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
if (error)