-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 06/21/2010 01:35 PM, Paul Moore wrote: > On Monday, June 21, 2010 11:26:48 am Stephen Smalley wrote: >> On Mon, 2010-06-21 at 11:20 -0400, Paul Moore wrote: >>> On Friday, June 18, 2010 04:31:45 pm Stephen Smalley wrote: >>>> On Fri, 2010-06-18 at 16:22 -0400, Stephen Smalley wrote: >>>>> On Fri, 2010-06-18 at 16:00 -0400, Daniel J Walsh wrote: >>>>>> On 06/18/2010 03:45 PM, Stephen Smalley wrote: >>>>>>> On Fri, 2010-06-18 at 15:34 -0400, Daniel J Walsh wrote: >>>>>>>> http://0pointer.de/blog/projects/systemd.html >>>>>>>> >>>>>>>> This has interesting ramifications for SELinux. I have a >>>>>>>> working version of this in Fedora 14, but we need to add rules >>>>>>>> like >>>>>>>> >>>>>>>> allow sshd_t init_t:tcp_socket { getopt ioctl getattr setopt }; >>>>>>>> >>>>>>>> Since systemd will be doing the listening and passing the socket >>>>>>>> to sshd. >>>>>>>> >>>>>>>> Could we have risks of sshd_t grabbing the tcp_socket connected >>>>>>>> to httpd_t? >>>>>>>> >>>>>>>> In this scenario we are no longer protecting against the >>>>>>>> name_bind, and are forced to put more trust into init_t. >>>>>>> >>>>>>> Can we get systemd to use setsockcreatecon() to assign the right >>>>>>> label to the socket? >>>>>> >>>>>> Probably but how does it figure out the context? >>>>> >>>>> The sockets would normally be labeled with the context of the >>>>> individual daemon process. So we would want to compute the context >>>>> in which the daemon process will run and then use that for the >>>>> socket. Which we can do via security_compute_create(). Sample code >>>>> attached. Compile with: gcc -lselinux -o setsockcon setsockcon.c >>>>> >>>>> Example run (in permissive): >>>>> $ runcon system_u:system_r:init_t:s0 ./setsockcon /usr/sbin/sshd >>>>> /usr/sbin/sshd system_u:system_r:sshd_t:s0 >>>> >>>> So the concept here is that systemd must already know the path to the >>>> daemon executable as part of its config, so it can call the >>>> setsockconfrompath() function on that path prior to calling socket() to >>>> create the socket. You can have the function bail immediately if >>>> (is_selinux_enabled() < 1), and perhaps ignore errors from it if >>>> (security_getenforce() < 1). >>>> >>>> We'll need something similar for Unix domain sockets to ensure that the >>>> file gets labeled properly, but using security_compute_create() on the >>>> daemon context, the parent directory context, and >>>> string_to_security_class("sock_file") to determine the right context >>>> and using setfscreatecon() before calling bind(). A bit messy. >>> >>> I would need to check the code a bit closer and test it to be certain but >>> I believe that setsockcreatecon() should work for UNIX domain sockets >>> too. At least selinux_socket[_post]_create() applies the sockcreate_sid >>> regardless of the socket's address family. >>> >>> Granted, determining the correct label is still a bit ugly but at least >>> you don't have to use setfscreatecon() would could get nasty very >>> quickly if you're not careful. >> >> With Unix domain sockets bound to the filesystem namespace, there are >> two separate objects: the socket and the file. > > Yes, sorry, my mistake; I was thinking of the socket fsetxattr() labeling > support - that supported labeling the filesystem and socket components of a > UNIX domain socket. > Hacked up setsockcon a little bit further to try to establish the correct context for an object created by the executable in a particular directory runcon system_u:system_r:init_t:s0 ./setsockcon /bin/dbus-daemon /var/run/dbus/ sock_file /bin/dbus-daemon system_u:system_r:system_dbusd_t:s0 system_u:object_r:system_dbusd_var_run_t:s0 runcon system_u:system_r:init_t:s0 ./setsockcon /usr/sbin/avahi-daemon /var/run/avahi-daemon sock_file /usr/sbin/avahi-daemon system_u:system_r:avahi_t:s0 system_u:object_r:avahi_var_run_t:s0 This does not currently handle creating multiple objects in the path if they do not exist. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/ iEYEARECAAYFAkxEqrMACgkQrlYvE4MpobPXuACfQi1BUE3l3IwxfGdBAsuv5KXh RXcAoKTxC3wZrScQtvRqLvius46EcUl3 =Zd4q -----END PGP SIGNATURE-----
#include <selinux/selinux.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> /* class can be "file" "dir" "lnk_file" "sock_file" "fifo_file" "chr_file" "blk_file" */ static int getfileconfrompath(security_context_t scon, const char *path, char *class, security_context_t *newcon) { security_context_t fcon = NULL; security_class_t sclass; int rc = 0; rc = getfilecon(path, &fcon); if (rc < 0) goto out; sclass = string_to_security_class(class); rc = security_compute_create(scon, fcon, sclass, newcon); if (rc < 0) goto out; out: freecon(fcon); return rc; } static int getconfromexe(const char *exe, security_context_t *newcon) { security_context_t mycon = NULL, fcon = NULL; security_class_t sclass; int rc = 0; rc = getcon(&mycon); if (rc < 0) goto out; rc = getfilecon(exe, &fcon); if (rc < 0) goto out; sclass = string_to_security_class("process"); rc = security_compute_create(mycon, fcon, sclass, newcon); if (rc < 0) goto out; out: freecon(mycon); freecon(fcon); return rc; } void usage(const char *program) { printf( "%s exec_path listen_directory type\n\n" "%s /usr/sbin/avahi-daemon /var/run file\n" , program, program); } int main(int argc, char **argv) { int i; security_context_t newcon = NULL; security_context_t filecon = NULL; if ( argc < 3 ) { usage(argv[0]); exit(1); } /* This function returns the context defined in policy for the executable argv[1], after it transitions from the current context */ if (getconfromexe(argv[1], &newcon) < 0) { perror(argv[1]); exit(1); } /* This function tells the kernel to label all sockets after this call with the newcon context, untill this function is called again */ if (setsockcreatecon(newcon) < 0) { perror(argv[1]); exit(1); } /* This function returns the file context defined in policy for the context newcon, creating a object of type arg[2] in the directory argv[2] */ if (getfileconfrompath(newcon, argv[2], argv[3], &filecon) < 0) { perror(argv[2]); exit(1); } printf("%s %s %s\n", argv[1], newcon, filecon); /* This function tells the kernel to label all file system objects created after this call with the filecon context, until this function is called again */ if (setfscreatecon(filecon) < 0) { perror(filecon); exit(1); } freecon(newcon); freecon(filecon); /* calling setsockcreatecon and setfscreatecon with the NULL parameter resets the system to the default */ setsockcreatecon(NULL); setfscreatecon(NULL); exit(0); }
Attachment:
setsockcon.c.sig
Description: PGP signature