diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 259 |
1 files changed, 184 insertions, 75 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index 37b3ac94bc47..e75f84e1a1a0 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -34,7 +34,8 @@ | |||
34 | #include <asm/types.h> | 34 | #include <asm/types.h> |
35 | #include <linux/mm.h> | 35 | #include <linux/mm.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | 37 | #include <linux/mount.h> | |
38 | #include <linux/socket.h> | ||
38 | #include <linux/audit.h> | 39 | #include <linux/audit.h> |
39 | #include <linux/personality.h> | 40 | #include <linux/personality.h> |
40 | #include <linux/time.h> | 41 | #include <linux/time.h> |
@@ -112,6 +113,23 @@ struct audit_aux_data_ipcctl { | |||
112 | mode_t mode; | 113 | mode_t mode; |
113 | }; | 114 | }; |
114 | 115 | ||
116 | struct audit_aux_data_socketcall { | ||
117 | struct audit_aux_data d; | ||
118 | int nargs; | ||
119 | unsigned long args[0]; | ||
120 | }; | ||
121 | |||
122 | struct audit_aux_data_sockaddr { | ||
123 | struct audit_aux_data d; | ||
124 | int len; | ||
125 | char a[0]; | ||
126 | }; | ||
127 | |||
128 | struct audit_aux_data_path { | ||
129 | struct audit_aux_data d; | ||
130 | struct dentry *dentry; | ||
131 | struct vfsmount *mnt; | ||
132 | }; | ||
115 | 133 | ||
116 | /* The per-task audit context. */ | 134 | /* The per-task audit context. */ |
117 | struct audit_context { | 135 | struct audit_context { |
@@ -127,6 +145,8 @@ struct audit_context { | |||
127 | int auditable; /* 1 if record should be written */ | 145 | int auditable; /* 1 if record should be written */ |
128 | int name_count; | 146 | int name_count; |
129 | struct audit_names names[AUDIT_NAMES]; | 147 | struct audit_names names[AUDIT_NAMES]; |
148 | struct dentry * pwd; | ||
149 | struct vfsmount * pwdmnt; | ||
130 | struct audit_context *previous; /* For nested syscalls */ | 150 | struct audit_context *previous; /* For nested syscalls */ |
131 | struct audit_aux_data *aux; | 151 | struct audit_aux_data *aux; |
132 | 152 | ||
@@ -157,6 +177,8 @@ struct audit_entry { | |||
157 | struct audit_rule rule; | 177 | struct audit_rule rule; |
158 | }; | 178 | }; |
159 | 179 | ||
180 | extern int audit_pid; | ||
181 | |||
160 | /* Check to see if two rules are identical. It is called from | 182 | /* Check to see if two rules are identical. It is called from |
161 | * audit_del_rule during AUDIT_DEL. */ | 183 | * audit_del_rule during AUDIT_DEL. */ |
162 | static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b) | 184 | static int audit_compare_rule(struct audit_rule *a, struct audit_rule *b) |
@@ -226,7 +248,6 @@ static inline int audit_del_rule(struct audit_rule *rule, | |||
226 | return -EFAULT; /* No matching rule */ | 248 | return -EFAULT; /* No matching rule */ |
227 | } | 249 | } |
228 | 250 | ||
229 | #ifdef CONFIG_NET | ||
230 | /* Copy rule from user-space to kernel-space. Called during | 251 | /* Copy rule from user-space to kernel-space. Called during |
231 | * AUDIT_ADD. */ | 252 | * AUDIT_ADD. */ |
232 | static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) | 253 | static int audit_copy_rule(struct audit_rule *d, struct audit_rule *s) |
@@ -287,7 +308,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
287 | err = audit_add_rule(entry, &audit_entlist); | 308 | err = audit_add_rule(entry, &audit_entlist); |
288 | if (!err && (flags & AUDIT_AT_EXIT)) | 309 | if (!err && (flags & AUDIT_AT_EXIT)) |
289 | err = audit_add_rule(entry, &audit_extlist); | 310 | err = audit_add_rule(entry, &audit_extlist); |
290 | audit_log(NULL, "auid %u added an audit rule\n", loginuid); | 311 | audit_log(NULL, AUDIT_CONFIG_CHANGE, |
312 | "auid=%u added an audit rule\n", loginuid); | ||
291 | break; | 313 | break; |
292 | case AUDIT_DEL: | 314 | case AUDIT_DEL: |
293 | flags =((struct audit_rule *)data)->flags; | 315 | flags =((struct audit_rule *)data)->flags; |
@@ -297,7 +319,8 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
297 | err = audit_del_rule(data, &audit_entlist); | 319 | err = audit_del_rule(data, &audit_entlist); |
298 | if (!err && (flags & AUDIT_AT_EXIT)) | 320 | if (!err && (flags & AUDIT_AT_EXIT)) |
299 | err = audit_del_rule(data, &audit_extlist); | 321 | err = audit_del_rule(data, &audit_extlist); |
300 | audit_log(NULL, "auid %u removed an audit rule\n", loginuid); | 322 | audit_log(NULL, AUDIT_CONFIG_CHANGE, |
323 | "auid=%u removed an audit rule\n", loginuid); | ||
301 | break; | 324 | break; |
302 | default: | 325 | default: |
303 | return -EINVAL; | 326 | return -EINVAL; |
@@ -305,7 +328,6 @@ int audit_receive_filter(int type, int pid, int uid, int seq, void *data, | |||
305 | 328 | ||
306 | return err; | 329 | return err; |
307 | } | 330 | } |
308 | #endif | ||
309 | 331 | ||
310 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 | 332 | /* Compare a task_struct with an audit_rule. Return 1 on match, 0 |
311 | * otherwise. */ | 333 | * otherwise. */ |
@@ -444,7 +466,7 @@ static enum audit_state audit_filter_task(struct task_struct *tsk) | |||
444 | 466 | ||
445 | /* At syscall entry and exit time, this filter is called if the | 467 | /* At syscall entry and exit time, this filter is called if the |
446 | * audit_state is not low enough that auditing cannot take place, but is | 468 | * audit_state is not low enough that auditing cannot take place, but is |
447 | * also not high enough that we already know we have to write and audit | 469 | * also not high enough that we already know we have to write an audit |
448 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). | 470 | * record (i.e., the state is AUDIT_SETUP_CONTEXT or AUDIT_BUILD_CONTEXT). |
449 | */ | 471 | */ |
450 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, | 472 | static enum audit_state audit_filter_syscall(struct task_struct *tsk, |
@@ -532,6 +554,12 @@ static inline void audit_free_names(struct audit_context *context) | |||
532 | if (context->names[i].name) | 554 | if (context->names[i].name) |
533 | __putname(context->names[i].name); | 555 | __putname(context->names[i].name); |
534 | context->name_count = 0; | 556 | context->name_count = 0; |
557 | if (context->pwd) | ||
558 | dput(context->pwd); | ||
559 | if (context->pwdmnt) | ||
560 | mntput(context->pwdmnt); | ||
561 | context->pwd = NULL; | ||
562 | context->pwdmnt = NULL; | ||
535 | } | 563 | } |
536 | 564 | ||
537 | static inline void audit_free_aux(struct audit_context *context) | 565 | static inline void audit_free_aux(struct audit_context *context) |
@@ -539,6 +567,11 @@ static inline void audit_free_aux(struct audit_context *context) | |||
539 | struct audit_aux_data *aux; | 567 | struct audit_aux_data *aux; |
540 | 568 | ||
541 | while ((aux = context->aux)) { | 569 | while ((aux = context->aux)) { |
570 | if (aux->type == AUDIT_AVC_PATH) { | ||
571 | struct audit_aux_data_path *axi = (void *)aux; | ||
572 | dput(axi->dentry); | ||
573 | mntput(axi->mnt); | ||
574 | } | ||
542 | context->aux = aux->next; | 575 | context->aux = aux->next; |
543 | kfree(aux); | 576 | kfree(aux); |
544 | } | 577 | } |
@@ -625,7 +658,8 @@ static void audit_log_task_info(struct audit_buffer *ab) | |||
625 | struct vm_area_struct *vma; | 658 | struct vm_area_struct *vma; |
626 | 659 | ||
627 | get_task_comm(name, current); | 660 | get_task_comm(name, current); |
628 | audit_log_format(ab, " comm=%s", name); | 661 | audit_log_format(ab, " comm="); |
662 | audit_log_untrustedstring(ab, name); | ||
629 | 663 | ||
630 | if (!mm) | 664 | if (!mm) |
631 | return; | 665 | return; |
@@ -649,23 +683,24 @@ static void audit_log_exit(struct audit_context *context) | |||
649 | { | 683 | { |
650 | int i; | 684 | int i; |
651 | struct audit_buffer *ab; | 685 | struct audit_buffer *ab; |
686 | struct audit_aux_data *aux; | ||
652 | 687 | ||
653 | ab = audit_log_start(context); | 688 | ab = audit_log_start(context, AUDIT_SYSCALL); |
654 | if (!ab) | 689 | if (!ab) |
655 | return; /* audit_panic has been called */ | 690 | return; /* audit_panic has been called */ |
656 | audit_log_format(ab, "syscall=%d", context->major); | 691 | audit_log_format(ab, "arch=%x syscall=%d", |
692 | context->arch, context->major); | ||
657 | if (context->personality != PER_LINUX) | 693 | if (context->personality != PER_LINUX) |
658 | audit_log_format(ab, " per=%lx", context->personality); | 694 | audit_log_format(ab, " per=%lx", context->personality); |
659 | audit_log_format(ab, " arch=%x", context->arch); | ||
660 | if (context->return_valid) | 695 | if (context->return_valid) |
661 | audit_log_format(ab, " success=%s exit=%ld", | 696 | audit_log_format(ab, " success=%s exit=%ld", |
662 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", | 697 | (context->return_valid==AUDITSC_SUCCESS)?"yes":"no", |
663 | context->return_code); | 698 | context->return_code); |
664 | audit_log_format(ab, | 699 | audit_log_format(ab, |
665 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 700 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" |
666 | " pid=%d loginuid=%d uid=%d gid=%d" | 701 | " pid=%d auid=%u uid=%u gid=%u" |
667 | " euid=%d suid=%d fsuid=%d" | 702 | " euid=%u suid=%u fsuid=%u" |
668 | " egid=%d sgid=%d fsgid=%d", | 703 | " egid=%u sgid=%u fsgid=%u", |
669 | context->argv[0], | 704 | context->argv[0], |
670 | context->argv[1], | 705 | context->argv[1], |
671 | context->argv[2], | 706 | context->argv[2], |
@@ -679,33 +714,57 @@ static void audit_log_exit(struct audit_context *context) | |||
679 | context->egid, context->sgid, context->fsgid); | 714 | context->egid, context->sgid, context->fsgid); |
680 | audit_log_task_info(ab); | 715 | audit_log_task_info(ab); |
681 | audit_log_end(ab); | 716 | audit_log_end(ab); |
682 | while (context->aux) { | ||
683 | struct audit_aux_data *aux; | ||
684 | 717 | ||
685 | ab = audit_log_start(context); | 718 | for (aux = context->aux; aux; aux = aux->next) { |
719 | |||
720 | ab = audit_log_start(context, aux->type); | ||
686 | if (!ab) | 721 | if (!ab) |
687 | continue; /* audit_panic has been called */ | 722 | continue; /* audit_panic has been called */ |
688 | 723 | ||
689 | aux = context->aux; | ||
690 | context->aux = aux->next; | ||
691 | |||
692 | audit_log_format(ab, "auxitem=%d", aux->type); | ||
693 | switch (aux->type) { | 724 | switch (aux->type) { |
694 | case AUDIT_AUX_IPCPERM: { | 725 | case AUDIT_IPC: { |
695 | struct audit_aux_data_ipcctl *axi = (void *)aux; | 726 | struct audit_aux_data_ipcctl *axi = (void *)aux; |
696 | audit_log_format(ab, | 727 | audit_log_format(ab, |
697 | " qbytes=%lx uid=%d gid=%d mode=%x", | 728 | " qbytes=%lx iuid=%u igid=%u mode=%x", |
698 | axi->qbytes, axi->uid, axi->gid, axi->mode); | 729 | axi->qbytes, axi->uid, axi->gid, axi->mode); |
699 | } | 730 | break; } |
731 | |||
732 | case AUDIT_SOCKETCALL: { | ||
733 | int i; | ||
734 | struct audit_aux_data_socketcall *axs = (void *)aux; | ||
735 | audit_log_format(ab, "nargs=%d", axs->nargs); | ||
736 | for (i=0; i<axs->nargs; i++) | ||
737 | audit_log_format(ab, " a%d=%lx", i, axs->args[i]); | ||
738 | break; } | ||
739 | |||
740 | case AUDIT_SOCKADDR: { | ||
741 | struct audit_aux_data_sockaddr *axs = (void *)aux; | ||
742 | |||
743 | audit_log_format(ab, "saddr="); | ||
744 | audit_log_hex(ab, axs->a, axs->len); | ||
745 | break; } | ||
746 | |||
747 | case AUDIT_AVC_PATH: { | ||
748 | struct audit_aux_data_path *axi = (void *)aux; | ||
749 | audit_log_d_path(ab, "path=", axi->dentry, axi->mnt); | ||
750 | break; } | ||
751 | |||
700 | } | 752 | } |
701 | audit_log_end(ab); | 753 | audit_log_end(ab); |
702 | kfree(aux); | ||
703 | } | 754 | } |
704 | 755 | ||
756 | if (context->pwd && context->pwdmnt) { | ||
757 | ab = audit_log_start(context, AUDIT_CWD); | ||
758 | if (ab) { | ||
759 | audit_log_d_path(ab, "cwd=", context->pwd, context->pwdmnt); | ||
760 | audit_log_end(ab); | ||
761 | } | ||
762 | } | ||
705 | for (i = 0; i < context->name_count; i++) { | 763 | for (i = 0; i < context->name_count; i++) { |
706 | ab = audit_log_start(context); | 764 | ab = audit_log_start(context, AUDIT_PATH); |
707 | if (!ab) | 765 | if (!ab) |
708 | continue; /* audit_panic has been called */ | 766 | continue; /* audit_panic has been called */ |
767 | |||
709 | audit_log_format(ab, "item=%d", i); | 768 | audit_log_format(ab, "item=%d", i); |
710 | if (context->names[i].name) { | 769 | if (context->names[i].name) { |
711 | audit_log_format(ab, " name="); | 770 | audit_log_format(ab, " name="); |
@@ -713,7 +772,7 @@ static void audit_log_exit(struct audit_context *context) | |||
713 | } | 772 | } |
714 | if (context->names[i].ino != (unsigned long)-1) | 773 | if (context->names[i].ino != (unsigned long)-1) |
715 | audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" | 774 | audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#o" |
716 | " uid=%d gid=%d rdev=%02x:%02x", | 775 | " ouid=%u ogid=%u rdev=%02x:%02x", |
717 | context->names[i].ino, | 776 | context->names[i].ino, |
718 | MAJOR(context->names[i].dev), | 777 | MAJOR(context->names[i].dev), |
719 | MINOR(context->names[i].dev), | 778 | MINOR(context->names[i].dev), |
@@ -741,42 +800,12 @@ void audit_free(struct task_struct *tsk) | |||
741 | 800 | ||
742 | /* Check for system calls that do not go through the exit | 801 | /* Check for system calls that do not go through the exit |
743 | * function (e.g., exit_group), then free context block. */ | 802 | * function (e.g., exit_group), then free context block. */ |
744 | if (context->in_syscall && context->auditable) | 803 | if (context->in_syscall && context->auditable && context->pid != audit_pid) |
745 | audit_log_exit(context); | 804 | audit_log_exit(context); |
746 | 805 | ||
747 | audit_free_context(context); | 806 | audit_free_context(context); |
748 | } | 807 | } |
749 | 808 | ||
750 | /* Compute a serial number for the audit record. Audit records are | ||
751 | * written to user-space as soon as they are generated, so a complete | ||
752 | * audit record may be written in several pieces. The timestamp of the | ||
753 | * record and this serial number are used by the user-space daemon to | ||
754 | * determine which pieces belong to the same audit record. The | ||
755 | * (timestamp,serial) tuple is unique for each syscall and is live from | ||
756 | * syscall entry to syscall exit. | ||
757 | * | ||
758 | * Atomic values are only guaranteed to be 24-bit, so we count down. | ||
759 | * | ||
760 | * NOTE: Another possibility is to store the formatted records off the | ||
761 | * audit context (for those records that have a context), and emit them | ||
762 | * all at syscall exit. However, this could delay the reporting of | ||
763 | * significant errors until syscall exit (or never, if the system | ||
764 | * halts). */ | ||
765 | static inline unsigned int audit_serial(void) | ||
766 | { | ||
767 | static atomic_t serial = ATOMIC_INIT(0xffffff); | ||
768 | unsigned int a, b; | ||
769 | |||
770 | do { | ||
771 | a = atomic_read(&serial); | ||
772 | if (atomic_dec_and_test(&serial)) | ||
773 | atomic_set(&serial, 0xffffff); | ||
774 | b = atomic_read(&serial); | ||
775 | } while (b != a - 1); | ||
776 | |||
777 | return 0xffffff - b; | ||
778 | } | ||
779 | |||
780 | /* Fill in audit context at syscall entry. This only happens if the | 809 | /* Fill in audit context at syscall entry. This only happens if the |
781 | * audit context was created when the task was created and the state or | 810 | * audit context was created when the task was created and the state or |
782 | * filters demand the audit context be built. If the state from the | 811 | * filters demand the audit context be built. If the state from the |
@@ -876,7 +905,7 @@ void audit_syscall_exit(struct task_struct *tsk, int valid, long return_code) | |||
876 | if (likely(!context)) | 905 | if (likely(!context)) |
877 | return; | 906 | return; |
878 | 907 | ||
879 | if (context->in_syscall && context->auditable) | 908 | if (context->in_syscall && context->auditable && context->pid != audit_pid) |
880 | audit_log_exit(context); | 909 | audit_log_exit(context); |
881 | 910 | ||
882 | context->in_syscall = 0; | 911 | context->in_syscall = 0; |
@@ -916,6 +945,13 @@ void audit_getname(const char *name) | |||
916 | context->names[context->name_count].name = name; | 945 | context->names[context->name_count].name = name; |
917 | context->names[context->name_count].ino = (unsigned long)-1; | 946 | context->names[context->name_count].ino = (unsigned long)-1; |
918 | ++context->name_count; | 947 | ++context->name_count; |
948 | if (!context->pwd) { | ||
949 | read_lock(¤t->fs->lock); | ||
950 | context->pwd = dget(current->fs->pwd); | ||
951 | context->pwdmnt = mntget(current->fs->pwdmnt); | ||
952 | read_unlock(¤t->fs->lock); | ||
953 | } | ||
954 | |||
919 | } | 955 | } |
920 | 956 | ||
921 | /* Intercept a putname request. Called from | 957 | /* Intercept a putname request. Called from |
@@ -994,34 +1030,26 @@ void audit_inode(const char *name, const struct inode *inode) | |||
994 | context->names[idx].rdev = inode->i_rdev; | 1030 | context->names[idx].rdev = inode->i_rdev; |
995 | } | 1031 | } |
996 | 1032 | ||
997 | void audit_get_stamp(struct audit_context *ctx, | 1033 | void auditsc_get_stamp(struct audit_context *ctx, |
998 | struct timespec *t, unsigned int *serial) | 1034 | struct timespec *t, unsigned int *serial) |
999 | { | 1035 | { |
1000 | if (ctx) { | 1036 | t->tv_sec = ctx->ctime.tv_sec; |
1001 | t->tv_sec = ctx->ctime.tv_sec; | 1037 | t->tv_nsec = ctx->ctime.tv_nsec; |
1002 | t->tv_nsec = ctx->ctime.tv_nsec; | 1038 | *serial = ctx->serial; |
1003 | *serial = ctx->serial; | 1039 | ctx->auditable = 1; |
1004 | ctx->auditable = 1; | ||
1005 | } else { | ||
1006 | *t = CURRENT_TIME; | ||
1007 | *serial = 0; | ||
1008 | } | ||
1009 | } | 1040 | } |
1010 | 1041 | ||
1011 | extern int audit_set_type(struct audit_buffer *ab, int type); | ||
1012 | |||
1013 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 1042 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) |
1014 | { | 1043 | { |
1015 | if (task->audit_context) { | 1044 | if (task->audit_context) { |
1016 | struct audit_buffer *ab; | 1045 | struct audit_buffer *ab; |
1017 | 1046 | ||
1018 | ab = audit_log_start(NULL); | 1047 | ab = audit_log_start(NULL, AUDIT_LOGIN); |
1019 | if (ab) { | 1048 | if (ab) { |
1020 | audit_log_format(ab, "login pid=%d uid=%u " | 1049 | audit_log_format(ab, "login pid=%d uid=%u " |
1021 | "old loginuid=%u new loginuid=%u", | 1050 | "old auid=%u new auid=%u", |
1022 | task->pid, task->uid, | 1051 | task->pid, task->uid, |
1023 | task->audit_context->loginuid, loginuid); | 1052 | task->audit_context->loginuid, loginuid); |
1024 | audit_set_type(ab, AUDIT_LOGIN); | ||
1025 | audit_log_end(ab); | 1053 | audit_log_end(ab); |
1026 | } | 1054 | } |
1027 | task->audit_context->loginuid = loginuid; | 1055 | task->audit_context->loginuid = loginuid; |
@@ -1051,8 +1079,89 @@ int audit_ipc_perms(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode) | |||
1051 | ax->gid = gid; | 1079 | ax->gid = gid; |
1052 | ax->mode = mode; | 1080 | ax->mode = mode; |
1053 | 1081 | ||
1054 | ax->d.type = AUDIT_AUX_IPCPERM; | 1082 | ax->d.type = AUDIT_IPC; |
1083 | ax->d.next = context->aux; | ||
1084 | context->aux = (void *)ax; | ||
1085 | return 0; | ||
1086 | } | ||
1087 | |||
1088 | int audit_socketcall(int nargs, unsigned long *args) | ||
1089 | { | ||
1090 | struct audit_aux_data_socketcall *ax; | ||
1091 | struct audit_context *context = current->audit_context; | ||
1092 | |||
1093 | if (likely(!context)) | ||
1094 | return 0; | ||
1095 | |||
1096 | ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL); | ||
1097 | if (!ax) | ||
1098 | return -ENOMEM; | ||
1099 | |||
1100 | ax->nargs = nargs; | ||
1101 | memcpy(ax->args, args, nargs * sizeof(unsigned long)); | ||
1102 | |||
1103 | ax->d.type = AUDIT_SOCKETCALL; | ||
1104 | ax->d.next = context->aux; | ||
1105 | context->aux = (void *)ax; | ||
1106 | return 0; | ||
1107 | } | ||
1108 | |||
1109 | int audit_sockaddr(int len, void *a) | ||
1110 | { | ||
1111 | struct audit_aux_data_sockaddr *ax; | ||
1112 | struct audit_context *context = current->audit_context; | ||
1113 | |||
1114 | if (likely(!context)) | ||
1115 | return 0; | ||
1116 | |||
1117 | ax = kmalloc(sizeof(*ax) + len, GFP_KERNEL); | ||
1118 | if (!ax) | ||
1119 | return -ENOMEM; | ||
1120 | |||
1121 | ax->len = len; | ||
1122 | memcpy(ax->a, a, len); | ||
1123 | |||
1124 | ax->d.type = AUDIT_SOCKADDR; | ||
1055 | ax->d.next = context->aux; | 1125 | ax->d.next = context->aux; |
1056 | context->aux = (void *)ax; | 1126 | context->aux = (void *)ax; |
1057 | return 0; | 1127 | return 0; |
1058 | } | 1128 | } |
1129 | |||
1130 | int audit_avc_path(struct dentry *dentry, struct vfsmount *mnt) | ||
1131 | { | ||
1132 | struct audit_aux_data_path *ax; | ||
1133 | struct audit_context *context = current->audit_context; | ||
1134 | |||
1135 | if (likely(!context)) | ||
1136 | return 0; | ||
1137 | |||
1138 | ax = kmalloc(sizeof(*ax), GFP_ATOMIC); | ||
1139 | if (!ax) | ||
1140 | return -ENOMEM; | ||
1141 | |||
1142 | ax->dentry = dget(dentry); | ||
1143 | ax->mnt = mntget(mnt); | ||
1144 | |||
1145 | ax->d.type = AUDIT_AVC_PATH; | ||
1146 | ax->d.next = context->aux; | ||
1147 | context->aux = (void *)ax; | ||
1148 | return 0; | ||
1149 | } | ||
1150 | |||
1151 | void audit_signal_info(int sig, struct task_struct *t) | ||
1152 | { | ||
1153 | extern pid_t audit_sig_pid; | ||
1154 | extern uid_t audit_sig_uid; | ||
1155 | |||
1156 | if (unlikely(audit_pid && t->pid == audit_pid)) { | ||
1157 | if (sig == SIGTERM || sig == SIGHUP) { | ||
1158 | struct audit_context *ctx = current->audit_context; | ||
1159 | audit_sig_pid = current->pid; | ||
1160 | if (ctx) | ||
1161 | audit_sig_uid = ctx->loginuid; | ||
1162 | else | ||
1163 | audit_sig_uid = current->uid; | ||
1164 | } | ||
1165 | } | ||
1166 | } | ||
1167 | |||