diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 3 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 45 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 5 |
3 files changed, 26 insertions, 27 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 45c41490d521..fc774436a264 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -1986,6 +1986,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, | |||
1986 | 1986 | ||
1987 | inode_security_set_sid(inode, newsid); | 1987 | inode_security_set_sid(inode, newsid); |
1988 | 1988 | ||
1989 | if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) | ||
1990 | return -EOPNOTSUPP; | ||
1991 | |||
1989 | if (name) { | 1992 | if (name) { |
1990 | namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); | 1993 | namep = kstrdup(XATTR_SELINUX_SUFFIX, GFP_KERNEL); |
1991 | if (!namep) | 1994 | if (!namep) |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index fdc382389720..0e1352a555c8 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -271,46 +271,38 @@ static struct file_operations sel_load_ops = { | |||
271 | .write = sel_write_load, | 271 | .write = sel_write_load, |
272 | }; | 272 | }; |
273 | 273 | ||
274 | 274 | static ssize_t sel_write_context(struct file * file, char *buf, size_t size) | |
275 | static ssize_t sel_write_context(struct file * file, const char __user * buf, | ||
276 | size_t count, loff_t *ppos) | ||
277 | |||
278 | { | 275 | { |
279 | char *page; | 276 | char *canon; |
280 | u32 sid; | 277 | u32 sid, len; |
281 | ssize_t length; | 278 | ssize_t length; |
282 | 279 | ||
283 | length = task_has_security(current, SECURITY__CHECK_CONTEXT); | 280 | length = task_has_security(current, SECURITY__CHECK_CONTEXT); |
284 | if (length) | 281 | if (length) |
285 | return length; | 282 | return length; |
286 | 283 | ||
287 | if (count >= PAGE_SIZE) | 284 | length = security_context_to_sid(buf, size, &sid); |
288 | return -ENOMEM; | 285 | if (length < 0) |
289 | if (*ppos != 0) { | 286 | return length; |
290 | /* No partial writes. */ | ||
291 | return -EINVAL; | ||
292 | } | ||
293 | page = (char*)get_zeroed_page(GFP_KERNEL); | ||
294 | if (!page) | ||
295 | return -ENOMEM; | ||
296 | length = -EFAULT; | ||
297 | if (copy_from_user(page, buf, count)) | ||
298 | goto out; | ||
299 | 287 | ||
300 | length = security_context_to_sid(page, count, &sid); | 288 | length = security_sid_to_context(sid, &canon, &len); |
301 | if (length < 0) | 289 | if (length < 0) |
290 | return length; | ||
291 | |||
292 | if (len > SIMPLE_TRANSACTION_LIMIT) { | ||
293 | printk(KERN_ERR "%s: context size (%u) exceeds payload " | ||
294 | "max\n", __FUNCTION__, len); | ||
295 | length = -ERANGE; | ||
302 | goto out; | 296 | goto out; |
297 | } | ||
303 | 298 | ||
304 | length = count; | 299 | memcpy(buf, canon, len); |
300 | length = len; | ||
305 | out: | 301 | out: |
306 | free_page((unsigned long) page); | 302 | kfree(canon); |
307 | return length; | 303 | return length; |
308 | } | 304 | } |
309 | 305 | ||
310 | static struct file_operations sel_context_ops = { | ||
311 | .write = sel_write_context, | ||
312 | }; | ||
313 | |||
314 | static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, | 306 | static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, |
315 | size_t count, loff_t *ppos) | 307 | size_t count, loff_t *ppos) |
316 | { | 308 | { |
@@ -375,6 +367,7 @@ static ssize_t (*write_op[])(struct file *, char *, size_t) = { | |||
375 | [SEL_RELABEL] = sel_write_relabel, | 367 | [SEL_RELABEL] = sel_write_relabel, |
376 | [SEL_USER] = sel_write_user, | 368 | [SEL_USER] = sel_write_user, |
377 | [SEL_MEMBER] = sel_write_member, | 369 | [SEL_MEMBER] = sel_write_member, |
370 | [SEL_CONTEXT] = sel_write_context, | ||
378 | }; | 371 | }; |
379 | 372 | ||
380 | static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) | 373 | static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) |
@@ -1220,7 +1213,7 @@ static int sel_fill_super(struct super_block * sb, void * data, int silent) | |||
1220 | static struct tree_descr selinux_files[] = { | 1213 | static struct tree_descr selinux_files[] = { |
1221 | [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, | 1214 | [SEL_LOAD] = {"load", &sel_load_ops, S_IRUSR|S_IWUSR}, |
1222 | [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, | 1215 | [SEL_ENFORCE] = {"enforce", &sel_enforce_ops, S_IRUGO|S_IWUSR}, |
1223 | [SEL_CONTEXT] = {"context", &sel_context_ops, S_IRUGO|S_IWUGO}, | 1216 | [SEL_CONTEXT] = {"context", &transaction_ops, S_IRUGO|S_IWUGO}, |
1224 | [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, | 1217 | [SEL_ACCESS] = {"access", &transaction_ops, S_IRUGO|S_IWUGO}, |
1225 | [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, | 1218 | [SEL_CREATE] = {"create", &transaction_ops, S_IRUGO|S_IWUGO}, |
1226 | [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, | 1219 | [SEL_RELABEL] = {"relabel", &transaction_ops, S_IRUGO|S_IWUGO}, |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index aaefac2921f1..640d0bfdbc68 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -262,8 +262,11 @@ int mls_context_to_sid(char oldc, | |||
262 | struct cat_datum *catdatum, *rngdatum; | 262 | struct cat_datum *catdatum, *rngdatum; |
263 | int l, rc = -EINVAL; | 263 | int l, rc = -EINVAL; |
264 | 264 | ||
265 | if (!selinux_mls_enabled) | 265 | if (!selinux_mls_enabled) { |
266 | if (def_sid != SECSID_NULL && oldc) | ||
267 | *scontext += strlen(*scontext); | ||
266 | return 0; | 268 | return 0; |
269 | } | ||
267 | 270 | ||
268 | /* | 271 | /* |
269 | * No MLS component to the security context, try and map to | 272 | * No MLS component to the security context, try and map to |