[redhat-lspp] Updated NetLabel patch

Paul Moore paul.moore at hp.com
Mon Jun 19 17:06:28 UTC 2006


Stephen Smalley wrote:
> On Thu, 2006-06-15 at 15:16 -0400, Paul Moore wrote:
> 
>>Sorry, I typed fork when I mean fork-and-exec, I understand why you
>>wouldn't want to do a context transition on a fork.
>>
>>I guess I need to look at the xinetd sources as well as Trent's xinetd
>>patch one more time as I didn't remember xinetd doing an accept().  I
>>thought xinetd just setup a socket and waited for a select() to fire for
>>the socket and then did the fork-and-exec.  If that isn't the case then
>>this is really going to require some thought ...
> 
> You'd have to accept before you could get the peer context - peer only
> makes sense for a connected socket.
> 
> Per xinetd.conf, the wait attribute controls whether or not xinetd does
> the accept on a per-service basis, and tcp services generally use wait =
> no, which means xinetd handles accepting the connections.
> 

After some head scratching I believe I have come across a solution which
should retain the tranquility of the system while solving the accept()
problem.  It works as follows:

 1. Remote system establishes a TCP connection and is put on the accept
    queue for the socket.  Like now there is no LSM intervention and the
    IP options are set according to the core network stack (i.e. copied
    from the incoming packet).
 2. User application calls accept() which triggers the LSM accept hooks.
    The NetLabel code records the CIPSO label in a new struct inside
    the inode_security_struct.  It also sets a flag in the same struct
    to indicate that this socket needs to be "NetLabel'd".  Reads on the
    newly accept()ed socket continue to be labeled according to the
    skb's CIPSO label.

     struct netlbl_security_struct {
	u32 netlbl_sid;           /* SID used to set the NetLabel */
	u32 peer_sid;             /* SID of the connected peer */
	u32 req_netlbl:1,         /* socket requires a NetLabel label */
	    labeled:1,            /* socket is labeled with NetLabel */
	    __unused:30;
     };

 3. When the application does a write to the newly accept()ed socket
    it hits a NetLabel hook placed in either socket_sendmsg() or
    file_permission(), after the existing AVC check, and the NetLabel
    hook looks at the netlbl_security_struct to determine if the socket
    needs "NetLabel'ing".  If so it performs the NetLabel using the
    task's current SID, otherwise it falls through.  If the socket is
    already "NetLabel'ed" it checks the SID used to "NetLabel" the
    socket and if they are not equal it fails.

This basically deffers setting the NetLabel on the socket until any user
data is sent across the socket, and when it is "NetLabel'ed" the current
task's SID is used, not the parent socket's SID.  I feel that not only
does this make more sense conceptually (the data being sent belongs in
the current->sid domain) but it solves the problem of the accept()ed
socket having a different domain/MLS-label than the current domain.
Plus, there shouldn't be any violation of tranquility since the socket's
SID is never relabeled and the existing AVC checks are left intact.

I have code for this but I haven't had a chance to test it yet.  Comments?

-- 
paul moore
linux security @ hp




More information about the redhat-lspp mailing list