aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2008-05-19 08:32:49 -0400
committerJames Morris <jmorris@namei.org>2008-07-14 01:01:47 -0400
commit006ebb40d3d65338bd74abb03b945f8d60e362bd (patch)
treec548c678b54b307e1fb9acf94676fb7bfd849501 /include
parentfeb2a5b82d87fbdc01c00b7e9413e4b5f4c1f0c1 (diff)
Security: split proc ptrace checking into read vs. attach
Enable security modules to distinguish reading of process state via proc from full ptrace access by renaming ptrace_may_attach to ptrace_may_access and adding a mode argument indicating whether only read access or full attach access is requested. This allows security modules to permit access to reading process state without granting full ptrace access. The base DAC/capability checking remains unchanged. Read access to /proc/pid/mem continues to apply a full ptrace attach check since check_mem_permission() already requires the current task to already be ptracing the target. The other ptrace checks within proc for elements like environ, maps, and fds are changed to pass the read mode instead of attach. In the SELinux case, we model such reading of process state as a reading of a proc file labeled with the target process' label. This enables SELinux policy to permit such reading of process state without permitting control or manipulation of the target process, as there are a number of cases where programs probe for such information via proc but do not need to be able to control the target (e.g. procps, lsof, PolicyKit, ConsoleKit). At present we have to choose between allowing full ptrace in policy (more permissive than required/desired) or breaking functionality (or in some cases just silencing the denials via dontaudit rules but this can hide genuine attacks). This version of the patch incorporates comments from Casey Schaufler (change/replace existing ptrace_may_attach interface, pass access mode), and Chris Wright (provide greater consistency in the checking). Note that like their predecessors __ptrace_may_attach and ptrace_may_attach, the __ptrace_may_access and ptrace_may_access interfaces use different return value conventions from each other (0 or -errno vs. 1 or 0). I retained this difference to avoid any changes to the caller logic but made the difference clearer by changing the latter interface to return a bool rather than an int and by adding a comment about it to ptrace.h for any future callers. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/ptrace.h8
-rw-r--r--include/linux/security.h16
2 files changed, 17 insertions, 7 deletions
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index f98501ba557e..c6f5f9dd0cee 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -95,8 +95,12 @@ extern void __ptrace_link(struct task_struct *child,
95 struct task_struct *new_parent); 95 struct task_struct *new_parent);
96extern void __ptrace_unlink(struct task_struct *child); 96extern void __ptrace_unlink(struct task_struct *child);
97extern void ptrace_untrace(struct task_struct *child); 97extern void ptrace_untrace(struct task_struct *child);
98extern int ptrace_may_attach(struct task_struct *task); 98#define PTRACE_MODE_READ 1
99extern int __ptrace_may_attach(struct task_struct *task); 99#define PTRACE_MODE_ATTACH 2
100/* Returns 0 on success, -errno on denial. */
101extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
102/* Returns true on success, false on denial. */
103extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
100 104
101static inline int ptrace_reparented(struct task_struct *child) 105static inline int ptrace_reparented(struct task_struct *child)
102{ 106{
diff --git a/include/linux/security.h b/include/linux/security.h
index 50737c70e78e..62bd80cb7f87 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -46,7 +46,8 @@ struct audit_krule;
46 */ 46 */
47extern int cap_capable(struct task_struct *tsk, int cap); 47extern int cap_capable(struct task_struct *tsk, int cap);
48extern int cap_settime(struct timespec *ts, struct timezone *tz); 48extern int cap_settime(struct timespec *ts, struct timezone *tz);
49extern int cap_ptrace(struct task_struct *parent, struct task_struct *child); 49extern int cap_ptrace(struct task_struct *parent, struct task_struct *child,
50 unsigned int mode);
50extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); 51extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
51extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); 52extern int cap_capset_check(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
52extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); 53extern void cap_capset_set(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted);
@@ -1170,6 +1171,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1170 * attributes would be changed by the execve. 1171 * attributes would be changed by the execve.
1171 * @parent contains the task_struct structure for parent process. 1172 * @parent contains the task_struct structure for parent process.
1172 * @child contains the task_struct structure for child process. 1173 * @child contains the task_struct structure for child process.
1174 * @mode contains the PTRACE_MODE flags indicating the form of access.
1173 * Return 0 if permission is granted. 1175 * Return 0 if permission is granted.
1174 * @capget: 1176 * @capget:
1175 * Get the @effective, @inheritable, and @permitted capability sets for 1177 * Get the @effective, @inheritable, and @permitted capability sets for
@@ -1295,7 +1297,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1295struct security_operations { 1297struct security_operations {
1296 char name[SECURITY_NAME_MAX + 1]; 1298 char name[SECURITY_NAME_MAX + 1];
1297 1299
1298 int (*ptrace) (struct task_struct *parent, struct task_struct *child); 1300 int (*ptrace) (struct task_struct *parent, struct task_struct *child,
1301 unsigned int mode);
1299 int (*capget) (struct task_struct *target, 1302 int (*capget) (struct task_struct *target,
1300 kernel_cap_t *effective, 1303 kernel_cap_t *effective,
1301 kernel_cap_t *inheritable, kernel_cap_t *permitted); 1304 kernel_cap_t *inheritable, kernel_cap_t *permitted);
@@ -1573,7 +1576,8 @@ extern struct dentry *securityfs_create_dir(const char *name, struct dentry *par
1573extern void securityfs_remove(struct dentry *dentry); 1576extern void securityfs_remove(struct dentry *dentry);
1574 1577
1575/* Security operations */ 1578/* Security operations */
1576int security_ptrace(struct task_struct *parent, struct task_struct *child); 1579int security_ptrace(struct task_struct *parent, struct task_struct *child,
1580 unsigned int mode);
1577int security_capget(struct task_struct *target, 1581int security_capget(struct task_struct *target,
1578 kernel_cap_t *effective, 1582 kernel_cap_t *effective,
1579 kernel_cap_t *inheritable, 1583 kernel_cap_t *inheritable,
@@ -1755,9 +1759,11 @@ static inline int security_init(void)
1755 return 0; 1759 return 0;
1756} 1760}
1757 1761
1758static inline int security_ptrace(struct task_struct *parent, struct task_struct *child) 1762static inline int security_ptrace(struct task_struct *parent,
1763 struct task_struct *child,
1764 unsigned int mode)
1759{ 1765{
1760 return cap_ptrace(parent, child); 1766 return cap_ptrace(parent, child, mode);
1761} 1767}
1762 1768
1763static inline int security_capget(struct task_struct *target, 1769static inline int security_capget(struct task_struct *target,