diff options
Diffstat (limited to 'security/selinux/selinuxfs.c')
-rw-r--r-- | security/selinux/selinuxfs.c | 45 |
1 files changed, 19 insertions, 26 deletions
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}, |