diff options
| author | Kohei Kaigai <Kohei.Kaigai@eu.nec.com> | 2011-04-01 15:39:26 +0100 | 
|---|---|---|
| committer | Eric Paris <eparis@redhat.com> | 2011-04-01 17:13:23 -0400 | 
| commit | f50a3ec961f90e38c0311411179d5dfee1412192 (patch) | |
| tree | 600b7909964cd116af1252ecabb5b1415c01d7a0 | |
| parent | 6bde95ce33e1c2ac9b5cb3d814722105131090ec (diff) | |
| download | olio-linux-3.10-f50a3ec961f90e38c0311411179d5dfee1412192.tar.xz olio-linux-3.10-f50a3ec961f90e38c0311411179d5dfee1412192.zip  | |
selinux: add type_transition with name extension support for selinuxfs
The attached patch allows /selinux/create takes optional 4th argument
to support TYPE_TRANSITION with name extension for userspace object
managers.
If 4th argument is not supplied, it shall perform as existing kernel.
In fact, the regression test of SE-PostgreSQL works well on the patched
kernel.
Thanks,
Signed-off-by: KaiGai Kohei <kohei.kaigai@eu.nec.com>
[manually verify fuzz was not an issue, and it wasn't: eparis]
Signed-off-by: Eric Paris <eparis@redhat.com>
| -rw-r--r-- | security/selinux/include/security.h | 4 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 16 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 17 | 
3 files changed, 25 insertions, 12 deletions
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index bfc5218d584..2cf67086414 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -112,8 +112,8 @@ void security_compute_av_user(u32 ssid, u32 tsid,  int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,  			    const struct qstr *qstr, u32 *out_sid); -int security_transition_sid_user(u32 ssid, u32 tsid, -				 u16 tclass, u32 *out_sid); +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, +				 const char *objname, u32 *out_sid);  int security_member_sid(u32 ssid, u32 tsid,  	u16 tclass, u32 *out_sid); diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index ea39cb742ae..973f5a4a6fc 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c @@ -753,11 +753,13 @@ out:  static ssize_t sel_write_create(struct file *file, char *buf, size_t size)  {  	char *scon = NULL, *tcon = NULL; +	char *namebuf = NULL, *objname = NULL;  	u32 ssid, tsid, newsid;  	u16 tclass;  	ssize_t length;  	char *newcon = NULL;  	u32 len; +	int nargs;  	length = task_has_security(current, SECURITY__COMPUTE_CREATE);  	if (length) @@ -773,9 +775,17 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)  	if (!tcon)  		goto out; +	length = -ENOMEM; +	namebuf = kzalloc(size + 1, GFP_KERNEL); +	if (!namebuf) +		goto out; +  	length = -EINVAL; -	if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) +	nargs = sscanf(buf, "%s %s %hu %s", scon, tcon, &tclass, namebuf); +	if (nargs < 3 || nargs > 4)  		goto out; +	if (nargs == 4) +		objname = namebuf;  	length = security_context_to_sid(scon, strlen(scon) + 1, &ssid);  	if (length) @@ -785,7 +795,8 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)  	if (length)  		goto out; -	length = security_transition_sid_user(ssid, tsid, tclass, &newsid); +	length = security_transition_sid_user(ssid, tsid, tclass, +					      objname, &newsid);  	if (length)  		goto out; @@ -804,6 +815,7 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)  	length = len;  out:  	kfree(newcon); +	kfree(namebuf);  	kfree(tcon);  	kfree(scon);  	return length; diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 03f7a4748ee..39d732145ab 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1360,14 +1360,14 @@ out:  static void filename_compute_type(struct policydb *p, struct context *newcontext,  				  u32 scon, u32 tcon, u16 tclass, -				  const struct qstr *qstr) +				  const char *objname)  {  	struct filename_trans *ft;  	for (ft = p->filename_trans; ft; ft = ft->next) {  		if (ft->stype == scon &&  		    ft->ttype == tcon &&  		    ft->tclass == tclass && -		    !strcmp(ft->name, qstr->name)) { +		    !strcmp(ft->name, objname)) {  			newcontext->type = ft->otype;  			return;  		} @@ -1378,7 +1378,7 @@ static int security_compute_sid(u32 ssid,  				u32 tsid,  				u16 orig_tclass,  				u32 specified, -				const struct qstr *qstr, +				const char *objname,  				u32 *out_sid,  				bool kern)  { @@ -1479,9 +1479,9 @@ static int security_compute_sid(u32 ssid,  	}  	/* if we have a qstr this is a file trans check so check those rules */ -	if (qstr) +	if (objname)  		filename_compute_type(&policydb, &newcontext, scontext->type, -				      tcontext->type, tclass, qstr); +				      tcontext->type, tclass, objname);  	/* Check for class-specific changes. */  	if (specified & AVTAB_TRANSITION) { @@ -1539,13 +1539,14 @@ int security_transition_sid(u32 ssid, u32 tsid, u16 tclass,  			    const struct qstr *qstr, u32 *out_sid)  {  	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, -				    qstr, out_sid, true); +				    qstr ? qstr->name : NULL, out_sid, true);  } -int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, u32 *out_sid) +int security_transition_sid_user(u32 ssid, u32 tsid, u16 tclass, +				 const char *objname, u32 *out_sid)  {  	return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, -				    NULL, out_sid, false); +				    objname, out_sid, false);  }  /**  |