aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2005-04-18 13:47:35 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-18 13:47:35 -0400
commit219f0817038cabc722968e914490adf6b686499e (patch)
tree13b64537abe906645ee22843e146e21958236219
parent865108d13801d39ec038bdc82b5bec5e1eaffa9d (diff)
[PATCH] SELinux: fix deadlock on dcache lock
This fixes a deadlock on the dcache lock detected during testing at IBM by moving the logging of the current executable information from the SELinux avc_audit function to audit_log_exit (via an audit_log_task_info helper) for processing upon syscall exit. For consistency, the patch also removes the logging of other task-related information from avc_audit, deferring handling to audit_log_exit instead. This allows simplification of the avc_audit code, allows the exe information to be obtained more reliably, always includes the comm information (useful for scripts), and avoids including bogus task information for checks performed from irq or softirq. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@redhat.com> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--kernel/auditsc.c28
-rw-r--r--security/selinux/avc.c34
2 files changed, 28 insertions, 34 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 8c454852d6a5..6f1931381bc9 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -610,6 +610,33 @@ static inline void audit_free_context(struct audit_context *context)
610 printk(KERN_ERR "audit: freed %d contexts\n", count); 610 printk(KERN_ERR "audit: freed %d contexts\n", count);
611} 611}
612 612
613static void audit_log_task_info(struct audit_buffer *ab)
614{
615 char name[sizeof(current->comm)];
616 struct mm_struct *mm = current->mm;
617 struct vm_area_struct *vma;
618
619 get_task_comm(name, current);
620 audit_log_format(ab, " comm=%s", name);
621
622 if (!mm)
623 return;
624
625 down_read(&mm->mmap_sem);
626 vma = mm->mmap;
627 while (vma) {
628 if ((vma->vm_flags & VM_EXECUTABLE) &&
629 vma->vm_file) {
630 audit_log_d_path(ab, "exe=",
631 vma->vm_file->f_dentry,
632 vma->vm_file->f_vfsmnt);
633 break;
634 }
635 vma = vma->vm_next;
636 }
637 up_read(&mm->mmap_sem);
638}
639
613static void audit_log_exit(struct audit_context *context) 640static void audit_log_exit(struct audit_context *context)
614{ 641{
615 int i; 642 int i;
@@ -639,6 +666,7 @@ static void audit_log_exit(struct audit_context *context)
639 context->gid, 666 context->gid,
640 context->euid, context->suid, context->fsuid, 667 context->euid, context->suid, context->fsuid,
641 context->egid, context->sgid, context->fsgid); 668 context->egid, context->sgid, context->fsgid);
669 audit_log_task_info(ab);
642 audit_log_end(ab); 670 audit_log_end(ab);
643 while (context->aux) { 671 while (context->aux) {
644 struct audit_aux_data *aux; 672 struct audit_aux_data *aux;
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index fe6285e5c68f..85a6f66a873f 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -532,7 +532,6 @@ void avc_audit(u32 ssid, u32 tsid,
532 u16 tclass, u32 requested, 532 u16 tclass, u32 requested,
533 struct av_decision *avd, int result, struct avc_audit_data *a) 533 struct av_decision *avd, int result, struct avc_audit_data *a)
534{ 534{
535 struct task_struct *tsk = current;
536 struct inode *inode = NULL; 535 struct inode *inode = NULL;
537 u32 denied, audited; 536 u32 denied, audited;
538 struct audit_buffer *ab; 537 struct audit_buffer *ab;
@@ -556,39 +555,6 @@ void avc_audit(u32 ssid, u32 tsid,
556 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); 555 audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted");
557 avc_dump_av(ab, tclass,audited); 556 avc_dump_av(ab, tclass,audited);
558 audit_log_format(ab, " for "); 557 audit_log_format(ab, " for ");
559 if (a && a->tsk)
560 tsk = a->tsk;
561 if (tsk && tsk->pid) {
562 struct mm_struct *mm;
563 struct vm_area_struct *vma;
564 audit_log_format(ab, " pid=%d", tsk->pid);
565 if (tsk == current)
566 mm = current->mm;
567 else
568 mm = get_task_mm(tsk);
569 if (mm) {
570 if (down_read_trylock(&mm->mmap_sem)) {
571 vma = mm->mmap;
572 while (vma) {
573 if ((vma->vm_flags & VM_EXECUTABLE) &&
574 vma->vm_file) {
575 audit_log_d_path(ab, "exe=",
576 vma->vm_file->f_dentry,
577 vma->vm_file->f_vfsmnt);
578 break;
579 }
580 vma = vma->vm_next;
581 }
582 up_read(&mm->mmap_sem);
583 } else {
584 audit_log_format(ab, " comm=%s", tsk->comm);
585 }
586 if (tsk != current)
587 mmput(mm);
588 } else {
589 audit_log_format(ab, " comm=%s", tsk->comm);
590 }
591 }
592 if (a) { 558 if (a) {
593 switch (a->type) { 559 switch (a->type) {
594 case AVC_AUDIT_DATA_IPC: 560 case AVC_AUDIT_DATA_IPC: