On Thu, 2010-03-25 at 14:23 -0400, Eric Paris wrote: > On Thu, 2010-03-25 at 14:11 -0400, Daniel J Walsh wrote: > > On 03/25/2010 02:06 PM, Stephen Smalley wrote: > > > On Thu, 2010-03-25 at 12:49 -0400, Paul Moore wrote: > > > > > >> On Thursday 25 March 2010 10:02:48 am Stephen Smalley wrote: > > >> > > >>> On Wed, 2010-03-24 at 22:42 -0400, Eric Paris wrote: > > >>> > > >>>> On Tue, 2010-03-23 at 11:44 +0000, Daniel P. Berrange wrote: > > >>>> > > >>>>> On Tue, Mar 23, 2010 at 07:35:13AM -0400, Daniel J Walsh wrote: > > >>>>> > > >>>>>> On 03/22/2010 07:47 PM, Eric Paris wrote: > > >>>>>> > > >>>>>>> On Mon, 2010-03-22 at 17:44 -0400, Daniel J Walsh wrote: > > >>>>>>> > > >>>>>>>> type=AVC msg=audit(1269293509.223:4753): avc: denied { write } > > >>>>>>>> for pid=28549 comm="qemu-kvm" path="socket:[4417531]" dev=sockfs > > >>>>>>>> ino=4417531 scontext=system_u:system_r:svirt_t:s0:c1 > > >>>>>>>> tcontext=system_u:system_r:svirt_t:s0-s15:c0.c1023 > > >>>>>>>> tclass=unix_stream_socket > > >>>>>>>> > > >>>>>>>> I have Static Virtualization working on an MLS box except for this > > >>>>>>>> strange AVC. > > >>>>>>>> > > >> ... > > >> > > >> > > >>>>>>>> # ps -eZ | grep virt > > >>>>>>>> system_u:system_r:virtd_t:s0-s15:c0.c1023 27344 ? 05:34:47 libvirtd > > >>>>>>>> system_u:system_r:svirt_t:s0:c1 28549 ? 00:00:01 qemu-kvm > > >>>>>>>> > > >> ... > > >> > > >> > > >>>>>>>> # ls -lZ /proc/28549/fd/ | grep 4417531 > > >>>>>>>> lrwx------. qemu qemu system_u:system_r:svirt_t:s0:c1 17 -> > > >>>>>>>> socket:[4417531] > > >>>>>>>> > > >>>>>>>> lsof | grep 4417531 > > >>>>>>>> > > >>>>>>>> qemu-kvm 28549 qemu 17u unix 0xffff88003e1f7900 > > >>>>>>>> 0t0 4417531 /var/lib/libvirt/qemu/xguest.monitor > > >>>>>>>> > > >>>>>>>> # lsof /var/lib/libvirt/qemu/xguest.monitor > > >>>>>>>> COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE > > >>>>>>>> NAME qemu-kvm 28549 qemu 3u unix 0xffff88003a853000 0t0 > > >>>>>>>> 4417518 /var/lib/libvirt/qemu/xguest.monitor > > >>>>>>>> qemu-kvm 28549 qemu 17u unix 0xffff88003e1f7900 0t0 4417531 > > >>>>>>>> /var/lib/libvirt/qemu/xguest.monitor > > >>>>>>>> > > >>>>>>>> So it looks like we have a process that is running as both labels? > > >>>>>>>> > > >>>>>>> This is a check between the type of the process and that of the > > >>>>>>> socket itself, not between 2 processes. So, the type of the socket > > >>>>>>> is wrong. Just as a question, what does ls -lZ > > >>>>>>> /var/lib/libvirt/qemu/ show? c0-c1023 for xguest.monitor? What > > >>>>>>> created that socket? Did they get it correct? (I admit it looks > > >>>>>>> correct on my F13ish system) > > >>>>>>> > > >>>>>> The socket file is labeled svirt_var_run_t and has the correct level. > > >>>>>> > > >>>>>> I believe the socket file was created by qemu. Dan can you confirm > > >>>>>> this. > > >>>>>> > > >>>>> Yes, these sockets are created by QEMU when it starts. libvirt just > > >>>>> gives it the path at which to create the socket. > > >>>>> > > >>>>> > > >>>>>> # ls -lZa /var/lib/libvirt/qemu/ > > >>>>>> > > >>>>>> drwx------. qemu qemu > > >>>>>> system_u:object_r:svirt_var_run_t:s0-s15:c0.c1023 . drwxr-xr-x. root > > >>>>>> root system_u:object_r:virt_var_lib_t:s0 .. srwxr-xr-x. qemu qemu > > >>>>>> system_u:object_r:svirt_var_run_t:s0:c1 xguest.monitor > > >>>>>> > > >>>> And then libvirt attaches to the other end? > > >>>> > > >>>> In any case, doing some digging the problem (where we first end up with > > >>>> this crazy context with the type of svirt_t but the MLS label of > > >>>> libvirt) is in selinux_socket_unix_stream_connect(). We never saw this > > >>>> in MCS because we don't have constraints on unix domain sockets in > > >>>> targetted/MCS policy. At this hour of the night my brain isn't running > > >>>> well enough nor is my networking foo strong enough to understand exactly > > >>>> which object is supposed to be labeled what where, but it has to be > > >>>> something with the call to security_sid_mls_copy(). > > >>>> > > >>>> I'll certainly be looking at this again in the morning. > > >>>> > > >>> That's intentional behavior for MLS. > > >>> > > >> Stephen is correct, the general idea is that when a connected child socket is > > >> created on a socket accepting incoming connections it is labeled using the > > >> type of the listening socket and the MLS attributes of the remote peer. As an > > >> example, imagine client client_t:s0:c1 connecting to server server_t:s0- > > >> s15:c0.c1023, the client's connected socket would be labeled client_t:s0:c1 > > >> (it inherits the label from the client process) while the server's connected > > >> child socket would be labeled server_t:s0:c1 (labeled as described above). > > >> > > >> Now, while the code (looking at Linus' current tree, but this hasn't changed > > >> in a while) it does handle labeling UNIX sockets correctly but there are a few > > >> things which strike me as odd, if not wrong: > > >> > > >> 1. The "peer_sid" field of the client's socket is set to the label of the > > >> server's listening socket, NOT the derived label used for the server's child > > >> socket. This means that the MLS attributes of the "peer_sid" stored in the > > >> client's socket do not match the MLS attributes of the server's child socket. > > >> This isn't consistent with how we handle INET sockets, but then again with > > >> UNIX sockets we know the labels of both the remote socket and the remote peer; > > >> with INET sockets we only get one label. In some ways this gets back to the > > >> socket as an endpoint argument and I'm not sure we want to dig that up. > > >> > > > That should likely be changed. > > > > > > > > >> 2. We don't currently update the server's child socket inode label to reflect > > >> the derived label used in the socket. A potential difference between INET and > > >> UNIX socket handling if security_sock_graft() is not called at some point in > > >> the connect process (need to track this down, but it didn't jump out at me in > > >> unix_stream_connect()). > > >> > > > unix_accept() calls sock_graft, so I think that is already covered. > > > > > > > > >> 3. Somewhat unrelated I think, but selinux_socket_unix_may_send() doesn't use > > >> the socket/sock labels, it relies on the inode labels. As has been mentioned > > >> several times in the past, we need to unify the inode/sock labels better. > > >> > > >> There may be more issues, but these are the ones that caught my eye when > > >> scanning the UNIX socket code quickly. Item #1 is probably only an annoyance > > >> that you would see in getpeercon() but we should still probably fix. Item's > > >> #2 and #3 are potentially a bit more serious as the file descriptor access > > >> controls are going to use the inode's label so a mis-match between the socket > > >> and inode labels could cause some rather strange behavior. I can go through > > >> and cleanup this code (it is long overdue), but I want to get some consensus > > >> first on how we want UNIX sockets to behave. > > >> > > >> > > > > Eric, explained what is going on here is actually > > virtd_t:s0-s15:c0.c1023 is trying to write to svirt_t:s0:c1. > > > > So I need to add mls_net_write_within_range(virtd_t), correct? > > I admit to being at least as network ignorant as the next guy, but I'm > totally not understanding why the type of the socket makes sense. We > have two ends of this unix domain socket: > > svirt_t:c0:c1 and libvirtd_t:s0-s15:c0-c1023 > > The label on the socket, and thus the label that both ends are going to > have to check against is actually some amalgamation of the context on > both ends. In fact the socket gets the type of svirt_t and the level of > s0-s15:c0-c1023, svirt_t:c0-s15:c0-c1023. Now we need to allow both: > > svirt_t:s0:c1 -> svirt_t:s0-s15:c0-c1023 > libvirtd_t:s0-s15:c0-c1023 -> sivrt_t:s0-s15:c0-c1023 > > to use this screwy label that I don't understand at all. I guess I just > don't like the fact that somehow the MLS portion is a magic different > class citizen. It seems to me that the 'correct' checks on a unix > domain socket (where we really know this info) would be different > depending on the direction. We should need to allow > > svirt_t:s0:c1 -> libvirtd_t:s0-s15:c0-c1023 > libvirtd_t:s0-s15:c0-c1023 -> svirt_t:s0:c1 > > No more of this horrific magic derived other context. Obviously I'm > networking clueless, but someone please explain me how this type makes > sense..... You should get the desired permission checks between the client socket and the listening socket (which will reflect client and server contexts). But the behavior for the new connection/server socket was changed for MLS during the LSPP work to reflect the level of the client. This makes sense when you have a single-level client connecting to a ranged server - the connection is then established at the requesting level and the traffic is labeled and protected accordingly. It doesn't make sense to me when you have a ranged client. -- Stephen Smalley National Security Agency -- This message was distributed to subscribers of the selinux mailing list. If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with the words "unsubscribe selinux" without quotes as the message.