diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2007-03-20 13:58:35 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2007-05-11 05:38:25 -0400 |
commit | a5cb013da773a67ee48d1c19e96436c22a73a7eb (patch) | |
tree | 8832d105c4742674423bd50352b8a4805c44fecc | |
parent | 129a84de2347002f09721cda3155ccfd19fade40 (diff) |
[PATCH] auditing ptrace
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | include/linux/audit.h | 10 | ||||
-rw-r--r-- | kernel/auditsc.c | 29 | ||||
-rw-r--r-- | kernel/ptrace.c | 3 |
3 files changed, 42 insertions, 0 deletions
diff --git a/include/linux/audit.h b/include/linux/audit.h index 773e30df11ee..f93ce78cecbb 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h | |||
@@ -91,6 +91,7 @@ | |||
91 | #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ | 91 | #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ |
92 | #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ | 92 | #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ |
93 | #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ | 93 | #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ |
94 | #define AUDIT_OBJ_PID 1318 /* ptrace target */ | ||
94 | 95 | ||
95 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ | 96 | #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ |
96 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ | 97 | #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ |
@@ -352,6 +353,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); | |||
352 | extern void __audit_inode_child(const char *dname, const struct inode *inode, | 353 | extern void __audit_inode_child(const char *dname, const struct inode *inode, |
353 | const struct inode *parent); | 354 | const struct inode *parent); |
354 | extern void __audit_inode_update(const struct inode *inode); | 355 | extern void __audit_inode_update(const struct inode *inode); |
356 | extern void __audit_ptrace(struct task_struct *t); | ||
357 | |||
355 | static inline int audit_dummy_context(void) | 358 | static inline int audit_dummy_context(void) |
356 | { | 359 | { |
357 | void *p = current->audit_context; | 360 | void *p = current->audit_context; |
@@ -377,6 +380,12 @@ static inline void audit_inode_update(const struct inode *inode) { | |||
377 | __audit_inode_update(inode); | 380 | __audit_inode_update(inode); |
378 | } | 381 | } |
379 | 382 | ||
383 | static inline void audit_ptrace(struct task_struct *t) | ||
384 | { | ||
385 | if (unlikely(!audit_dummy_context())) | ||
386 | __audit_ptrace(t); | ||
387 | } | ||
388 | |||
380 | /* Private API (for audit.c only) */ | 389 | /* Private API (for audit.c only) */ |
381 | extern unsigned int audit_serial(void); | 390 | extern unsigned int audit_serial(void); |
382 | extern void auditsc_get_stamp(struct audit_context *ctx, | 391 | extern void auditsc_get_stamp(struct audit_context *ctx, |
@@ -477,6 +486,7 @@ extern int audit_n_rules; | |||
477 | #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) | 486 | #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) |
478 | #define audit_mq_notify(d,n) ({ 0; }) | 487 | #define audit_mq_notify(d,n) ({ 0; }) |
479 | #define audit_mq_getsetattr(d,s) ({ 0; }) | 488 | #define audit_mq_getsetattr(d,s) ({ 0; }) |
489 | #define audit_ptrace(t) ((void)0) | ||
480 | #define audit_n_rules 0 | 490 | #define audit_n_rules 0 |
481 | #endif | 491 | #endif |
482 | 492 | ||
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 628c7ac590a0..2243c559bc03 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -209,6 +209,9 @@ struct audit_context { | |||
209 | unsigned long personality; | 209 | unsigned long personality; |
210 | int arch; | 210 | int arch; |
211 | 211 | ||
212 | pid_t target_pid; | ||
213 | u32 target_sid; | ||
214 | |||
212 | #if AUDIT_DEBUG | 215 | #if AUDIT_DEBUG |
213 | int put_count; | 216 | int put_count; |
214 | int ino_count; | 217 | int ino_count; |
@@ -973,6 +976,23 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
973 | audit_log_end(ab); | 976 | audit_log_end(ab); |
974 | } | 977 | } |
975 | 978 | ||
979 | if (context->target_pid) { | ||
980 | ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); | ||
981 | if (ab) { | ||
982 | char *s = NULL, *t; | ||
983 | u32 len; | ||
984 | if (selinux_sid_to_string(context->target_sid, | ||
985 | &s, &len)) | ||
986 | t = "(none)"; | ||
987 | else | ||
988 | t = s; | ||
989 | audit_log_format(ab, "opid=%d obj=%s", | ||
990 | context->target_pid, t); | ||
991 | audit_log_end(ab); | ||
992 | kfree(s); | ||
993 | } | ||
994 | } | ||
995 | |||
976 | if (context->pwd && context->pwdmnt) { | 996 | if (context->pwd && context->pwdmnt) { |
977 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); | 997 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); |
978 | if (ab) { | 998 | if (ab) { |
@@ -1193,6 +1213,7 @@ void audit_syscall_exit(int valid, long return_code) | |||
1193 | } else { | 1213 | } else { |
1194 | audit_free_names(context); | 1214 | audit_free_names(context); |
1195 | audit_free_aux(context); | 1215 | audit_free_aux(context); |
1216 | context->target_pid = 0; | ||
1196 | kfree(context->filterkey); | 1217 | kfree(context->filterkey); |
1197 | context->filterkey = NULL; | 1218 | context->filterkey = NULL; |
1198 | tsk->audit_context = context; | 1219 | tsk->audit_context = context; |
@@ -1880,6 +1901,14 @@ int audit_sockaddr(int len, void *a) | |||
1880 | return 0; | 1901 | return 0; |
1881 | } | 1902 | } |
1882 | 1903 | ||
1904 | void __audit_ptrace(struct task_struct *t) | ||
1905 | { | ||
1906 | struct audit_context *context = current->audit_context; | ||
1907 | |||
1908 | context->target_pid = t->pid; | ||
1909 | selinux_get_task_sid(t, &context->target_sid); | ||
1910 | } | ||
1911 | |||
1883 | /** | 1912 | /** |
1884 | * audit_avc_path - record the granting or denial of permissions | 1913 | * audit_avc_path - record the granting or denial of permissions |
1885 | * @dentry: dentry to record | 1914 | * @dentry: dentry to record |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4d50e06fd745..ad7949a589dd 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/ptrace.h> | 18 | #include <linux/ptrace.h> |
19 | #include <linux/security.h> | 19 | #include <linux/security.h> |
20 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
21 | #include <linux/audit.h> | ||
21 | 22 | ||
22 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
23 | #include <asm/uaccess.h> | 24 | #include <asm/uaccess.h> |
@@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) | |||
161 | { | 162 | { |
162 | int retval; | 163 | int retval; |
163 | 164 | ||
165 | audit_ptrace(task); | ||
166 | |||
164 | retval = -EPERM; | 167 | retval = -EPERM; |
165 | if (task->pid <= 1) | 168 | if (task->pid <= 1) |
166 | goto out; | 169 | goto out; |