diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2007-03-12 12:17:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-14 18:27:48 -0400 |
commit | 04ff97086b1a3237bbd1fe6390fa80fe75207e23 (patch) | |
tree | 877e26055759d84a726c6bc68245bc6f9a4a5753 | |
parent | c4823bce033be74c0fcfbcae2f1be0854fdc2e18 (diff) |
[PATCH] sanitize security_getprocattr() API
have it return the buffer it had allocated
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Acked-by: James Morris <jmorris@namei.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/proc/base.c | 21 | ||||
-rw-r--r-- | include/linux/security.h | 8 | ||||
-rw-r--r-- | security/dummy.c | 2 | ||||
-rw-r--r-- | security/selinux/hooks.c | 8 |
4 files changed, 17 insertions, 22 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 01f7769da8e6..989af5e55d1b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1558,29 +1558,20 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, | |||
1558 | size_t count, loff_t *ppos) | 1558 | size_t count, loff_t *ppos) |
1559 | { | 1559 | { |
1560 | struct inode * inode = file->f_path.dentry->d_inode; | 1560 | struct inode * inode = file->f_path.dentry->d_inode; |
1561 | unsigned long page; | 1561 | char *p = NULL; |
1562 | ssize_t length; | 1562 | ssize_t length; |
1563 | struct task_struct *task = get_proc_task(inode); | 1563 | struct task_struct *task = get_proc_task(inode); |
1564 | 1564 | ||
1565 | length = -ESRCH; | ||
1566 | if (!task) | 1565 | if (!task) |
1567 | goto out_no_task; | 1566 | return -ESRCH; |
1568 | |||
1569 | if (count > PAGE_SIZE) | ||
1570 | count = PAGE_SIZE; | ||
1571 | length = -ENOMEM; | ||
1572 | if (!(page = __get_free_page(GFP_KERNEL))) | ||
1573 | goto out; | ||
1574 | 1567 | ||
1575 | length = security_getprocattr(task, | 1568 | length = security_getprocattr(task, |
1576 | (char*)file->f_path.dentry->d_name.name, | 1569 | (char*)file->f_path.dentry->d_name.name, |
1577 | (void*)page, count); | 1570 | &p); |
1578 | if (length >= 0) | ||
1579 | length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); | ||
1580 | free_page(page); | ||
1581 | out: | ||
1582 | put_task_struct(task); | 1571 | put_task_struct(task); |
1583 | out_no_task: | 1572 | if (length > 0) |
1573 | length = simple_read_from_buffer(buf, count, ppos, p, length); | ||
1574 | kfree(p); | ||
1584 | return length; | 1575 | return length; |
1585 | } | 1576 | } |
1586 | 1577 | ||
diff --git a/include/linux/security.h b/include/linux/security.h index 7f88d97575fd..47e82c120f9a 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -1324,7 +1324,7 @@ struct security_operations { | |||
1324 | 1324 | ||
1325 | void (*d_instantiate) (struct dentry *dentry, struct inode *inode); | 1325 | void (*d_instantiate) (struct dentry *dentry, struct inode *inode); |
1326 | 1326 | ||
1327 | int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); | 1327 | int (*getprocattr)(struct task_struct *p, char *name, char **value); |
1328 | int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); | 1328 | int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); |
1329 | int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); | 1329 | int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); |
1330 | void (*release_secctx)(char *secdata, u32 seclen); | 1330 | void (*release_secctx)(char *secdata, u32 seclen); |
@@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * | |||
2092 | security_ops->d_instantiate (dentry, inode); | 2092 | security_ops->d_instantiate (dentry, inode); |
2093 | } | 2093 | } |
2094 | 2094 | ||
2095 | static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) | 2095 | static inline int security_getprocattr(struct task_struct *p, char *name, char **value) |
2096 | { | 2096 | { |
2097 | return security_ops->getprocattr(p, name, value, size); | 2097 | return security_ops->getprocattr(p, name, value); |
2098 | } | 2098 | } |
2099 | 2099 | ||
2100 | static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) | 2100 | static inline int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size) |
@@ -2749,7 +2749,7 @@ static inline int security_sem_semop (struct sem_array * sma, | |||
2749 | static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) | 2749 | static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) |
2750 | { } | 2750 | { } |
2751 | 2751 | ||
2752 | static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) | 2752 | static inline int security_getprocattr(struct task_struct *p, char *name, char **value) |
2753 | { | 2753 | { |
2754 | return -EINVAL; | 2754 | return -EINVAL; |
2755 | } | 2755 | } |
diff --git a/security/dummy.c b/security/dummy.c index 558795b237d6..8ffd76405b5b 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) | |||
907 | return; | 907 | return; |
908 | } | 908 | } |
909 | 909 | ||
910 | static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) | 910 | static int dummy_getprocattr(struct task_struct *p, char *name, char **value) |
911 | { | 911 | { |
912 | return -EINVAL; | 912 | return -EINVAL; |
913 | } | 913 | } |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 19a385e9968e..d41e24d6ae41 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -4468,11 +4468,12 @@ static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) | |||
4468 | } | 4468 | } |
4469 | 4469 | ||
4470 | static int selinux_getprocattr(struct task_struct *p, | 4470 | static int selinux_getprocattr(struct task_struct *p, |
4471 | char *name, void *value, size_t size) | 4471 | char *name, char **value) |
4472 | { | 4472 | { |
4473 | struct task_security_struct *tsec; | 4473 | struct task_security_struct *tsec; |
4474 | u32 sid; | 4474 | u32 sid; |
4475 | int error; | 4475 | int error; |
4476 | unsigned len; | ||
4476 | 4477 | ||
4477 | if (current != p) { | 4478 | if (current != p) { |
4478 | error = task_has_perm(current, p, PROCESS__GETATTR); | 4479 | error = task_has_perm(current, p, PROCESS__GETATTR); |
@@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, | |||
4500 | if (!sid) | 4501 | if (!sid) |
4501 | return 0; | 4502 | return 0; |
4502 | 4503 | ||
4503 | return selinux_getsecurity(sid, value, size); | 4504 | error = security_sid_to_context(sid, value, &len); |
4505 | if (error) | ||
4506 | return error; | ||
4507 | return len; | ||
4504 | } | 4508 | } |
4505 | 4509 | ||
4506 | static int selinux_setprocattr(struct task_struct *p, | 4510 | static int selinux_setprocattr(struct task_struct *p, |