SELinux: Compute SID for the newly created socket

The security context for the newly created socket shares the same
user, role and MLS attribute as its creator but may have a different
type, which could be specified by a type_transition rule in the relevant
policy package.

Signed-off-by: Harry Ciao <qingtao.cao@windriver.com>
[fix call to security_transition_sid to include qstr, Eric Paris]
Signed-off-by: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
This commit is contained in:
Harry Ciao 2011-03-02 13:32:34 +08:00 committed by Eric Paris
parent 6f5317e730
commit 2ad18bdf3b

View File

@ -3591,9 +3591,16 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
/* socket security operations */
static u32 socket_sockcreate_sid(const struct task_security_struct *tsec)
static int socket_sockcreate_sid(const struct task_security_struct *tsec,
u16 secclass, u32 *socksid)
{
return tsec->sockcreate_sid ? : tsec->sid;
if (tsec->sockcreate_sid > SECSID_NULL) {
*socksid = tsec->sockcreate_sid;
return 0;
}
return security_transition_sid(tsec->sid, tsec->sid, secclass, NULL,
socksid);
}
static int sock_has_perm(struct task_struct *task, struct sock *sk, u32 perms)
@ -3617,12 +3624,16 @@ static int selinux_socket_create(int family, int type,
const struct task_security_struct *tsec = current_security();
u32 newsid;
u16 secclass;
int rc;
if (kern)
return 0;
newsid = socket_sockcreate_sid(tsec);
secclass = socket_type_to_security_class(family, type, protocol);
rc = socket_sockcreate_sid(tsec, secclass, &newsid);
if (rc)
return rc;
return avc_has_perm(tsec->sid, newsid, secclass, SOCKET__CREATE, NULL);
}
@ -3634,12 +3645,16 @@ static int selinux_socket_post_create(struct socket *sock, int family,
struct sk_security_struct *sksec;
int err = 0;
isec->sclass = socket_type_to_security_class(family, type, protocol);
if (kern)
isec->sid = SECINITSID_KERNEL;
else
isec->sid = socket_sockcreate_sid(tsec);
else {
err = socket_sockcreate_sid(tsec, isec->sclass, &(isec->sid));
if (err)
return err;
}
isec->sclass = socket_type_to_security_class(family, type, protocol);
isec->initialized = 1;
if (sock->sk) {