aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--security/selinux/selinuxfs.c45
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 274static ssize_t sel_write_context(struct file * file, char *buf, size_t size)
275static 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;
305out: 301out:
306 free_page((unsigned long) page); 302 kfree(canon);
307 return length; 303 return length;
308} 304}
309 305
310static struct file_operations sel_context_ops = {
311 .write = sel_write_context,
312};
313
314static ssize_t sel_read_checkreqprot(struct file *filp, char __user *buf, 306static 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
380static ssize_t selinux_transaction_write(struct file *file, const char __user *buf, size_t size, loff_t *pos) 373static 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},