* audit-ptrace patch (untested) @ 2007-03-05 14:50 Alexander Viro 2007-03-06 14:46 ` Stephen Smalley 0 siblings, 1 reply; 13+ messages in thread From: Alexander Viro @ 2007-03-05 14:50 UTC (permalink / raw) To: linux-audit That one is on top of security_getprocattr() patch. See bz#228384... diff --git a/include/linux/audit.h b/include/linux/audit.h index 229fa01..cce8b6c 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -90,6 +90,7 @@ #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ +#define AUDIT_OBJ_PID 1318 /* ptrace target */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ @@ -351,6 +352,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); extern void __audit_inode_child(const char *dname, const struct inode *inode, const struct inode *parent); extern void __audit_inode_update(const struct inode *inode); +extern void __audit_ptrace(struct task_struct *t); + static inline int audit_dummy_context(void) { void *p = current->audit_context; @@ -376,6 +379,12 @@ static inline void audit_inode_update(const struct inode *inode) { __audit_inode_update(inode); } +static inline void audit_ptrace(struct task_struct *t) +{ + if (unlikely(!audit_dummy_context())) + __audit_ptrace(t); +} + /* Private API (for audit.c only) */ extern unsigned int audit_serial(void); extern void auditsc_get_stamp(struct audit_context *ctx, @@ -476,6 +485,7 @@ extern int audit_n_rules; #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) #define audit_mq_notify(d,n) ({ 0; }) #define audit_mq_getsetattr(d,s) ({ 0; }) +#define audit_ptrace(t) ((void)0) #define audit_n_rules 0 #endif diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 89875b2..c8465ea 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -209,6 +209,9 @@ struct audit_context { unsigned long personality; int arch; + pid_t target_pid; + char * obj_ctx; + #if AUDIT_DEBUG int put_count; int ino_count; @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) audit_free_names(context); audit_free_aux(context); kfree(context->filterkey); + kfree(context->obj_ctx); kfree(context); context = previous; } while (context); @@ -967,6 +971,13 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts audit_log_end(ab); } + if (context->obj_ctx) { + ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); + audit_log_format(ab, "opid=%d obj=%s", + context->target_pid, context->obj_ctx); + audit_log_end(ab); + } + if (context->pwd && context->pwdmnt) { ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); if (ab) { @@ -1187,6 +1198,8 @@ void audit_syscall_exit(int valid, long return_code) } else { audit_free_names(context); audit_free_aux(context); + kfree(context->obj_ctx); + context->obj_ctx = NULL; kfree(context->filterkey); context->filterkey = NULL; tsk->audit_context = context; @@ -1874,6 +1887,13 @@ int audit_sockaddr(int len, void *a) return 0; } +void __audit_ptrace(struct task_struct *t) +{ + struct audit_context *context = current->audit_context; + context->target_pid = t->pid; + security_getprocattr(t, "current", &context->obj_ctx); +} + /** * audit_avc_path - record the granting or denial of permissions * @dentry: dentry to record diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4d50e06..ad7949a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -18,6 +18,7 @@ #include <linux/ptrace.h> #include <linux/security.h> #include <linux/signal.h> +#include <linux/audit.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) { int retval; + audit_ptrace(task); + retval = -EPERM; if (task->pid <= 1) goto out; ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-05 14:50 audit-ptrace patch (untested) Alexander Viro @ 2007-03-06 14:46 ` Stephen Smalley 2007-03-07 3:13 ` Alexander Viro 0 siblings, 1 reply; 13+ messages in thread From: Stephen Smalley @ 2007-03-06 14:46 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit, James Morris On Mon, 2007-03-05 at 09:50 -0500, Alexander Viro wrote: > That one is on top of security_getprocattr() patch. See bz#228384... > <snip> > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index 89875b2..c8465ea 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c <snip> > @@ -1874,6 +1887,13 @@ int audit_sockaddr(int len, void *a) > return 0; > } > > +void __audit_ptrace(struct task_struct *t) > +{ > + struct audit_context *context = current->audit_context; > + context->target_pid = t->pid; > + security_getprocattr(t, "current", &context->obj_ctx); > +} This will trigger a permission check in selinux_getprocattr, because current != t. So the audit system could be prevented from fetching the context in this way based on the current task's permissions. As with the prior patch, I'd suggest using security_task_getsecid() and security_secid_to_secctx() [or their selinux-specific equivalents, selinux_get_task_sid and selinux_sid_to_string, already in use by audit] instead for such internal access to security contexts. -- Stephen Smalley National Security Agency ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-06 14:46 ` Stephen Smalley @ 2007-03-07 3:13 ` Alexander Viro 2007-03-07 12:52 ` Stephen Smalley 0 siblings, 1 reply; 13+ messages in thread From: Alexander Viro @ 2007-03-07 3:13 UTC (permalink / raw) To: Stephen Smalley; +Cc: Eric Paris, linux-audit, James Morris On Tue, Mar 06, 2007 at 09:46:14AM -0500, Stephen Smalley wrote: > On Mon, 2007-03-05 at 09:50 -0500, Alexander Viro wrote: > > That one is on top of security_getprocattr() patch. See bz#228384... > > > <snip> > > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > > index 89875b2..c8465ea 100644 > > --- a/kernel/auditsc.c > > +++ b/kernel/auditsc.c > <snip> > > @@ -1874,6 +1887,13 @@ int audit_sockaddr(int len, void *a) > > return 0; > > } > > > > +void __audit_ptrace(struct task_struct *t) > > +{ > > + struct audit_context *context = current->audit_context; > > + context->target_pid = t->pid; > > + security_getprocattr(t, "current", &context->obj_ctx); > > +} > > This will trigger a permission check in selinux_getprocattr, because > current != t. So the audit system could be prevented from fetching the > context in this way based on the current task's permissions. As with > the prior patch, I'd suggest using security_task_getsecid() and > security_secid_to_secctx() [or their selinux-specific equivalents, > selinux_get_task_sid and selinux_sid_to_string, already in use by audit] > instead for such internal access to security contexts. OK... Here's combined patch (with switch to security_task_getsecid(), etc.) diff --git a/fs/proc/base.c b/fs/proc/base.c index 4f5745a..6bbfe91 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, size_t count, loff_t *ppos) { struct inode * inode = file->f_path.dentry->d_inode; - unsigned long page; + char *p = NULL; ssize_t length; struct task_struct *task = get_proc_task(inode); - length = -ESRCH; if (!task) - goto out_no_task; - - if (count > PAGE_SIZE) - count = PAGE_SIZE; - length = -ENOMEM; - if (!(page = __get_free_page(GFP_KERNEL))) - goto out; + return -ESRCH; length = security_getprocattr(task, (char*)file->f_path.dentry->d_name.name, - (void*)page, count); - if (length >= 0) - length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); - free_page(page); -out: + &p); put_task_struct(task); -out_no_task: + if (length > 0) + length = simple_read_from_buffer(buf, count, ppos, p, length); + kfree(p); return length; } diff --git a/include/linux/audit.h b/include/linux/audit.h index 229fa01..31b0f40 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -90,6 +90,7 @@ #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ +#define AUDIT_OBJ_PID 1318 /* ptrace target */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ @@ -351,6 +352,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); extern void __audit_inode_child(const char *dname, const struct inode *inode, const struct inode *parent); extern void __audit_inode_update(const struct inode *inode); +extern void __audit_ptrace(struct task_struct *t); + static inline int audit_dummy_context(void) { void *p = current->audit_context; @@ -376,6 +379,12 @@ static inline void audit_inode_update(const struct inode *inode) { __audit_inode_update(inode); } +static inline void audit_ptrace(struct task_struct *t) +{ + if (unlikely(!audit_dummy_context())) + __audit_ptrace(t); +} + /* Private API (for audit.c only) */ extern unsigned int audit_serial(void); extern void auditsc_get_stamp(struct audit_context *ctx, @@ -476,6 +485,7 @@ extern int audit_n_rules; #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) #define audit_mq_notify(d,n) ({ 0; }) #define audit_mq_getsetattr(d,s) ({ 0; }) +#define audit_ptrace(t) ((void)0) #define audit_n_rules 0 #endif diff --git a/include/linux/security.h b/include/linux/security.h index 7f88d97..47e82c1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1324,7 +1324,7 @@ struct security_operations { void (*d_instantiate) (struct dentry *dentry, struct inode *inode); - int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); + int (*getprocattr)(struct task_struct *p, char *name, char **value); int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); void (*release_secctx)(char *secdata, u32 seclen); @@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * security_ops->d_instantiate (dentry, inode); } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { - return security_ops->getprocattr(p, name, value, size); + return security_ops->getprocattr(p, name, value); } 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, static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3599558..f8875cb 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -209,6 +209,9 @@ struct audit_context { unsigned long personality; int arch; + pid_t target_pid; + char * obj_ctx; + #if AUDIT_DEBUG int put_count; int ino_count; @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) audit_free_names(context); audit_free_aux(context); kfree(context->filterkey); + kfree(context->obj_ctx); kfree(context); context = previous; } while (context); @@ -739,28 +743,26 @@ static inline void audit_free_context(struct audit_context *context) void audit_log_task_context(struct audit_buffer *ab) { char *ctx = NULL; - ssize_t len = 0; + unsigned len; + int error; + u32 sid; - len = security_getprocattr(current, "current", NULL, 0); - if (len < 0) { - if (len != -EINVAL) + security_task_getsecid(current, &sid); + if (!sid) + return; + + error = security_secid_to_secctx(sid, &ctx, &len); + if (error) { + if (error != -EINVAL) goto error_path; return; } - ctx = kmalloc(len, GFP_KERNEL); - if (!ctx) - goto error_path; - - len = security_getprocattr(current, "current", ctx, len); - if (len < 0 ) - goto error_path; - audit_log_format(ab, " subj=%s", ctx); + kfree(ctx); return; error_path: - kfree(ctx); audit_panic("error in audit_log_task_context"); return; } @@ -975,6 +977,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts audit_log_end(ab); } + if (context->target_pid) { + char *s = context->obj_ctx ? context->obj_ctx : "(none)"; + ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); + if (ab) { + audit_log_format(ab, "opid=%d obj=%s", + context->target_pid, s); + audit_log_end(ab); + } + } + if (context->pwd && context->pwdmnt) { ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); if (ab) { @@ -1195,6 +1207,9 @@ void audit_syscall_exit(int valid, long return_code) } else { audit_free_names(context); audit_free_aux(context); + kfree(context->obj_ctx); + context->obj_ctx = NULL; + context->target_pid = 0; kfree(context->filterkey); context->filterkey = NULL; tsk->audit_context = context; @@ -1882,6 +1897,19 @@ int audit_sockaddr(int len, void *a) return 0; } +void __audit_ptrace(struct task_struct *t) +{ + struct audit_context *context = current->audit_context; + unsigned len; + u32 sid; + + context->target_pid = t->pid; + + security_task_getsecid(t, &sid); + if (sid) + security_secid_to_secctx(sid, &context->obj_ctx, &len); +} + /** * audit_avc_path - record the granting or denial of permissions * @dentry: dentry to record diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4d50e06..ad7949a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -18,6 +18,7 @@ #include <linux/ptrace.h> #include <linux/security.h> #include <linux/signal.h> +#include <linux/audit.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) { int retval; + audit_ptrace(task); + retval = -EPERM; if (task->pid <= 1) goto out; diff --git a/security/dummy.c b/security/dummy.c index 558795b..8ffd764 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) return; } -static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static int dummy_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b1ac22d..0b265a5 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) } static int selinux_getprocattr(struct task_struct *p, - char *name, void *value, size_t size) + char *name, char **value) { struct task_security_struct *tsec; u32 sid; int error; + unsigned len; if (current != p) { error = task_has_perm(current, p, PROCESS__GETATTR); @@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, if (!sid) return 0; - return selinux_getsecurity(sid, value, size); + error = security_sid_to_context(sid, value, &len); + if (error) + return error; + return len; } static int selinux_setprocattr(struct task_struct *p, ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-07 3:13 ` Alexander Viro @ 2007-03-07 12:52 ` Stephen Smalley 2007-03-07 16:22 ` James Morris 2007-03-12 12:20 ` Alexander Viro 0 siblings, 2 replies; 13+ messages in thread From: Stephen Smalley @ 2007-03-07 12:52 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit, James Morris On Tue, 2007-03-06 at 22:13 -0500, Alexander Viro wrote: > OK... Here's combined patch (with switch to security_task_getsecid(), etc.) > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index 3599558..f8875cb 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c > @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) > audit_free_names(context); > audit_free_aux(context); > kfree(context->filterkey); > + kfree(context->obj_ctx); Technically, this should be: security_release_secctx(context->obj_ctx, context->ctxlen); Although that does require keeping the length around, and the rest of the audit code is already assuming it is just a string (unlike the original user of these LSM hooks, the labeled IPSEC code). > @@ -739,28 +743,26 @@ static inline void audit_free_context(struct audit_context *context) > void audit_log_task_context(struct audit_buffer *ab) > { > char *ctx = NULL; > - ssize_t len = 0; > + unsigned len; > + int error; > + u32 sid; > > - len = security_getprocattr(current, "current", NULL, 0); > - if (len < 0) { > - if (len != -EINVAL) > + security_task_getsecid(current, &sid); > + if (!sid) > + return; > + > + error = security_secid_to_secctx(sid, &ctx, &len); > + if (error) { > + if (error != -EINVAL) > goto error_path; > return; > } > > - ctx = kmalloc(len, GFP_KERNEL); > - if (!ctx) > - goto error_path; > - > - len = security_getprocattr(current, "current", ctx, len); > - if (len < 0 ) > - goto error_path; > - > audit_log_format(ab, " subj=%s", ctx); > + kfree(ctx); As above, technically should be: security_release_secctx(ctx,len). > @@ -1195,6 +1207,9 @@ void audit_syscall_exit(int valid, long return_code) > } else { > audit_free_names(context); > audit_free_aux(context); > + kfree(context->obj_ctx); And again. Otherwise, looks fine. -- Stephen Smalley National Security Agency ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-07 12:52 ` Stephen Smalley @ 2007-03-07 16:22 ` James Morris 2007-03-12 12:20 ` Alexander Viro 1 sibling, 0 replies; 13+ messages in thread From: James Morris @ 2007-03-07 16:22 UTC (permalink / raw) To: Stephen Smalley; +Cc: Eric Paris, linux-audit On Wed, 7 Mar 2007, Stephen Smalley wrote: > > audit_free_aux(context); > > kfree(context->filterkey); > > + kfree(context->obj_ctx); > > Technically, this should be: > security_release_secctx(context->obj_ctx, context->ctxlen); > Although that does require keeping the length around, and the rest of > the audit code is already assuming it is just a string (unlike the > original user of these LSM hooks, the labeled IPSEC code). I think these needs to be fixed before merge, as the presence of existing mistakes doesn't justify adding new ones. - James -- James Morris <jmorris@namei.org> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-07 12:52 ` Stephen Smalley 2007-03-07 16:22 ` James Morris @ 2007-03-12 12:20 ` Alexander Viro 2007-03-12 13:07 ` Stephen Smalley ` (2 more replies) 1 sibling, 3 replies; 13+ messages in thread From: Alexander Viro @ 2007-03-12 12:20 UTC (permalink / raw) To: Stephen Smalley; +Cc: Eric Paris, linux-audit, James Morris OK, you've convinced me - I'm switching to selinux-specific ones in kernel/auditsc.c. Updated patch follows, should fix 228409 and 228384. diff --git a/fs/proc/base.c b/fs/proc/base.c index 4f5745a..6bbfe91 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, size_t count, loff_t *ppos) { struct inode * inode = file->f_path.dentry->d_inode; - unsigned long page; + char *p = NULL; ssize_t length; struct task_struct *task = get_proc_task(inode); - length = -ESRCH; if (!task) - goto out_no_task; - - if (count > PAGE_SIZE) - count = PAGE_SIZE; - length = -ENOMEM; - if (!(page = __get_free_page(GFP_KERNEL))) - goto out; + return -ESRCH; length = security_getprocattr(task, (char*)file->f_path.dentry->d_name.name, - (void*)page, count); - if (length >= 0) - length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); - free_page(page); -out: + &p); put_task_struct(task); -out_no_task: + if (length > 0) + length = simple_read_from_buffer(buf, count, ppos, p, length); + kfree(p); return length; } diff --git a/include/linux/audit.h b/include/linux/audit.h index 229fa01..31b0f40 100644 --- a/include/linux/audit.h +++ b/include/linux/audit.h @@ -90,6 +90,7 @@ #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ +#define AUDIT_OBJ_PID 1318 /* ptrace target */ #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ @@ -351,6 +352,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); extern void __audit_inode_child(const char *dname, const struct inode *inode, const struct inode *parent); extern void __audit_inode_update(const struct inode *inode); +extern void __audit_ptrace(struct task_struct *t); + static inline int audit_dummy_context(void) { void *p = current->audit_context; @@ -376,6 +379,12 @@ static inline void audit_inode_update(const struct inode *inode) { __audit_inode_update(inode); } +static inline void audit_ptrace(struct task_struct *t) +{ + if (unlikely(!audit_dummy_context())) + __audit_ptrace(t); +} + /* Private API (for audit.c only) */ extern unsigned int audit_serial(void); extern void auditsc_get_stamp(struct audit_context *ctx, @@ -476,6 +485,7 @@ extern int audit_n_rules; #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) #define audit_mq_notify(d,n) ({ 0; }) #define audit_mq_getsetattr(d,s) ({ 0; }) +#define audit_ptrace(t) ((void)0) #define audit_n_rules 0 #endif diff --git a/include/linux/security.h b/include/linux/security.h index 7f88d97..47e82c1 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1324,7 +1324,7 @@ struct security_operations { void (*d_instantiate) (struct dentry *dentry, struct inode *inode); - int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); + int (*getprocattr)(struct task_struct *p, char *name, char **value); int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); void (*release_secctx)(char *secdata, u32 seclen); @@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * security_ops->d_instantiate (dentry, inode); } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { - return security_ops->getprocattr(p, name, value, size); + return security_ops->getprocattr(p, name, value); } 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, static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) { } -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 3599558..f489fed 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c @@ -209,6 +209,9 @@ struct audit_context { unsigned long personality; int arch; + pid_t target_pid; + char * obj_ctx; + #if AUDIT_DEBUG int put_count; int ino_count; @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) audit_free_names(context); audit_free_aux(context); kfree(context->filterkey); + kfree(context->obj_ctx); kfree(context); context = previous; } while (context); @@ -739,28 +743,26 @@ static inline void audit_free_context(struct audit_context *context) void audit_log_task_context(struct audit_buffer *ab) { char *ctx = NULL; - ssize_t len = 0; + unsigned len; + int error; + u32 sid; - len = security_getprocattr(current, "current", NULL, 0); - if (len < 0) { - if (len != -EINVAL) + selinux_get_task_sid(current, &sid); + if (!sid) + return; + + error = selinux_sid_to_string(sid, &ctx, &len); + if (error) { + if (error != -EINVAL) goto error_path; return; } - ctx = kmalloc(len, GFP_KERNEL); - if (!ctx) - goto error_path; - - len = security_getprocattr(current, "current", ctx, len); - if (len < 0 ) - goto error_path; - audit_log_format(ab, " subj=%s", ctx); + kfree(ctx); return; error_path: - kfree(ctx); audit_panic("error in audit_log_task_context"); return; } @@ -975,6 +977,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts audit_log_end(ab); } + if (context->target_pid) { + char *s = context->obj_ctx ? context->obj_ctx : "(none)"; + ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); + if (ab) { + audit_log_format(ab, "opid=%d obj=%s", + context->target_pid, s); + audit_log_end(ab); + } + } + if (context->pwd && context->pwdmnt) { ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); if (ab) { @@ -1195,6 +1207,9 @@ void audit_syscall_exit(int valid, long return_code) } else { audit_free_names(context); audit_free_aux(context); + kfree(context->obj_ctx); + context->obj_ctx = NULL; + context->target_pid = 0; kfree(context->filterkey); context->filterkey = NULL; tsk->audit_context = context; @@ -1882,6 +1897,19 @@ int audit_sockaddr(int len, void *a) return 0; } +void __audit_ptrace(struct task_struct *t) +{ + struct audit_context *context = current->audit_context; + unsigned len; + u32 sid; + + context->target_pid = t->pid; + + selinux_get_task_sid(t, &sid); + if (sid) + selinux_sid_to_string(sid, &context->obj_ctx, &len); +} + /** * audit_avc_path - record the granting or denial of permissions * @dentry: dentry to record diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 4d50e06..ad7949a 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -18,6 +18,7 @@ #include <linux/ptrace.h> #include <linux/security.h> #include <linux/signal.h> +#include <linux/audit.h> #include <asm/pgtable.h> #include <asm/uaccess.h> @@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) { int retval; + audit_ptrace(task); + retval = -EPERM; if (task->pid <= 1) goto out; diff --git a/security/dummy.c b/security/dummy.c index 558795b..8ffd764 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) return; } -static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) +static int dummy_getprocattr(struct task_struct *p, char *name, char **value) { return -EINVAL; } diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b1ac22d..0b265a5 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) } static int selinux_getprocattr(struct task_struct *p, - char *name, void *value, size_t size) + char *name, char **value) { struct task_security_struct *tsec; u32 sid; int error; + unsigned len; if (current != p) { error = task_has_perm(current, p, PROCESS__GETATTR); @@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, if (!sid) return 0; - return selinux_getsecurity(sid, value, size); + error = security_sid_to_context(sid, value, &len); + if (error) + return error; + return len; } static int selinux_setprocattr(struct task_struct *p, ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-12 12:20 ` Alexander Viro @ 2007-03-12 13:07 ` Stephen Smalley 2007-03-12 14:16 ` James Morris 2007-03-13 19:00 ` Amy Griffis 2 siblings, 0 replies; 13+ messages in thread From: Stephen Smalley @ 2007-03-12 13:07 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit, James Morris On Mon, 2007-03-12 at 08:20 -0400, Alexander Viro wrote: > OK, you've convinced me - I'm switching to selinux-specific ones > in kernel/auditsc.c. Updated patch follows, should fix 228409 and > 228384. Acked-by: Stephen Smalley <sds@tycho.nsa.gov> > > diff --git a/fs/proc/base.c b/fs/proc/base.c > index 4f5745a..6bbfe91 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, > size_t count, loff_t *ppos) > { > struct inode * inode = file->f_path.dentry->d_inode; > - unsigned long page; > + char *p = NULL; > ssize_t length; > struct task_struct *task = get_proc_task(inode); > > - length = -ESRCH; > if (!task) > - goto out_no_task; > - > - if (count > PAGE_SIZE) > - count = PAGE_SIZE; > - length = -ENOMEM; > - if (!(page = __get_free_page(GFP_KERNEL))) > - goto out; > + return -ESRCH; > > length = security_getprocattr(task, > (char*)file->f_path.dentry->d_name.name, > - (void*)page, count); > - if (length >= 0) > - length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); > - free_page(page); > -out: > + &p); > put_task_struct(task); > -out_no_task: > + if (length > 0) > + length = simple_read_from_buffer(buf, count, ppos, p, length); > + kfree(p); > return length; > } > > diff --git a/include/linux/audit.h b/include/linux/audit.h > index 229fa01..31b0f40 100644 > --- a/include/linux/audit.h > +++ b/include/linux/audit.h > @@ -90,6 +90,7 @@ > #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ > #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ > #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ > +#define AUDIT_OBJ_PID 1318 /* ptrace target */ > > #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ > #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ > @@ -351,6 +352,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); > extern void __audit_inode_child(const char *dname, const struct inode *inode, > const struct inode *parent); > extern void __audit_inode_update(const struct inode *inode); > +extern void __audit_ptrace(struct task_struct *t); > + > static inline int audit_dummy_context(void) > { > void *p = current->audit_context; > @@ -376,6 +379,12 @@ static inline void audit_inode_update(const struct inode *inode) { > __audit_inode_update(inode); > } > > +static inline void audit_ptrace(struct task_struct *t) > +{ > + if (unlikely(!audit_dummy_context())) > + __audit_ptrace(t); > +} > + > /* Private API (for audit.c only) */ > extern unsigned int audit_serial(void); > extern void auditsc_get_stamp(struct audit_context *ctx, > @@ -476,6 +485,7 @@ extern int audit_n_rules; > #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) > #define audit_mq_notify(d,n) ({ 0; }) > #define audit_mq_getsetattr(d,s) ({ 0; }) > +#define audit_ptrace(t) ((void)0) > #define audit_n_rules 0 > #endif > > diff --git a/include/linux/security.h b/include/linux/security.h > index 7f88d97..47e82c1 100644 > --- a/include/linux/security.h > +++ b/include/linux/security.h > @@ -1324,7 +1324,7 @@ struct security_operations { > > void (*d_instantiate) (struct dentry *dentry, struct inode *inode); > > - int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); > + int (*getprocattr)(struct task_struct *p, char *name, char **value); > int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); > int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); > void (*release_secctx)(char *secdata, u32 seclen); > @@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * > security_ops->d_instantiate (dentry, inode); > } > > -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) > { > - return security_ops->getprocattr(p, name, value, size); > + return security_ops->getprocattr(p, name, value); > } > > 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, > static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) > { } > > -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) > { > return -EINVAL; > } > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index 3599558..f489fed 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c > @@ -209,6 +209,9 @@ struct audit_context { > unsigned long personality; > int arch; > > + pid_t target_pid; > + char * obj_ctx; > + > #if AUDIT_DEBUG > int put_count; > int ino_count; > @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) > audit_free_names(context); > audit_free_aux(context); > kfree(context->filterkey); > + kfree(context->obj_ctx); > kfree(context); > context = previous; > } while (context); > @@ -739,28 +743,26 @@ static inline void audit_free_context(struct audit_context *context) > void audit_log_task_context(struct audit_buffer *ab) > { > char *ctx = NULL; > - ssize_t len = 0; > + unsigned len; > + int error; > + u32 sid; > > - len = security_getprocattr(current, "current", NULL, 0); > - if (len < 0) { > - if (len != -EINVAL) > + selinux_get_task_sid(current, &sid); > + if (!sid) > + return; > + > + error = selinux_sid_to_string(sid, &ctx, &len); > + if (error) { > + if (error != -EINVAL) > goto error_path; > return; > } > > - ctx = kmalloc(len, GFP_KERNEL); > - if (!ctx) > - goto error_path; > - > - len = security_getprocattr(current, "current", ctx, len); > - if (len < 0 ) > - goto error_path; > - > audit_log_format(ab, " subj=%s", ctx); > + kfree(ctx); > return; > > error_path: > - kfree(ctx); > audit_panic("error in audit_log_task_context"); > return; > } > @@ -975,6 +977,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts > audit_log_end(ab); > } > > + if (context->target_pid) { > + char *s = context->obj_ctx ? context->obj_ctx : "(none)"; > + ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); > + if (ab) { > + audit_log_format(ab, "opid=%d obj=%s", > + context->target_pid, s); > + audit_log_end(ab); > + } > + } > + > if (context->pwd && context->pwdmnt) { > ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); > if (ab) { > @@ -1195,6 +1207,9 @@ void audit_syscall_exit(int valid, long return_code) > } else { > audit_free_names(context); > audit_free_aux(context); > + kfree(context->obj_ctx); > + context->obj_ctx = NULL; > + context->target_pid = 0; > kfree(context->filterkey); > context->filterkey = NULL; > tsk->audit_context = context; > @@ -1882,6 +1897,19 @@ int audit_sockaddr(int len, void *a) > return 0; > } > > +void __audit_ptrace(struct task_struct *t) > +{ > + struct audit_context *context = current->audit_context; > + unsigned len; > + u32 sid; > + > + context->target_pid = t->pid; > + > + selinux_get_task_sid(t, &sid); > + if (sid) > + selinux_sid_to_string(sid, &context->obj_ctx, &len); > +} > + > /** > * audit_avc_path - record the granting or denial of permissions > * @dentry: dentry to record > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 4d50e06..ad7949a 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -18,6 +18,7 @@ > #include <linux/ptrace.h> > #include <linux/security.h> > #include <linux/signal.h> > +#include <linux/audit.h> > > #include <asm/pgtable.h> > #include <asm/uaccess.h> > @@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) > { > int retval; > > + audit_ptrace(task); > + > retval = -EPERM; > if (task->pid <= 1) > goto out; > diff --git a/security/dummy.c b/security/dummy.c > index 558795b..8ffd764 100644 > --- a/security/dummy.c > +++ b/security/dummy.c > @@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) > return; > } > > -static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static int dummy_getprocattr(struct task_struct *p, char *name, char **value) > { > return -EINVAL; > } > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index b1ac22d..0b265a5 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) > } > > static int selinux_getprocattr(struct task_struct *p, > - char *name, void *value, size_t size) > + char *name, char **value) > { > struct task_security_struct *tsec; > u32 sid; > int error; > + unsigned len; > > if (current != p) { > error = task_has_perm(current, p, PROCESS__GETATTR); > @@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, > if (!sid) > return 0; > > - return selinux_getsecurity(sid, value, size); > + error = security_sid_to_context(sid, value, &len); > + if (error) > + return error; > + return len; > } > > static int selinux_setprocattr(struct task_struct *p, -- Stephen Smalley National Security Agency ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-12 12:20 ` Alexander Viro 2007-03-12 13:07 ` Stephen Smalley @ 2007-03-12 14:16 ` James Morris 2007-03-12 16:19 ` Alexander Viro 2007-03-13 19:00 ` Amy Griffis 2 siblings, 1 reply; 13+ messages in thread From: James Morris @ 2007-03-12 14:16 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit On Mon, 12 Mar 2007, Alexander Viro wrote: > OK, you've convinced me - I'm switching to selinux-specific ones > in kernel/auditsc.c. Updated patch follows, should fix 228409 and > 228384. Al, I think this needs to go into Linus' tree and -stable to fix the crash. Do you want to forward it to Linus ? (I could, but it's a large patch for a bugfix and he'd probably be happier seeing it from you at this point in the development cycle). Acked-by: James Morris <jmorris@namei.org> > > diff --git a/fs/proc/base.c b/fs/proc/base.c > index 4f5745a..6bbfe91 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, > size_t count, loff_t *ppos) > { > struct inode * inode = file->f_path.dentry->d_inode; > - unsigned long page; > + char *p = NULL; > ssize_t length; > struct task_struct *task = get_proc_task(inode); > > - length = -ESRCH; > if (!task) > - goto out_no_task; > - > - if (count > PAGE_SIZE) > - count = PAGE_SIZE; > - length = -ENOMEM; > - if (!(page = __get_free_page(GFP_KERNEL))) > - goto out; > + return -ESRCH; > > length = security_getprocattr(task, > (char*)file->f_path.dentry->d_name.name, > - (void*)page, count); > - if (length >= 0) > - length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); > - free_page(page); > -out: > + &p); > put_task_struct(task); > -out_no_task: > + if (length > 0) > + length = simple_read_from_buffer(buf, count, ppos, p, length); > + kfree(p); > return length; > } > > diff --git a/include/linux/audit.h b/include/linux/audit.h > index 229fa01..31b0f40 100644 > --- a/include/linux/audit.h > +++ b/include/linux/audit.h > @@ -90,6 +90,7 @@ > #define AUDIT_MQ_GETSETATTR 1315 /* POSIX MQ get/set attribute record type */ > #define AUDIT_KERNEL_OTHER 1316 /* For use by 3rd party modules */ > #define AUDIT_FD_PAIR 1317 /* audit record for pipe/socketpair */ > +#define AUDIT_OBJ_PID 1318 /* ptrace target */ > > #define AUDIT_AVC 1400 /* SE Linux avc denial or grant */ > #define AUDIT_SELINUX_ERR 1401 /* Internal SE Linux Errors */ > @@ -351,6 +352,8 @@ extern void __audit_inode(const char *name, const struct inode *inode); > extern void __audit_inode_child(const char *dname, const struct inode *inode, > const struct inode *parent); > extern void __audit_inode_update(const struct inode *inode); > +extern void __audit_ptrace(struct task_struct *t); > + > static inline int audit_dummy_context(void) > { > void *p = current->audit_context; > @@ -376,6 +379,12 @@ static inline void audit_inode_update(const struct inode *inode) { > __audit_inode_update(inode); > } > > +static inline void audit_ptrace(struct task_struct *t) > +{ > + if (unlikely(!audit_dummy_context())) > + __audit_ptrace(t); > +} > + > /* Private API (for audit.c only) */ > extern unsigned int audit_serial(void); > extern void auditsc_get_stamp(struct audit_context *ctx, > @@ -476,6 +485,7 @@ extern int audit_n_rules; > #define audit_mq_timedreceive(d,l,p,t) ({ 0; }) > #define audit_mq_notify(d,n) ({ 0; }) > #define audit_mq_getsetattr(d,s) ({ 0; }) > +#define audit_ptrace(t) ((void)0) > #define audit_n_rules 0 > #endif > > diff --git a/include/linux/security.h b/include/linux/security.h > index 7f88d97..47e82c1 100644 > --- a/include/linux/security.h > +++ b/include/linux/security.h > @@ -1324,7 +1324,7 @@ struct security_operations { > > void (*d_instantiate) (struct dentry *dentry, struct inode *inode); > > - int (*getprocattr)(struct task_struct *p, char *name, void *value, size_t size); > + int (*getprocattr)(struct task_struct *p, char *name, char **value); > int (*setprocattr)(struct task_struct *p, char *name, void *value, size_t size); > int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen); > void (*release_secctx)(char *secdata, u32 seclen); > @@ -2092,9 +2092,9 @@ static inline void security_d_instantiate (struct dentry *dentry, struct inode * > security_ops->d_instantiate (dentry, inode); > } > > -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) > { > - return security_ops->getprocattr(p, name, value, size); > + return security_ops->getprocattr(p, name, value); > } > > 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, > static inline void security_d_instantiate (struct dentry *dentry, struct inode *inode) > { } > > -static inline int security_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static inline int security_getprocattr(struct task_struct *p, char *name, char **value) > { > return -EINVAL; > } > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index 3599558..f489fed 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c > @@ -209,6 +209,9 @@ struct audit_context { > unsigned long personality; > int arch; > > + pid_t target_pid; > + char * obj_ctx; > + > #if AUDIT_DEBUG > int put_count; > int ino_count; > @@ -729,6 +732,7 @@ static inline void audit_free_context(struct audit_context *context) > audit_free_names(context); > audit_free_aux(context); > kfree(context->filterkey); > + kfree(context->obj_ctx); > kfree(context); > context = previous; > } while (context); > @@ -739,28 +743,26 @@ static inline void audit_free_context(struct audit_context *context) > void audit_log_task_context(struct audit_buffer *ab) > { > char *ctx = NULL; > - ssize_t len = 0; > + unsigned len; > + int error; > + u32 sid; > > - len = security_getprocattr(current, "current", NULL, 0); > - if (len < 0) { > - if (len != -EINVAL) > + selinux_get_task_sid(current, &sid); > + if (!sid) > + return; > + > + error = selinux_sid_to_string(sid, &ctx, &len); > + if (error) { > + if (error != -EINVAL) > goto error_path; > return; > } > > - ctx = kmalloc(len, GFP_KERNEL); > - if (!ctx) > - goto error_path; > - > - len = security_getprocattr(current, "current", ctx, len); > - if (len < 0 ) > - goto error_path; > - > audit_log_format(ab, " subj=%s", ctx); > + kfree(ctx); > return; > > error_path: > - kfree(ctx); > audit_panic("error in audit_log_task_context"); > return; > } > @@ -975,6 +977,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts > audit_log_end(ab); > } > > + if (context->target_pid) { > + char *s = context->obj_ctx ? context->obj_ctx : "(none)"; > + ab =audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); > + if (ab) { > + audit_log_format(ab, "opid=%d obj=%s", > + context->target_pid, s); > + audit_log_end(ab); > + } > + } > + > if (context->pwd && context->pwdmnt) { > ab = audit_log_start(context, GFP_KERNEL, AUDIT_CWD); > if (ab) { > @@ -1195,6 +1207,9 @@ void audit_syscall_exit(int valid, long return_code) > } else { > audit_free_names(context); > audit_free_aux(context); > + kfree(context->obj_ctx); > + context->obj_ctx = NULL; > + context->target_pid = 0; > kfree(context->filterkey); > context->filterkey = NULL; > tsk->audit_context = context; > @@ -1882,6 +1897,19 @@ int audit_sockaddr(int len, void *a) > return 0; > } > > +void __audit_ptrace(struct task_struct *t) > +{ > + struct audit_context *context = current->audit_context; > + unsigned len; > + u32 sid; > + > + context->target_pid = t->pid; > + > + selinux_get_task_sid(t, &sid); > + if (sid) > + selinux_sid_to_string(sid, &context->obj_ctx, &len); > +} > + > /** > * audit_avc_path - record the granting or denial of permissions > * @dentry: dentry to record > diff --git a/kernel/ptrace.c b/kernel/ptrace.c > index 4d50e06..ad7949a 100644 > --- a/kernel/ptrace.c > +++ b/kernel/ptrace.c > @@ -18,6 +18,7 @@ > #include <linux/ptrace.h> > #include <linux/security.h> > #include <linux/signal.h> > +#include <linux/audit.h> > > #include <asm/pgtable.h> > #include <asm/uaccess.h> > @@ -161,6 +162,8 @@ int ptrace_attach(struct task_struct *task) > { > int retval; > > + audit_ptrace(task); > + > retval = -EPERM; > if (task->pid <= 1) > goto out; > diff --git a/security/dummy.c b/security/dummy.c > index 558795b..8ffd764 100644 > --- a/security/dummy.c > +++ b/security/dummy.c > @@ -907,7 +907,7 @@ static void dummy_d_instantiate (struct dentry *dentry, struct inode *inode) > return; > } > > -static int dummy_getprocattr(struct task_struct *p, char *name, void *value, size_t size) > +static int dummy_getprocattr(struct task_struct *p, char *name, char **value) > { > return -EINVAL; > } > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index b1ac22d..0b265a5 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) > } > > static int selinux_getprocattr(struct task_struct *p, > - char *name, void *value, size_t size) > + char *name, char **value) > { > struct task_security_struct *tsec; > u32 sid; > int error; > + unsigned len; > > if (current != p) { > error = task_has_perm(current, p, PROCESS__GETATTR); > @@ -4500,7 +4501,10 @@ static int selinux_getprocattr(struct task_struct *p, > if (!sid) > return 0; > > - return selinux_getsecurity(sid, value, size); > + error = security_sid_to_context(sid, value, &len); > + if (error) > + return error; > + return len; > } > > static int selinux_setprocattr(struct task_struct *p, > -- James Morris <jmorris@namei.org> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-12 14:16 ` James Morris @ 2007-03-12 16:19 ` Alexander Viro 0 siblings, 0 replies; 13+ messages in thread From: Alexander Viro @ 2007-03-12 16:19 UTC (permalink / raw) To: James Morris; +Cc: Eric Paris, linux-audit On Mon, Mar 12, 2007 at 10:16:42AM -0400, James Morris wrote: > On Mon, 12 Mar 2007, Alexander Viro wrote: > > > OK, you've convinced me - I'm switching to selinux-specific ones > > in kernel/auditsc.c. Updated patch follows, should fix 228409 and > > 228384. > > Al, I think this needs to go into Linus' tree and -stable to fix the > crash. Do you want to forward it to Linus ? (I could, but it's a large > patch for a bugfix and he'd probably be happier seeing it from you at > this point in the development cycle). deadlock fix + security_getprocattr() sanitizing sent as two patches, auditing ptrace target held back for now ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-12 12:20 ` Alexander Viro 2007-03-12 13:07 ` Stephen Smalley 2007-03-12 14:16 ` James Morris @ 2007-03-13 19:00 ` Amy Griffis 2007-03-13 19:39 ` Alexander Viro 2007-03-14 3:06 ` Steve Grubb 2 siblings, 2 replies; 13+ messages in thread From: Amy Griffis @ 2007-03-13 19:00 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit, James Morris Alexander Viro wrote: [Mon Mar 12 2007, 08:20:55AM EDT] > diff --git a/kernel/auditsc.c b/kernel/auditsc.c > index 3599558..f489fed 100644 > --- a/kernel/auditsc.c > +++ b/kernel/auditsc.c <snip> > +void __audit_ptrace(struct task_struct *t) > +{ > + struct audit_context *context = current->audit_context; > + unsigned len; > + u32 sid; > + > + context->target_pid = t->pid; > + > + selinux_get_task_sid(t, &sid); > + if (sid) > + selinux_sid_to_string(sid, &context->obj_ctx, &len); > +} Why did you choose to do the sid to string conversion at collection time, rather than waiting for audit_log_exit? In other code like this we've been delaying the memory alloc until logging, in case we never need it. Amy ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-13 19:00 ` Amy Griffis @ 2007-03-13 19:39 ` Alexander Viro 2007-03-14 15:57 ` Amy Griffis 2007-03-14 3:06 ` Steve Grubb 1 sibling, 1 reply; 13+ messages in thread From: Alexander Viro @ 2007-03-13 19:39 UTC (permalink / raw) To: Alexander Viro, Stephen Smalley, Eric Paris, linux-audit, James Morris On Tue, Mar 13, 2007 at 03:00:46PM -0400, Amy Griffis wrote: > > + if (sid) > > + selinux_sid_to_string(sid, &context->obj_ctx, &len); > > +} > > Why did you choose to do the sid to string conversion at collection > time, rather than waiting for audit_log_exit? Narrower window for sid_to_context to change... ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-13 19:39 ` Alexander Viro @ 2007-03-14 15:57 ` Amy Griffis 0 siblings, 0 replies; 13+ messages in thread From: Amy Griffis @ 2007-03-14 15:57 UTC (permalink / raw) To: Alexander Viro; +Cc: Eric Paris, linux-audit, James Morris Alexander Viro wrote: [Tue Mar 13 2007, 03:39:09PM EDT] > On Tue, Mar 13, 2007 at 03:00:46PM -0400, Amy Griffis wrote: > > > + if (sid) > > > + selinux_sid_to_string(sid, &context->obj_ctx, &len); > > > +} > > > > Why did you choose to do the sid to string conversion at collection > > time, rather than waiting for audit_log_exit? > > Narrower window for sid_to_context to change... Okay, I hadn't thought of that. But is it really more of a problem for processes than for ipc or inodes? It's true that processes can change their context, but that would change the sid, and we've already collected that data. The sid-to-context-string mapping will only change on policy load. I see the argument for narrowing the window, but I'd like to see audit pick one way and stick to it. Amy ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: audit-ptrace patch (untested) 2007-03-13 19:00 ` Amy Griffis 2007-03-13 19:39 ` Alexander Viro @ 2007-03-14 3:06 ` Steve Grubb 1 sibling, 0 replies; 13+ messages in thread From: Steve Grubb @ 2007-03-14 3:06 UTC (permalink / raw) To: linux-audit; +Cc: James Morris, Eric Paris On Tuesday 13 March 2007 15:00:46 Amy Griffis wrote: > Why did you choose to do the sid to string conversion at collection > time, rather than waiting for audit_log_exit? In other code like this > we've been delaying the memory alloc until logging, in case we never > need it. Yeah I agree. We were waiting until the end to do the conversion in case we ultimately didn't need the string. -Steve ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2007-03-14 15:57 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2007-03-05 14:50 audit-ptrace patch (untested) Alexander Viro 2007-03-06 14:46 ` Stephen Smalley 2007-03-07 3:13 ` Alexander Viro 2007-03-07 12:52 ` Stephen Smalley 2007-03-07 16:22 ` James Morris 2007-03-12 12:20 ` Alexander Viro 2007-03-12 13:07 ` Stephen Smalley 2007-03-12 14:16 ` James Morris 2007-03-12 16:19 ` Alexander Viro 2007-03-13 19:00 ` Amy Griffis 2007-03-13 19:39 ` Alexander Viro 2007-03-14 15:57 ` Amy Griffis 2007-03-14 3:06 ` Steve Grubb
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox