[redhat-lspp] Labeled networking MLS constraints?

Paul Moore paul.moore at hp.com
Tue Oct 17 12:36:07 UTC 2006


On Monday 16 October 2006 9:49 pm, Klaus Weidner wrote:
> back in August we had a discussion about MLS enforcement related to TCP
> connections - could we revisit that from the viewpoint of the current
> networking code? I'm also unsure to what extent this applies to both
> CIPSO and IPSec/mlsxfrm, or if they handle things differently.
>
> Here's Paul Moore's explanation from an older discussion - I've added my
> interpretations below, please correct me if I'm misunderstanding things:

I'll throw my interpretations in too :)

> On Thu, Aug 31, 2006 at 02:01:28PM -0400, Paul Moore wrote:
> > When a process creates a socket through a call to socket() the socket
> > takes the SID of the process' domain and the NetLabel is set based on
> > that SID.  Assuming NetLabel/CIPSO is used, all data written to that
> > socket will be labeled with the socket's MLS label.
>
> So for the calls that use unconnected sockets, for example recvfrom() and
> recvmsg() for UDP communication, the socket's label should always be the
> same as the process label, right?

By default yes, but don't forget about setsockcreatecon() and sockets create 
by accept() when labeled networking is active on that connection.

> > When a process creates a socket through a call to accept() when CIPSO
> > tags are present on the TCP handshake packets the child socket's SID is
> > a combination of the parent socket's context and the *connection's* MLS
> > label.  All data writeen to the child socket will be labeled with the
> > socket/connection's MLS label.
>
> I'm confused here - assuming that it's a TCP connection and the handshake
> packets indicate that the connection's MLS label doesn't permit
> communication with the process, what happens? Does the accept() call
> fail, or does it succeed and the socket gets created anyway (with the
> connection's MLS label), but any attempt to read/write from the socket
> then fails?

You got it, the access check on the accept() call depends on the context of 
the current process/domain and the parent socket's type.  Due to some 
limitations in the placement of the LSM accept hook and the nature of the 
network stack it's just not possible with the code we have today to block 
access at the accept() syscall.

We might be able to do this if we added/modified some LSM hooks but I don't 
think that is reasonable to expect in the RHEL5 timeframe we are facing.

> > When packets are received and a CIPSO tag is present NetLabel generates
> > a SID for the packet based on the receiving socket's context and the
> > packet's CIPSO MLS label.  The packet's SID is then compared to the
> > socket's SID with an avc_has_perm() call, the socket's SID is the
> > subject the packet's SID is the object.

This is a little different now, instead of using the receiving socket's 
context the SECINITSID_UNLABELED context is used instead, i.e. "unlabeled_t".

> > All reads/writes to and from a socket or file descriptor behave as they
> > always have, the process' SID is checked against the socket/fd's SID,
> > the process' SID is the subject and the socket/fd's SID is the object.
>
> For recvmsg/recvfrom with unconnected sockets (for example UDP), that
> should mean that incoming packets get dropped in the packet/socket check,
> and that the read call will never fail due to missing MLS rights - it
> just won't get any data.

I'm only going to speak about the recvfrom permission as that is what 
NetLabel/CIPSO uses, if I remember correctly recvmsg is only used by the 
compat_net method of determining local packet labels.

There are basically two checks a packet with CIPSO tagging must face before it 
can be "read" by a process.  The first check is a check between the generated 
(explained above) NetLabel packet context and the receiving socket's context; 
this uses the "recvfrom" permission.  The second check is between the 
processes' domain and the socket's context; this uses the normal socket read 
permissions.

> For sendto/sendmsg, the MLS check would happen at 
> the receiving machine, does this mean that there is no MLS enforcement
> for sending packets out at this level? Will they get dropped if there is
> no valid CIPSO DOI mapping or SELinux SA?

NetLabel does not impose any additional restrictions on sending data (other 
then denying the send if it can not label the data as intended by the 
configuration).  This is largely due to the fact that CIPSO does not do any 
sort of negotiation between hosts; it simply attaches the security attributes 
to a packet and dumps the packet on the wire.

I believe labeled IPsec does add an additional restriction on sending data as 
it can use the outbound SA; perhaps Joy or Venkat can explain this in further 
detail.

> About the "all reads/writes" - does this also apply to more exotic
> interfaces such as the new splice() call? For example, I didn't see an
> obvious LSM hook in net/ipv4/tcp.c:do_tcp_sendpages(), but I haven't
> tracked down the call chain to see if it's in another function, or if
> it's even necessary.

I can't say right now, this is the first I've heard of splice().  If there is 
no LSM hook in place at some point in the splice() stack then this is a 
serious bug not just for labeled networking but LSM and SELinux in general.

-- 
paul moore
linux security @ hp




More information about the redhat-lspp mailing list