|
@@ -1423,6 +1423,41 @@ static int selinux_capable(struct task_struct *tsk, int cap)
|
|
return task_has_capability(tsk,cap);
|
|
return task_has_capability(tsk,cap);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int selinux_sysctl_get_sid(ctl_table *table, u16 tclass, u32 *sid)
|
|
|
|
+{
|
|
|
|
+ int buflen, rc;
|
|
|
|
+ char *buffer, *path, *end;
|
|
|
|
+
|
|
|
|
+ rc = -ENOMEM;
|
|
|
|
+ buffer = (char*)__get_free_page(GFP_KERNEL);
|
|
|
|
+ if (!buffer)
|
|
|
|
+ goto out;
|
|
|
|
+
|
|
|
|
+ buflen = PAGE_SIZE;
|
|
|
|
+ end = buffer+buflen;
|
|
|
|
+ *--end = '\0';
|
|
|
|
+ buflen--;
|
|
|
|
+ path = end-1;
|
|
|
|
+ *path = '/';
|
|
|
|
+ while (table) {
|
|
|
|
+ const char *name = table->procname;
|
|
|
|
+ size_t namelen = strlen(name);
|
|
|
|
+ buflen -= namelen + 1;
|
|
|
|
+ if (buflen < 0)
|
|
|
|
+ goto out_free;
|
|
|
|
+ end -= namelen;
|
|
|
|
+ memcpy(end, name, namelen);
|
|
|
|
+ *--end = '/';
|
|
|
|
+ path = end;
|
|
|
|
+ table = table->parent;
|
|
|
|
+ }
|
|
|
|
+ rc = security_genfs_sid("proc", path, tclass, sid);
|
|
|
|
+out_free:
|
|
|
|
+ free_page((unsigned long)buffer);
|
|
|
|
+out:
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
static int selinux_sysctl(ctl_table *table, int op)
|
|
static int selinux_sysctl(ctl_table *table, int op)
|
|
{
|
|
{
|
|
int error = 0;
|
|
int error = 0;
|
|
@@ -1437,8 +1472,8 @@ static int selinux_sysctl(ctl_table *table, int op)
|
|
|
|
|
|
tsec = current->security;
|
|
tsec = current->security;
|
|
|
|
|
|
- rc = selinux_proc_get_sid(table->de, (op == 001) ?
|
|
|
|
- SECCLASS_DIR : SECCLASS_FILE, &tsid);
|
|
|
|
|
|
+ rc = selinux_sysctl_get_sid(table, (op == 0001) ?
|
|
|
|
+ SECCLASS_DIR : SECCLASS_FILE, &tsid);
|
|
if (rc) {
|
|
if (rc) {
|
|
/* Default to the well-defined sysctl SID. */
|
|
/* Default to the well-defined sysctl SID. */
|
|
tsid = SECINITSID_SYSCTL;
|
|
tsid = SECINITSID_SYSCTL;
|