[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