diff options
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 349 |
1 files changed, 256 insertions, 93 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index bce9ecdb7712..1c06ecf38d7b 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include "audit.h" | 70 | #include "audit.h" |
71 | 71 | ||
72 | extern struct list_head audit_filter_list[]; | 72 | extern struct list_head audit_filter_list[]; |
73 | extern int audit_ever_enabled; | ||
73 | 74 | ||
74 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context | 75 | /* AUDIT_NAMES is the number of slots we reserve in the audit_context |
75 | * for saving names from getname(). */ | 76 | * for saving names from getname(). */ |
@@ -78,6 +79,9 @@ extern struct list_head audit_filter_list[]; | |||
78 | /* Indicates that audit should log the full pathname. */ | 79 | /* Indicates that audit should log the full pathname. */ |
79 | #define AUDIT_NAME_FULL -1 | 80 | #define AUDIT_NAME_FULL -1 |
80 | 81 | ||
82 | /* no execve audit message should be longer than this (userspace limits) */ | ||
83 | #define MAX_EXECVE_AUDIT_LEN 7500 | ||
84 | |||
81 | /* number of audit rules */ | 85 | /* number of audit rules */ |
82 | int audit_n_rules; | 86 | int audit_n_rules; |
83 | 87 | ||
@@ -176,7 +180,11 @@ struct audit_aux_data_fd_pair { | |||
176 | struct audit_aux_data_pids { | 180 | struct audit_aux_data_pids { |
177 | struct audit_aux_data d; | 181 | struct audit_aux_data d; |
178 | pid_t target_pid[AUDIT_AUX_PIDS]; | 182 | pid_t target_pid[AUDIT_AUX_PIDS]; |
183 | uid_t target_auid[AUDIT_AUX_PIDS]; | ||
184 | uid_t target_uid[AUDIT_AUX_PIDS]; | ||
185 | unsigned int target_sessionid[AUDIT_AUX_PIDS]; | ||
179 | u32 target_sid[AUDIT_AUX_PIDS]; | 186 | u32 target_sid[AUDIT_AUX_PIDS]; |
187 | char target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN]; | ||
180 | int pid_count; | 188 | int pid_count; |
181 | }; | 189 | }; |
182 | 190 | ||
@@ -192,7 +200,6 @@ struct audit_context { | |||
192 | enum audit_state state; | 200 | enum audit_state state; |
193 | unsigned int serial; /* serial number for record */ | 201 | unsigned int serial; /* serial number for record */ |
194 | struct timespec ctime; /* time of syscall entry */ | 202 | struct timespec ctime; /* time of syscall entry */ |
195 | uid_t loginuid; /* login uid (identity) */ | ||
196 | int major; /* syscall number */ | 203 | int major; /* syscall number */ |
197 | unsigned long argv[4]; /* syscall arguments */ | 204 | unsigned long argv[4]; /* syscall arguments */ |
198 | int return_valid; /* return code is valid */ | 205 | int return_valid; /* return code is valid */ |
@@ -215,7 +222,11 @@ struct audit_context { | |||
215 | int arch; | 222 | int arch; |
216 | 223 | ||
217 | pid_t target_pid; | 224 | pid_t target_pid; |
225 | uid_t target_auid; | ||
226 | uid_t target_uid; | ||
227 | unsigned int target_sessionid; | ||
218 | u32 target_sid; | 228 | u32 target_sid; |
229 | char target_comm[TASK_COMM_LEN]; | ||
219 | 230 | ||
220 | struct audit_tree_refs *trees, *first_trees; | 231 | struct audit_tree_refs *trees, *first_trees; |
221 | int tree_count; | 232 | int tree_count; |
@@ -506,7 +517,7 @@ static int audit_filter_rules(struct task_struct *tsk, | |||
506 | case AUDIT_LOGINUID: | 517 | case AUDIT_LOGINUID: |
507 | result = 0; | 518 | result = 0; |
508 | if (ctx) | 519 | if (ctx) |
509 | result = audit_comparator(ctx->loginuid, f->op, f->val); | 520 | result = audit_comparator(tsk->loginuid, f->op, f->val); |
510 | break; | 521 | break; |
511 | case AUDIT_SUBJ_USER: | 522 | case AUDIT_SUBJ_USER: |
512 | case AUDIT_SUBJ_ROLE: | 523 | case AUDIT_SUBJ_ROLE: |
@@ -702,7 +713,24 @@ static inline struct audit_context *audit_get_context(struct task_struct *tsk, | |||
702 | if (likely(!context)) | 713 | if (likely(!context)) |
703 | return NULL; | 714 | return NULL; |
704 | context->return_valid = return_valid; | 715 | context->return_valid = return_valid; |
705 | context->return_code = return_code; | 716 | |
717 | /* | ||
718 | * we need to fix up the return code in the audit logs if the actual | ||
719 | * return codes are later going to be fixed up by the arch specific | ||
720 | * signal handlers | ||
721 | * | ||
722 | * This is actually a test for: | ||
723 | * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) || | ||
724 | * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK) | ||
725 | * | ||
726 | * but is faster than a bunch of || | ||
727 | */ | ||
728 | if (unlikely(return_code <= -ERESTARTSYS) && | ||
729 | (return_code >= -ERESTART_RESTARTBLOCK) && | ||
730 | (return_code != -ENOIOCTLCMD)) | ||
731 | context->return_code = -EINTR; | ||
732 | else | ||
733 | context->return_code = return_code; | ||
706 | 734 | ||
707 | if (context->in_syscall && !context->dummy && !context->auditable) { | 735 | if (context->in_syscall && !context->dummy && !context->auditable) { |
708 | enum audit_state state; | 736 | enum audit_state state; |
@@ -783,11 +811,8 @@ static inline void audit_free_aux(struct audit_context *context) | |||
783 | static inline void audit_zero_context(struct audit_context *context, | 811 | static inline void audit_zero_context(struct audit_context *context, |
784 | enum audit_state state) | 812 | enum audit_state state) |
785 | { | 813 | { |
786 | uid_t loginuid = context->loginuid; | ||
787 | |||
788 | memset(context, 0, sizeof(*context)); | 814 | memset(context, 0, sizeof(*context)); |
789 | context->state = state; | 815 | context->state = state; |
790 | context->loginuid = loginuid; | ||
791 | } | 816 | } |
792 | 817 | ||
793 | static inline struct audit_context *audit_alloc_context(enum audit_state state) | 818 | static inline struct audit_context *audit_alloc_context(enum audit_state state) |
@@ -814,7 +839,7 @@ int audit_alloc(struct task_struct *tsk) | |||
814 | struct audit_context *context; | 839 | struct audit_context *context; |
815 | enum audit_state state; | 840 | enum audit_state state; |
816 | 841 | ||
817 | if (likely(!audit_enabled)) | 842 | if (likely(!audit_ever_enabled)) |
818 | return 0; /* Return if not auditing. */ | 843 | return 0; /* Return if not auditing. */ |
819 | 844 | ||
820 | state = audit_filter_task(tsk); | 845 | state = audit_filter_task(tsk); |
@@ -826,11 +851,6 @@ int audit_alloc(struct task_struct *tsk) | |||
826 | return -ENOMEM; | 851 | return -ENOMEM; |
827 | } | 852 | } |
828 | 853 | ||
829 | /* Preserve login uid */ | ||
830 | context->loginuid = -1; | ||
831 | if (current->audit_context) | ||
832 | context->loginuid = current->audit_context->loginuid; | ||
833 | |||
834 | tsk->audit_context = context; | 854 | tsk->audit_context = context; |
835 | set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); | 855 | set_tsk_thread_flag(tsk, TIF_SYSCALL_AUDIT); |
836 | return 0; | 856 | return 0; |
@@ -922,7 +942,8 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk | |||
922 | } | 942 | } |
923 | 943 | ||
924 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, | 944 | static int audit_log_pid_context(struct audit_context *context, pid_t pid, |
925 | u32 sid) | 945 | uid_t auid, uid_t uid, unsigned int sessionid, |
946 | u32 sid, char *comm) | ||
926 | { | 947 | { |
927 | struct audit_buffer *ab; | 948 | struct audit_buffer *ab; |
928 | char *s = NULL; | 949 | char *s = NULL; |
@@ -931,68 +952,204 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid, | |||
931 | 952 | ||
932 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); | 953 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_OBJ_PID); |
933 | if (!ab) | 954 | if (!ab) |
934 | return 1; | 955 | return rc; |
935 | 956 | ||
957 | audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid, | ||
958 | uid, sessionid); | ||
936 | if (selinux_sid_to_string(sid, &s, &len)) { | 959 | if (selinux_sid_to_string(sid, &s, &len)) { |
937 | audit_log_format(ab, "opid=%d obj=(none)", pid); | 960 | audit_log_format(ab, " obj=(none)"); |
938 | rc = 1; | 961 | rc = 1; |
939 | } else | 962 | } else |
940 | audit_log_format(ab, "opid=%d obj=%s", pid, s); | 963 | audit_log_format(ab, " obj=%s", s); |
964 | audit_log_format(ab, " ocomm="); | ||
965 | audit_log_untrustedstring(ab, comm); | ||
941 | audit_log_end(ab); | 966 | audit_log_end(ab); |
942 | kfree(s); | 967 | kfree(s); |
943 | 968 | ||
944 | return rc; | 969 | return rc; |
945 | } | 970 | } |
946 | 971 | ||
947 | static void audit_log_execve_info(struct audit_buffer *ab, | 972 | /* |
948 | struct audit_aux_data_execve *axi) | 973 | * to_send and len_sent accounting are very loose estimates. We aren't |
974 | * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being | ||
975 | * within about 500 bytes (next page boundry) | ||
976 | * | ||
977 | * why snprintf? an int is up to 12 digits long. if we just assumed when | ||
978 | * logging that a[%d]= was going to be 16 characters long we would be wasting | ||
979 | * space in every audit message. In one 7500 byte message we can log up to | ||
980 | * about 1000 min size arguments. That comes down to about 50% waste of space | ||
981 | * if we didn't do the snprintf to find out how long arg_num_len was. | ||
982 | */ | ||
983 | static int audit_log_single_execve_arg(struct audit_context *context, | ||
984 | struct audit_buffer **ab, | ||
985 | int arg_num, | ||
986 | size_t *len_sent, | ||
987 | const char __user *p, | ||
988 | char *buf) | ||
949 | { | 989 | { |
950 | int i; | 990 | char arg_num_len_buf[12]; |
951 | long len, ret; | 991 | const char __user *tmp_p = p; |
952 | const char __user *p; | 992 | /* how many digits are in arg_num? 3 is the length of a=\n */ |
953 | char *buf; | 993 | size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 3; |
994 | size_t len, len_left, to_send; | ||
995 | size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; | ||
996 | unsigned int i, has_cntl = 0, too_long = 0; | ||
997 | int ret; | ||
998 | |||
999 | /* strnlen_user includes the null we don't want to send */ | ||
1000 | len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1; | ||
954 | 1001 | ||
955 | if (axi->mm != current->mm) | 1002 | /* |
956 | return; /* execve failed, no additional info */ | 1003 | * We just created this mm, if we can't find the strings |
957 | 1004 | * we just copied into it something is _very_ wrong. Similar | |
958 | p = (const char __user *)axi->mm->arg_start; | 1005 | * for strings that are too long, we should not have created |
1006 | * any. | ||
1007 | */ | ||
1008 | if (unlikely((len = -1) || len > MAX_ARG_STRLEN - 1)) { | ||
1009 | WARN_ON(1); | ||
1010 | send_sig(SIGKILL, current, 0); | ||
1011 | } | ||
959 | 1012 | ||
960 | for (i = 0; i < axi->argc; i++, p += len) { | 1013 | /* walk the whole argument looking for non-ascii chars */ |
961 | len = strnlen_user(p, MAX_ARG_STRLEN); | 1014 | do { |
1015 | if (len_left > MAX_EXECVE_AUDIT_LEN) | ||
1016 | to_send = MAX_EXECVE_AUDIT_LEN; | ||
1017 | else | ||
1018 | to_send = len_left; | ||
1019 | ret = copy_from_user(buf, tmp_p, to_send); | ||
962 | /* | 1020 | /* |
963 | * We just created this mm, if we can't find the strings | 1021 | * There is no reason for this copy to be short. We just |
964 | * we just copied into it something is _very_ wrong. Similar | 1022 | * copied them here, and the mm hasn't been exposed to user- |
965 | * for strings that are too long, we should not have created | 1023 | * space yet. |
966 | * any. | ||
967 | */ | 1024 | */ |
968 | if (!len || len > MAX_ARG_STRLEN) { | 1025 | if (ret) { |
969 | WARN_ON(1); | 1026 | WARN_ON(1); |
970 | send_sig(SIGKILL, current, 0); | 1027 | send_sig(SIGKILL, current, 0); |
971 | } | 1028 | } |
972 | 1029 | buf[to_send] = '\0'; | |
973 | buf = kmalloc(len, GFP_KERNEL); | 1030 | has_cntl = audit_string_contains_control(buf, to_send); |
974 | if (!buf) { | 1031 | if (has_cntl) { |
975 | audit_panic("out of memory for argv string\n"); | 1032 | /* |
1033 | * hex messages get logged as 2 bytes, so we can only | ||
1034 | * send half as much in each message | ||
1035 | */ | ||
1036 | max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2; | ||
976 | break; | 1037 | break; |
977 | } | 1038 | } |
1039 | len_left -= to_send; | ||
1040 | tmp_p += to_send; | ||
1041 | } while (len_left > 0); | ||
1042 | |||
1043 | len_left = len; | ||
1044 | |||
1045 | if (len > max_execve_audit_len) | ||
1046 | too_long = 1; | ||
1047 | |||
1048 | /* rewalk the argument actually logging the message */ | ||
1049 | for (i = 0; len_left > 0; i++) { | ||
1050 | int room_left; | ||
1051 | |||
1052 | if (len_left > max_execve_audit_len) | ||
1053 | to_send = max_execve_audit_len; | ||
1054 | else | ||
1055 | to_send = len_left; | ||
1056 | |||
1057 | /* do we have space left to send this argument in this ab? */ | ||
1058 | room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; | ||
1059 | if (has_cntl) | ||
1060 | room_left -= (to_send * 2); | ||
1061 | else | ||
1062 | room_left -= to_send; | ||
1063 | if (room_left < 0) { | ||
1064 | *len_sent = 0; | ||
1065 | audit_log_end(*ab); | ||
1066 | *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE); | ||
1067 | if (!*ab) | ||
1068 | return 0; | ||
1069 | } | ||
978 | 1070 | ||
979 | ret = copy_from_user(buf, p, len); | ||
980 | /* | 1071 | /* |
981 | * There is no reason for this copy to be short. We just | 1072 | * first record needs to say how long the original string was |
982 | * copied them here, and the mm hasn't been exposed to user- | 1073 | * so we can be sure nothing was lost. |
983 | * space yet. | 1074 | */ |
1075 | if ((i == 0) && (too_long)) | ||
1076 | audit_log_format(*ab, "a%d_len=%ld ", arg_num, | ||
1077 | has_cntl ? 2*len : len); | ||
1078 | |||
1079 | /* | ||
1080 | * normally arguments are small enough to fit and we already | ||
1081 | * filled buf above when we checked for control characters | ||
1082 | * so don't bother with another copy_from_user | ||
984 | */ | 1083 | */ |
1084 | if (len >= max_execve_audit_len) | ||
1085 | ret = copy_from_user(buf, p, to_send); | ||
1086 | else | ||
1087 | ret = 0; | ||
985 | if (ret) { | 1088 | if (ret) { |
986 | WARN_ON(1); | 1089 | WARN_ON(1); |
987 | send_sig(SIGKILL, current, 0); | 1090 | send_sig(SIGKILL, current, 0); |
988 | } | 1091 | } |
1092 | buf[to_send] = '\0'; | ||
1093 | |||
1094 | /* actually log it */ | ||
1095 | audit_log_format(*ab, "a%d", arg_num); | ||
1096 | if (too_long) | ||
1097 | audit_log_format(*ab, "[%d]", i); | ||
1098 | audit_log_format(*ab, "="); | ||
1099 | if (has_cntl) | ||
1100 | audit_log_hex(*ab, buf, to_send); | ||
1101 | else | ||
1102 | audit_log_format(*ab, "\"%s\"", buf); | ||
1103 | audit_log_format(*ab, "\n"); | ||
1104 | |||
1105 | p += to_send; | ||
1106 | len_left -= to_send; | ||
1107 | *len_sent += arg_num_len; | ||
1108 | if (has_cntl) | ||
1109 | *len_sent += to_send * 2; | ||
1110 | else | ||
1111 | *len_sent += to_send; | ||
1112 | } | ||
1113 | /* include the null we didn't log */ | ||
1114 | return len + 1; | ||
1115 | } | ||
989 | 1116 | ||
990 | audit_log_format(ab, "a%d=", i); | 1117 | static void audit_log_execve_info(struct audit_context *context, |
991 | audit_log_untrustedstring(ab, buf); | 1118 | struct audit_buffer **ab, |
992 | audit_log_format(ab, "\n"); | 1119 | struct audit_aux_data_execve *axi) |
1120 | { | ||
1121 | int i; | ||
1122 | size_t len, len_sent = 0; | ||
1123 | const char __user *p; | ||
1124 | char *buf; | ||
1125 | |||
1126 | if (axi->mm != current->mm) | ||
1127 | return; /* execve failed, no additional info */ | ||
1128 | |||
1129 | p = (const char __user *)axi->mm->arg_start; | ||
1130 | |||
1131 | audit_log_format(*ab, "argc=%d ", axi->argc); | ||
1132 | |||
1133 | /* | ||
1134 | * we need some kernel buffer to hold the userspace args. Just | ||
1135 | * allocate one big one rather than allocating one of the right size | ||
1136 | * for every single argument inside audit_log_single_execve_arg() | ||
1137 | * should be <8k allocation so should be pretty safe. | ||
1138 | */ | ||
1139 | buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); | ||
1140 | if (!buf) { | ||
1141 | audit_panic("out of memory for argv string\n"); | ||
1142 | return; | ||
1143 | } | ||
993 | 1144 | ||
994 | kfree(buf); | 1145 | for (i = 0; i < axi->argc; i++) { |
1146 | len = audit_log_single_execve_arg(context, ab, i, | ||
1147 | &len_sent, p, buf); | ||
1148 | if (len <= 0) | ||
1149 | break; | ||
1150 | p += len; | ||
995 | } | 1151 | } |
1152 | kfree(buf); | ||
996 | } | 1153 | } |
997 | 1154 | ||
998 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) | 1155 | static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
@@ -1039,7 +1196,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1039 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" | 1196 | " a0=%lx a1=%lx a2=%lx a3=%lx items=%d" |
1040 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" | 1197 | " ppid=%d pid=%d auid=%u uid=%u gid=%u" |
1041 | " euid=%u suid=%u fsuid=%u" | 1198 | " euid=%u suid=%u fsuid=%u" |
1042 | " egid=%u sgid=%u fsgid=%u tty=%s", | 1199 | " egid=%u sgid=%u fsgid=%u tty=%s ses=%u", |
1043 | context->argv[0], | 1200 | context->argv[0], |
1044 | context->argv[1], | 1201 | context->argv[1], |
1045 | context->argv[2], | 1202 | context->argv[2], |
@@ -1047,11 +1204,12 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1047 | context->name_count, | 1204 | context->name_count, |
1048 | context->ppid, | 1205 | context->ppid, |
1049 | context->pid, | 1206 | context->pid, |
1050 | context->loginuid, | 1207 | tsk->loginuid, |
1051 | context->uid, | 1208 | context->uid, |
1052 | context->gid, | 1209 | context->gid, |
1053 | context->euid, context->suid, context->fsuid, | 1210 | context->euid, context->suid, context->fsuid, |
1054 | context->egid, context->sgid, context->fsgid, tty); | 1211 | context->egid, context->sgid, context->fsgid, tty, |
1212 | tsk->sessionid); | ||
1055 | 1213 | ||
1056 | mutex_unlock(&tty_mutex); | 1214 | mutex_unlock(&tty_mutex); |
1057 | 1215 | ||
@@ -1135,7 +1293,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1135 | 1293 | ||
1136 | case AUDIT_EXECVE: { | 1294 | case AUDIT_EXECVE: { |
1137 | struct audit_aux_data_execve *axi = (void *)aux; | 1295 | struct audit_aux_data_execve *axi = (void *)aux; |
1138 | audit_log_execve_info(ab, axi); | 1296 | audit_log_execve_info(context, &ab, axi); |
1139 | break; } | 1297 | break; } |
1140 | 1298 | ||
1141 | case AUDIT_SOCKETCALL: { | 1299 | case AUDIT_SOCKETCALL: { |
@@ -1168,13 +1326,19 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1168 | 1326 | ||
1169 | for (i = 0; i < axs->pid_count; i++) | 1327 | for (i = 0; i < axs->pid_count; i++) |
1170 | if (audit_log_pid_context(context, axs->target_pid[i], | 1328 | if (audit_log_pid_context(context, axs->target_pid[i], |
1171 | axs->target_sid[i])) | 1329 | axs->target_auid[i], |
1330 | axs->target_uid[i], | ||
1331 | axs->target_sessionid[i], | ||
1332 | axs->target_sid[i], | ||
1333 | axs->target_comm[i])) | ||
1172 | call_panic = 1; | 1334 | call_panic = 1; |
1173 | } | 1335 | } |
1174 | 1336 | ||
1175 | if (context->target_pid && | 1337 | if (context->target_pid && |
1176 | audit_log_pid_context(context, context->target_pid, | 1338 | audit_log_pid_context(context, context->target_pid, |
1177 | context->target_sid)) | 1339 | context->target_auid, context->target_uid, |
1340 | context->target_sessionid, | ||
1341 | context->target_sid, context->target_comm)) | ||
1178 | call_panic = 1; | 1342 | call_panic = 1; |
1179 | 1343 | ||
1180 | if (context->pwd && context->pwdmnt) { | 1344 | if (context->pwd && context->pwdmnt) { |
@@ -1242,6 +1406,11 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts | |||
1242 | 1406 | ||
1243 | audit_log_end(ab); | 1407 | audit_log_end(ab); |
1244 | } | 1408 | } |
1409 | |||
1410 | /* Send end of event record to help user space know we are finished */ | ||
1411 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); | ||
1412 | if (ab) | ||
1413 | audit_log_end(ab); | ||
1245 | if (call_panic) | 1414 | if (call_panic) |
1246 | audit_panic("error converting sid to string"); | 1415 | audit_panic("error converting sid to string"); |
1247 | } | 1416 | } |
@@ -1766,6 +1935,9 @@ void auditsc_get_stamp(struct audit_context *ctx, | |||
1766 | ctx->auditable = 1; | 1935 | ctx->auditable = 1; |
1767 | } | 1936 | } |
1768 | 1937 | ||
1938 | /* global counter which is incremented every time something logs in */ | ||
1939 | static atomic_t session_id = ATOMIC_INIT(0); | ||
1940 | |||
1769 | /** | 1941 | /** |
1770 | * audit_set_loginuid - set a task's audit_context loginuid | 1942 | * audit_set_loginuid - set a task's audit_context loginuid |
1771 | * @task: task whose audit context is being modified | 1943 | * @task: task whose audit context is being modified |
@@ -1777,41 +1949,29 @@ void auditsc_get_stamp(struct audit_context *ctx, | |||
1777 | */ | 1949 | */ |
1778 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) | 1950 | int audit_set_loginuid(struct task_struct *task, uid_t loginuid) |
1779 | { | 1951 | { |
1952 | unsigned int sessionid = atomic_inc_return(&session_id); | ||
1780 | struct audit_context *context = task->audit_context; | 1953 | struct audit_context *context = task->audit_context; |
1781 | 1954 | ||
1782 | if (context) { | 1955 | if (context && context->in_syscall) { |
1783 | /* Only log if audit is enabled */ | 1956 | struct audit_buffer *ab; |
1784 | if (context->in_syscall) { | 1957 | |
1785 | struct audit_buffer *ab; | 1958 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); |
1786 | 1959 | if (ab) { | |
1787 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); | 1960 | audit_log_format(ab, "login pid=%d uid=%u " |
1788 | if (ab) { | 1961 | "old auid=%u new auid=%u" |
1789 | audit_log_format(ab, "login pid=%d uid=%u " | 1962 | " old ses=%u new ses=%u", |
1790 | "old auid=%u new auid=%u", | 1963 | task->pid, task->uid, |
1791 | task->pid, task->uid, | 1964 | task->loginuid, loginuid, |
1792 | context->loginuid, loginuid); | 1965 | task->sessionid, sessionid); |
1793 | audit_log_end(ab); | 1966 | audit_log_end(ab); |
1794 | } | ||
1795 | } | 1967 | } |
1796 | context->loginuid = loginuid; | ||
1797 | } | 1968 | } |
1969 | task->sessionid = sessionid; | ||
1970 | task->loginuid = loginuid; | ||
1798 | return 0; | 1971 | return 0; |
1799 | } | 1972 | } |
1800 | 1973 | ||
1801 | /** | 1974 | /** |
1802 | * audit_get_loginuid - get the loginuid for an audit_context | ||
1803 | * @ctx: the audit_context | ||
1804 | * | ||
1805 | * Returns the context's loginuid or -1 if @ctx is NULL. | ||
1806 | */ | ||
1807 | uid_t audit_get_loginuid(struct audit_context *ctx) | ||
1808 | { | ||
1809 | return ctx ? ctx->loginuid : -1; | ||
1810 | } | ||
1811 | |||
1812 | EXPORT_SYMBOL(audit_get_loginuid); | ||
1813 | |||
1814 | /** | ||
1815 | * __audit_mq_open - record audit data for a POSIX MQ open | 1975 | * __audit_mq_open - record audit data for a POSIX MQ open |
1816 | * @oflag: open flag | 1976 | * @oflag: open flag |
1817 | * @mode: mode bits | 1977 | * @mode: mode bits |
@@ -2070,8 +2230,6 @@ int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode | |||
2070 | return 0; | 2230 | return 0; |
2071 | } | 2231 | } |
2072 | 2232 | ||
2073 | int audit_argv_kb = 32; | ||
2074 | |||
2075 | int audit_bprm(struct linux_binprm *bprm) | 2233 | int audit_bprm(struct linux_binprm *bprm) |
2076 | { | 2234 | { |
2077 | struct audit_aux_data_execve *ax; | 2235 | struct audit_aux_data_execve *ax; |
@@ -2080,14 +2238,6 @@ int audit_bprm(struct linux_binprm *bprm) | |||
2080 | if (likely(!audit_enabled || !context || context->dummy)) | 2238 | if (likely(!audit_enabled || !context || context->dummy)) |
2081 | return 0; | 2239 | return 0; |
2082 | 2240 | ||
2083 | /* | ||
2084 | * Even though the stack code doesn't limit the arg+env size any more, | ||
2085 | * the audit code requires that _all_ arguments be logged in a single | ||
2086 | * netlink skb. Hence cap it :-( | ||
2087 | */ | ||
2088 | if (bprm->argv_len > (audit_argv_kb << 10)) | ||
2089 | return -E2BIG; | ||
2090 | |||
2091 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); | 2241 | ax = kmalloc(sizeof(*ax), GFP_KERNEL); |
2092 | if (!ax) | 2242 | if (!ax) |
2093 | return -ENOMEM; | 2243 | return -ENOMEM; |
@@ -2193,7 +2343,11 @@ void __audit_ptrace(struct task_struct *t) | |||
2193 | struct audit_context *context = current->audit_context; | 2343 | struct audit_context *context = current->audit_context; |
2194 | 2344 | ||
2195 | context->target_pid = t->pid; | 2345 | context->target_pid = t->pid; |
2346 | context->target_auid = audit_get_loginuid(t); | ||
2347 | context->target_uid = t->uid; | ||
2348 | context->target_sessionid = audit_get_sessionid(t); | ||
2196 | selinux_get_task_sid(t, &context->target_sid); | 2349 | selinux_get_task_sid(t, &context->target_sid); |
2350 | memcpy(context->target_comm, t->comm, TASK_COMM_LEN); | ||
2197 | } | 2351 | } |
2198 | 2352 | ||
2199 | /** | 2353 | /** |
@@ -2216,8 +2370,8 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2216 | if (audit_pid && t->tgid == audit_pid) { | 2370 | if (audit_pid && t->tgid == audit_pid) { |
2217 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { | 2371 | if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1) { |
2218 | audit_sig_pid = tsk->pid; | 2372 | audit_sig_pid = tsk->pid; |
2219 | if (ctx) | 2373 | if (tsk->loginuid != -1) |
2220 | audit_sig_uid = ctx->loginuid; | 2374 | audit_sig_uid = tsk->loginuid; |
2221 | else | 2375 | else |
2222 | audit_sig_uid = tsk->uid; | 2376 | audit_sig_uid = tsk->uid; |
2223 | selinux_get_task_sid(tsk, &audit_sig_sid); | 2377 | selinux_get_task_sid(tsk, &audit_sig_sid); |
@@ -2230,7 +2384,11 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2230 | * in audit_context */ | 2384 | * in audit_context */ |
2231 | if (!ctx->target_pid) { | 2385 | if (!ctx->target_pid) { |
2232 | ctx->target_pid = t->tgid; | 2386 | ctx->target_pid = t->tgid; |
2387 | ctx->target_auid = audit_get_loginuid(t); | ||
2388 | ctx->target_uid = t->uid; | ||
2389 | ctx->target_sessionid = audit_get_sessionid(t); | ||
2233 | selinux_get_task_sid(t, &ctx->target_sid); | 2390 | selinux_get_task_sid(t, &ctx->target_sid); |
2391 | memcpy(ctx->target_comm, t->comm, TASK_COMM_LEN); | ||
2234 | return 0; | 2392 | return 0; |
2235 | } | 2393 | } |
2236 | 2394 | ||
@@ -2247,7 +2405,11 @@ int __audit_signal_info(int sig, struct task_struct *t) | |||
2247 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); | 2405 | BUG_ON(axp->pid_count >= AUDIT_AUX_PIDS); |
2248 | 2406 | ||
2249 | axp->target_pid[axp->pid_count] = t->tgid; | 2407 | axp->target_pid[axp->pid_count] = t->tgid; |
2408 | axp->target_auid[axp->pid_count] = audit_get_loginuid(t); | ||
2409 | axp->target_uid[axp->pid_count] = t->uid; | ||
2410 | axp->target_sessionid[axp->pid_count] = audit_get_sessionid(t); | ||
2250 | selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]); | 2411 | selinux_get_task_sid(t, &axp->target_sid[axp->pid_count]); |
2412 | memcpy(axp->target_comm[axp->pid_count], t->comm, TASK_COMM_LEN); | ||
2251 | axp->pid_count++; | 2413 | axp->pid_count++; |
2252 | 2414 | ||
2253 | return 0; | 2415 | return 0; |
@@ -2264,6 +2426,8 @@ void audit_core_dumps(long signr) | |||
2264 | { | 2426 | { |
2265 | struct audit_buffer *ab; | 2427 | struct audit_buffer *ab; |
2266 | u32 sid; | 2428 | u32 sid; |
2429 | uid_t auid = audit_get_loginuid(current); | ||
2430 | unsigned int sessionid = audit_get_sessionid(current); | ||
2267 | 2431 | ||
2268 | if (!audit_enabled) | 2432 | if (!audit_enabled) |
2269 | return; | 2433 | return; |
@@ -2272,9 +2436,8 @@ void audit_core_dumps(long signr) | |||
2272 | return; | 2436 | return; |
2273 | 2437 | ||
2274 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); | 2438 | ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_ANOM_ABEND); |
2275 | audit_log_format(ab, "auid=%u uid=%u gid=%u", | 2439 | audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u", |
2276 | audit_get_loginuid(current->audit_context), | 2440 | auid, current->uid, current->gid, sessionid); |
2277 | current->uid, current->gid); | ||
2278 | selinux_get_task_sid(current, &sid); | 2441 | selinux_get_task_sid(current, &sid); |
2279 | if (sid) { | 2442 | if (sid) { |
2280 | char *ctx = NULL; | 2443 | char *ctx = NULL; |