.. | .. |
---|
75 | 75 | #include <linux/uaccess.h> |
---|
76 | 76 | #include <linux/fsnotify_backend.h> |
---|
77 | 77 | #include <uapi/linux/limits.h> |
---|
| 78 | +#include <uapi/linux/netfilter/nf_tables.h> |
---|
78 | 79 | |
---|
79 | 80 | #include "audit.h" |
---|
80 | 81 | |
---|
.. | .. |
---|
128 | 129 | struct audit_tree_refs { |
---|
129 | 130 | struct audit_tree_refs *next; |
---|
130 | 131 | struct audit_chunk *c[31]; |
---|
| 132 | +}; |
---|
| 133 | + |
---|
| 134 | +struct audit_nfcfgop_tab { |
---|
| 135 | + enum audit_nfcfgop op; |
---|
| 136 | + const char *s; |
---|
| 137 | +}; |
---|
| 138 | + |
---|
| 139 | +static const struct audit_nfcfgop_tab audit_nfcfgs[] = { |
---|
| 140 | + { AUDIT_XT_OP_REGISTER, "xt_register" }, |
---|
| 141 | + { AUDIT_XT_OP_REPLACE, "xt_replace" }, |
---|
| 142 | + { AUDIT_XT_OP_UNREGISTER, "xt_unregister" }, |
---|
| 143 | + { AUDIT_NFT_OP_TABLE_REGISTER, "nft_register_table" }, |
---|
| 144 | + { AUDIT_NFT_OP_TABLE_UNREGISTER, "nft_unregister_table" }, |
---|
| 145 | + { AUDIT_NFT_OP_CHAIN_REGISTER, "nft_register_chain" }, |
---|
| 146 | + { AUDIT_NFT_OP_CHAIN_UNREGISTER, "nft_unregister_chain" }, |
---|
| 147 | + { AUDIT_NFT_OP_RULE_REGISTER, "nft_register_rule" }, |
---|
| 148 | + { AUDIT_NFT_OP_RULE_UNREGISTER, "nft_unregister_rule" }, |
---|
| 149 | + { AUDIT_NFT_OP_SET_REGISTER, "nft_register_set" }, |
---|
| 150 | + { AUDIT_NFT_OP_SET_UNREGISTER, "nft_unregister_set" }, |
---|
| 151 | + { AUDIT_NFT_OP_SETELEM_REGISTER, "nft_register_setelem" }, |
---|
| 152 | + { AUDIT_NFT_OP_SETELEM_UNREGISTER, "nft_unregister_setelem" }, |
---|
| 153 | + { AUDIT_NFT_OP_GEN_REGISTER, "nft_register_gen" }, |
---|
| 154 | + { AUDIT_NFT_OP_OBJ_REGISTER, "nft_register_obj" }, |
---|
| 155 | + { AUDIT_NFT_OP_OBJ_UNREGISTER, "nft_unregister_obj" }, |
---|
| 156 | + { AUDIT_NFT_OP_OBJ_RESET, "nft_reset_obj" }, |
---|
| 157 | + { AUDIT_NFT_OP_FLOWTABLE_REGISTER, "nft_register_flowtable" }, |
---|
| 158 | + { AUDIT_NFT_OP_FLOWTABLE_UNREGISTER, "nft_unregister_flowtable" }, |
---|
| 159 | + { AUDIT_NFT_OP_INVALID, "nft_invalid" }, |
---|
131 | 160 | }; |
---|
132 | 161 | |
---|
133 | 162 | static int audit_match_perm(struct audit_context *ctx, int mask) |
---|
.. | .. |
---|
200 | 229 | * References in it _are_ dropped - at the same time we free/drop aux stuff. |
---|
201 | 230 | */ |
---|
202 | 231 | |
---|
203 | | -#ifdef CONFIG_AUDIT_TREE |
---|
204 | 232 | static void audit_set_auditable(struct audit_context *ctx) |
---|
205 | 233 | { |
---|
206 | 234 | if (!ctx->prio) { |
---|
.. | .. |
---|
245 | 273 | ctx->tree_count = 31; |
---|
246 | 274 | return 1; |
---|
247 | 275 | } |
---|
248 | | -#endif |
---|
249 | 276 | |
---|
250 | 277 | static void unroll_tree_refs(struct audit_context *ctx, |
---|
251 | 278 | struct audit_tree_refs *p, int count) |
---|
252 | 279 | { |
---|
253 | | -#ifdef CONFIG_AUDIT_TREE |
---|
254 | 280 | struct audit_tree_refs *q; |
---|
255 | 281 | int n; |
---|
256 | 282 | if (!p) { |
---|
.. | .. |
---|
274 | 300 | } |
---|
275 | 301 | ctx->trees = p; |
---|
276 | 302 | ctx->tree_count = count; |
---|
277 | | -#endif |
---|
278 | 303 | } |
---|
279 | 304 | |
---|
280 | 305 | static void free_tree_refs(struct audit_context *ctx) |
---|
.. | .. |
---|
288 | 313 | |
---|
289 | 314 | static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree) |
---|
290 | 315 | { |
---|
291 | | -#ifdef CONFIG_AUDIT_TREE |
---|
292 | 316 | struct audit_tree_refs *p; |
---|
293 | 317 | int n; |
---|
294 | 318 | if (!tree) |
---|
.. | .. |
---|
305 | 329 | if (audit_tree_match(p->c[n], tree)) |
---|
306 | 330 | return 1; |
---|
307 | 331 | } |
---|
308 | | -#endif |
---|
309 | 332 | return 0; |
---|
310 | 333 | } |
---|
311 | 334 | |
---|
.. | .. |
---|
607 | 630 | } |
---|
608 | 631 | break; |
---|
609 | 632 | case AUDIT_WATCH: |
---|
610 | | - if (name) |
---|
611 | | - result = audit_watch_compare(rule->watch, name->ino, name->dev); |
---|
| 633 | + if (name) { |
---|
| 634 | + result = audit_watch_compare(rule->watch, |
---|
| 635 | + name->ino, |
---|
| 636 | + name->dev); |
---|
| 637 | + if (f->op == Audit_not_equal) |
---|
| 638 | + result = !result; |
---|
| 639 | + } |
---|
612 | 640 | break; |
---|
613 | 641 | case AUDIT_DIR: |
---|
614 | | - if (ctx) |
---|
| 642 | + if (ctx) { |
---|
615 | 643 | result = match_tree_refs(ctx, rule->tree); |
---|
| 644 | + if (f->op == Audit_not_equal) |
---|
| 645 | + result = !result; |
---|
| 646 | + } |
---|
616 | 647 | break; |
---|
617 | 648 | case AUDIT_LOGINUID: |
---|
618 | 649 | result = audit_uid_comparator(audit_get_loginuid(tsk), |
---|
.. | .. |
---|
620 | 651 | break; |
---|
621 | 652 | case AUDIT_LOGINUID_SET: |
---|
622 | 653 | result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val); |
---|
| 654 | + break; |
---|
| 655 | + case AUDIT_SADDR_FAM: |
---|
| 656 | + if (ctx && ctx->sockaddr) |
---|
| 657 | + result = audit_comparator(ctx->sockaddr->ss_family, |
---|
| 658 | + f->op, f->val); |
---|
623 | 659 | break; |
---|
624 | 660 | case AUDIT_SUBJ_USER: |
---|
625 | 661 | case AUDIT_SUBJ_ROLE: |
---|
.. | .. |
---|
637 | 673 | need_sid = 0; |
---|
638 | 674 | } |
---|
639 | 675 | result = security_audit_rule_match(sid, f->type, |
---|
640 | | - f->op, |
---|
641 | | - f->lsm_rule, |
---|
642 | | - ctx); |
---|
| 676 | + f->op, |
---|
| 677 | + f->lsm_rule); |
---|
643 | 678 | } |
---|
644 | 679 | break; |
---|
645 | 680 | case AUDIT_OBJ_USER: |
---|
.. | .. |
---|
653 | 688 | /* Find files that match */ |
---|
654 | 689 | if (name) { |
---|
655 | 690 | result = security_audit_rule_match( |
---|
656 | | - name->osid, f->type, f->op, |
---|
657 | | - f->lsm_rule, ctx); |
---|
| 691 | + name->osid, |
---|
| 692 | + f->type, |
---|
| 693 | + f->op, |
---|
| 694 | + f->lsm_rule); |
---|
658 | 695 | } else if (ctx) { |
---|
659 | 696 | list_for_each_entry(n, &ctx->names_list, list) { |
---|
660 | | - if (security_audit_rule_match(n->osid, f->type, |
---|
661 | | - f->op, f->lsm_rule, |
---|
662 | | - ctx)) { |
---|
| 697 | + if (security_audit_rule_match( |
---|
| 698 | + n->osid, |
---|
| 699 | + f->type, |
---|
| 700 | + f->op, |
---|
| 701 | + f->lsm_rule)) { |
---|
663 | 702 | ++result; |
---|
664 | 703 | break; |
---|
665 | 704 | } |
---|
.. | .. |
---|
670 | 709 | break; |
---|
671 | 710 | if (security_audit_rule_match(ctx->ipc.osid, |
---|
672 | 711 | f->type, f->op, |
---|
673 | | - f->lsm_rule, ctx)) |
---|
| 712 | + f->lsm_rule)) |
---|
674 | 713 | ++result; |
---|
675 | 714 | } |
---|
676 | 715 | break; |
---|
.. | .. |
---|
687 | 726 | break; |
---|
688 | 727 | case AUDIT_PERM: |
---|
689 | 728 | result = audit_match_perm(ctx, f->val); |
---|
| 729 | + if (f->op == Audit_not_equal) |
---|
| 730 | + result = !result; |
---|
690 | 731 | break; |
---|
691 | 732 | case AUDIT_FILETYPE: |
---|
692 | 733 | result = audit_match_filetype(ctx, f->val); |
---|
| 734 | + if (f->op == Audit_not_equal) |
---|
| 735 | + result = !result; |
---|
693 | 736 | break; |
---|
694 | 737 | case AUDIT_FIELD_COMPARE: |
---|
695 | 738 | result = audit_field_compare(tsk, cred, f, ctx, name); |
---|
.. | .. |
---|
774 | 817 | return AUDIT_DISABLED; |
---|
775 | 818 | |
---|
776 | 819 | rcu_read_lock(); |
---|
777 | | - if (!list_empty(list)) { |
---|
778 | | - list_for_each_entry_rcu(e, list, list) { |
---|
779 | | - if (audit_in_mask(&e->rule, ctx->major) && |
---|
780 | | - audit_filter_rules(tsk, &e->rule, ctx, NULL, |
---|
781 | | - &state, false)) { |
---|
782 | | - rcu_read_unlock(); |
---|
783 | | - ctx->current_state = state; |
---|
784 | | - return state; |
---|
785 | | - } |
---|
| 820 | + list_for_each_entry_rcu(e, list, list) { |
---|
| 821 | + if (audit_in_mask(&e->rule, ctx->major) && |
---|
| 822 | + audit_filter_rules(tsk, &e->rule, ctx, NULL, |
---|
| 823 | + &state, false)) { |
---|
| 824 | + rcu_read_unlock(); |
---|
| 825 | + ctx->current_state = state; |
---|
| 826 | + return state; |
---|
786 | 827 | } |
---|
787 | 828 | } |
---|
788 | 829 | rcu_read_unlock(); |
---|
.. | .. |
---|
801 | 842 | struct audit_entry *e; |
---|
802 | 843 | enum audit_state state; |
---|
803 | 844 | |
---|
804 | | - if (list_empty(list)) |
---|
805 | | - return 0; |
---|
806 | | - |
---|
807 | 845 | list_for_each_entry_rcu(e, list, list) { |
---|
808 | 846 | if (audit_in_mask(&e->rule, ctx->major) && |
---|
809 | 847 | audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { |
---|
.. | .. |
---|
811 | 849 | return 1; |
---|
812 | 850 | } |
---|
813 | 851 | } |
---|
814 | | - |
---|
815 | 852 | return 0; |
---|
816 | 853 | } |
---|
817 | 854 | |
---|
.. | .. |
---|
836 | 873 | rcu_read_unlock(); |
---|
837 | 874 | } |
---|
838 | 875 | |
---|
839 | | -/* Transfer the audit context pointer to the caller, clearing it in the tsk's struct */ |
---|
840 | | -static inline struct audit_context *audit_take_context(struct task_struct *tsk, |
---|
841 | | - int return_valid, |
---|
842 | | - long return_code) |
---|
843 | | -{ |
---|
844 | | - struct audit_context *context = tsk->audit_context; |
---|
845 | | - |
---|
846 | | - if (!context) |
---|
847 | | - return NULL; |
---|
848 | | - context->return_valid = return_valid; |
---|
849 | | - |
---|
850 | | - /* |
---|
851 | | - * we need to fix up the return code in the audit logs if the actual |
---|
852 | | - * return codes are later going to be fixed up by the arch specific |
---|
853 | | - * signal handlers |
---|
854 | | - * |
---|
855 | | - * This is actually a test for: |
---|
856 | | - * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) || |
---|
857 | | - * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK) |
---|
858 | | - * |
---|
859 | | - * but is faster than a bunch of || |
---|
860 | | - */ |
---|
861 | | - if (unlikely(return_code <= -ERESTARTSYS) && |
---|
862 | | - (return_code >= -ERESTART_RESTARTBLOCK) && |
---|
863 | | - (return_code != -ENOIOCTLCMD)) |
---|
864 | | - context->return_code = -EINTR; |
---|
865 | | - else |
---|
866 | | - context->return_code = return_code; |
---|
867 | | - |
---|
868 | | - if (context->in_syscall && !context->dummy) { |
---|
869 | | - audit_filter_syscall(tsk, context, &audit_filter_list[AUDIT_FILTER_EXIT]); |
---|
870 | | - audit_filter_inodes(tsk, context); |
---|
871 | | - } |
---|
872 | | - |
---|
873 | | - audit_set_context(tsk, NULL); |
---|
874 | | - return context; |
---|
875 | | -} |
---|
876 | | - |
---|
877 | 876 | static inline void audit_proctitle_free(struct audit_context *context) |
---|
878 | 877 | { |
---|
879 | 878 | kfree(context->proctitle.value); |
---|
.. | .. |
---|
881 | 880 | context->proctitle.len = 0; |
---|
882 | 881 | } |
---|
883 | 882 | |
---|
| 883 | +static inline void audit_free_module(struct audit_context *context) |
---|
| 884 | +{ |
---|
| 885 | + if (context->type == AUDIT_KERN_MODULE) { |
---|
| 886 | + kfree(context->module.name); |
---|
| 887 | + context->module.name = NULL; |
---|
| 888 | + } |
---|
| 889 | +} |
---|
884 | 890 | static inline void audit_free_names(struct audit_context *context) |
---|
885 | 891 | { |
---|
886 | 892 | struct audit_names *n, *next; |
---|
.. | .. |
---|
964 | 970 | |
---|
965 | 971 | static inline void audit_free_context(struct audit_context *context) |
---|
966 | 972 | { |
---|
| 973 | + audit_free_module(context); |
---|
967 | 974 | audit_free_names(context); |
---|
968 | 975 | unroll_tree_refs(context, NULL, 0); |
---|
969 | 976 | free_tree_refs(context); |
---|
.. | .. |
---|
1180 | 1187 | kfree(buf_head); |
---|
1181 | 1188 | } |
---|
1182 | 1189 | |
---|
| 1190 | +static void audit_log_cap(struct audit_buffer *ab, char *prefix, |
---|
| 1191 | + kernel_cap_t *cap) |
---|
| 1192 | +{ |
---|
| 1193 | + int i; |
---|
| 1194 | + |
---|
| 1195 | + if (cap_isclear(*cap)) { |
---|
| 1196 | + audit_log_format(ab, " %s=0", prefix); |
---|
| 1197 | + return; |
---|
| 1198 | + } |
---|
| 1199 | + audit_log_format(ab, " %s=", prefix); |
---|
| 1200 | + CAP_FOR_EACH_U32(i) |
---|
| 1201 | + audit_log_format(ab, "%08x", cap->cap[CAP_LAST_U32 - i]); |
---|
| 1202 | +} |
---|
| 1203 | + |
---|
| 1204 | +static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name) |
---|
| 1205 | +{ |
---|
| 1206 | + if (name->fcap_ver == -1) { |
---|
| 1207 | + audit_log_format(ab, " cap_fe=? cap_fver=? cap_fp=? cap_fi=?"); |
---|
| 1208 | + return; |
---|
| 1209 | + } |
---|
| 1210 | + audit_log_cap(ab, "cap_fp", &name->fcap.permitted); |
---|
| 1211 | + audit_log_cap(ab, "cap_fi", &name->fcap.inheritable); |
---|
| 1212 | + audit_log_format(ab, " cap_fe=%d cap_fver=%x cap_frootid=%d", |
---|
| 1213 | + name->fcap.fE, name->fcap_ver, |
---|
| 1214 | + from_kuid(&init_user_ns, name->fcap.rootid)); |
---|
| 1215 | +} |
---|
| 1216 | + |
---|
| 1217 | +static void audit_log_time(struct audit_context *context, struct audit_buffer **ab) |
---|
| 1218 | +{ |
---|
| 1219 | + const struct audit_ntp_data *ntp = &context->time.ntp_data; |
---|
| 1220 | + const struct timespec64 *tk = &context->time.tk_injoffset; |
---|
| 1221 | + static const char * const ntp_name[] = { |
---|
| 1222 | + "offset", |
---|
| 1223 | + "freq", |
---|
| 1224 | + "status", |
---|
| 1225 | + "tai", |
---|
| 1226 | + "tick", |
---|
| 1227 | + "adjust", |
---|
| 1228 | + }; |
---|
| 1229 | + int type; |
---|
| 1230 | + |
---|
| 1231 | + if (context->type == AUDIT_TIME_ADJNTPVAL) { |
---|
| 1232 | + for (type = 0; type < AUDIT_NTP_NVALS; type++) { |
---|
| 1233 | + if (ntp->vals[type].newval != ntp->vals[type].oldval) { |
---|
| 1234 | + if (!*ab) { |
---|
| 1235 | + *ab = audit_log_start(context, |
---|
| 1236 | + GFP_KERNEL, |
---|
| 1237 | + AUDIT_TIME_ADJNTPVAL); |
---|
| 1238 | + if (!*ab) |
---|
| 1239 | + return; |
---|
| 1240 | + } |
---|
| 1241 | + audit_log_format(*ab, "op=%s old=%lli new=%lli", |
---|
| 1242 | + ntp_name[type], |
---|
| 1243 | + ntp->vals[type].oldval, |
---|
| 1244 | + ntp->vals[type].newval); |
---|
| 1245 | + audit_log_end(*ab); |
---|
| 1246 | + *ab = NULL; |
---|
| 1247 | + } |
---|
| 1248 | + } |
---|
| 1249 | + } |
---|
| 1250 | + if (tk->tv_sec != 0 || tk->tv_nsec != 0) { |
---|
| 1251 | + if (!*ab) { |
---|
| 1252 | + *ab = audit_log_start(context, GFP_KERNEL, |
---|
| 1253 | + AUDIT_TIME_INJOFFSET); |
---|
| 1254 | + if (!*ab) |
---|
| 1255 | + return; |
---|
| 1256 | + } |
---|
| 1257 | + audit_log_format(*ab, "sec=%lli nsec=%li", |
---|
| 1258 | + (long long)tk->tv_sec, tk->tv_nsec); |
---|
| 1259 | + audit_log_end(*ab); |
---|
| 1260 | + *ab = NULL; |
---|
| 1261 | + } |
---|
| 1262 | +} |
---|
| 1263 | + |
---|
1183 | 1264 | static void show_special(struct audit_context *context, int *call_panic) |
---|
1184 | 1265 | { |
---|
1185 | 1266 | struct audit_buffer *ab; |
---|
.. | .. |
---|
1281 | 1362 | audit_log_format(ab, "name="); |
---|
1282 | 1363 | if (context->module.name) { |
---|
1283 | 1364 | audit_log_untrustedstring(ab, context->module.name); |
---|
1284 | | - kfree(context->module.name); |
---|
1285 | 1365 | } else |
---|
1286 | 1366 | audit_log_format(ab, "(null)"); |
---|
1287 | 1367 | |
---|
| 1368 | + break; |
---|
| 1369 | + case AUDIT_TIME_ADJNTPVAL: |
---|
| 1370 | + case AUDIT_TIME_INJOFFSET: |
---|
| 1371 | + /* this call deviates from the rest, eating the buffer */ |
---|
| 1372 | + audit_log_time(context, &ab); |
---|
1288 | 1373 | break; |
---|
1289 | 1374 | } |
---|
1290 | 1375 | audit_log_end(ab); |
---|
.. | .. |
---|
1302 | 1387 | return len; |
---|
1303 | 1388 | } |
---|
1304 | 1389 | |
---|
1305 | | -static void audit_log_proctitle(struct task_struct *tsk, |
---|
1306 | | - struct audit_context *context) |
---|
| 1390 | +/* |
---|
| 1391 | + * audit_log_name - produce AUDIT_PATH record from struct audit_names |
---|
| 1392 | + * @context: audit_context for the task |
---|
| 1393 | + * @n: audit_names structure with reportable details |
---|
| 1394 | + * @path: optional path to report instead of audit_names->name |
---|
| 1395 | + * @record_num: record number to report when handling a list of names |
---|
| 1396 | + * @call_panic: optional pointer to int that will be updated if secid fails |
---|
| 1397 | + */ |
---|
| 1398 | +static void audit_log_name(struct audit_context *context, struct audit_names *n, |
---|
| 1399 | + const struct path *path, int record_num, int *call_panic) |
---|
| 1400 | +{ |
---|
| 1401 | + struct audit_buffer *ab; |
---|
| 1402 | + |
---|
| 1403 | + ab = audit_log_start(context, GFP_KERNEL, AUDIT_PATH); |
---|
| 1404 | + if (!ab) |
---|
| 1405 | + return; |
---|
| 1406 | + |
---|
| 1407 | + audit_log_format(ab, "item=%d", record_num); |
---|
| 1408 | + |
---|
| 1409 | + if (path) |
---|
| 1410 | + audit_log_d_path(ab, " name=", path); |
---|
| 1411 | + else if (n->name) { |
---|
| 1412 | + switch (n->name_len) { |
---|
| 1413 | + case AUDIT_NAME_FULL: |
---|
| 1414 | + /* log the full path */ |
---|
| 1415 | + audit_log_format(ab, " name="); |
---|
| 1416 | + audit_log_untrustedstring(ab, n->name->name); |
---|
| 1417 | + break; |
---|
| 1418 | + case 0: |
---|
| 1419 | + /* name was specified as a relative path and the |
---|
| 1420 | + * directory component is the cwd |
---|
| 1421 | + */ |
---|
| 1422 | + audit_log_d_path(ab, " name=", &context->pwd); |
---|
| 1423 | + break; |
---|
| 1424 | + default: |
---|
| 1425 | + /* log the name's directory component */ |
---|
| 1426 | + audit_log_format(ab, " name="); |
---|
| 1427 | + audit_log_n_untrustedstring(ab, n->name->name, |
---|
| 1428 | + n->name_len); |
---|
| 1429 | + } |
---|
| 1430 | + } else |
---|
| 1431 | + audit_log_format(ab, " name=(null)"); |
---|
| 1432 | + |
---|
| 1433 | + if (n->ino != AUDIT_INO_UNSET) |
---|
| 1434 | + audit_log_format(ab, " inode=%lu dev=%02x:%02x mode=%#ho ouid=%u ogid=%u rdev=%02x:%02x", |
---|
| 1435 | + n->ino, |
---|
| 1436 | + MAJOR(n->dev), |
---|
| 1437 | + MINOR(n->dev), |
---|
| 1438 | + n->mode, |
---|
| 1439 | + from_kuid(&init_user_ns, n->uid), |
---|
| 1440 | + from_kgid(&init_user_ns, n->gid), |
---|
| 1441 | + MAJOR(n->rdev), |
---|
| 1442 | + MINOR(n->rdev)); |
---|
| 1443 | + if (n->osid != 0) { |
---|
| 1444 | + char *ctx = NULL; |
---|
| 1445 | + u32 len; |
---|
| 1446 | + |
---|
| 1447 | + if (security_secid_to_secctx( |
---|
| 1448 | + n->osid, &ctx, &len)) { |
---|
| 1449 | + audit_log_format(ab, " osid=%u", n->osid); |
---|
| 1450 | + if (call_panic) |
---|
| 1451 | + *call_panic = 2; |
---|
| 1452 | + } else { |
---|
| 1453 | + audit_log_format(ab, " obj=%s", ctx); |
---|
| 1454 | + security_release_secctx(ctx, len); |
---|
| 1455 | + } |
---|
| 1456 | + } |
---|
| 1457 | + |
---|
| 1458 | + /* log the audit_names record type */ |
---|
| 1459 | + switch (n->type) { |
---|
| 1460 | + case AUDIT_TYPE_NORMAL: |
---|
| 1461 | + audit_log_format(ab, " nametype=NORMAL"); |
---|
| 1462 | + break; |
---|
| 1463 | + case AUDIT_TYPE_PARENT: |
---|
| 1464 | + audit_log_format(ab, " nametype=PARENT"); |
---|
| 1465 | + break; |
---|
| 1466 | + case AUDIT_TYPE_CHILD_DELETE: |
---|
| 1467 | + audit_log_format(ab, " nametype=DELETE"); |
---|
| 1468 | + break; |
---|
| 1469 | + case AUDIT_TYPE_CHILD_CREATE: |
---|
| 1470 | + audit_log_format(ab, " nametype=CREATE"); |
---|
| 1471 | + break; |
---|
| 1472 | + default: |
---|
| 1473 | + audit_log_format(ab, " nametype=UNKNOWN"); |
---|
| 1474 | + break; |
---|
| 1475 | + } |
---|
| 1476 | + |
---|
| 1477 | + audit_log_fcaps(ab, n); |
---|
| 1478 | + audit_log_end(ab); |
---|
| 1479 | +} |
---|
| 1480 | + |
---|
| 1481 | +static void audit_log_proctitle(void) |
---|
1307 | 1482 | { |
---|
1308 | 1483 | int res; |
---|
1309 | 1484 | char *buf; |
---|
1310 | 1485 | char *msg = "(null)"; |
---|
1311 | 1486 | int len = strlen(msg); |
---|
| 1487 | + struct audit_context *context = audit_context(); |
---|
1312 | 1488 | struct audit_buffer *ab; |
---|
| 1489 | + |
---|
| 1490 | + if (!context || context->dummy) |
---|
| 1491 | + return; |
---|
1313 | 1492 | |
---|
1314 | 1493 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_PROCTITLE); |
---|
1315 | 1494 | if (!ab) |
---|
.. | .. |
---|
1323 | 1502 | if (!buf) |
---|
1324 | 1503 | goto out; |
---|
1325 | 1504 | /* Historically called this from procfs naming */ |
---|
1326 | | - res = get_cmdline(tsk, buf, MAX_PROCTITLE_AUDIT_LEN); |
---|
| 1505 | + res = get_cmdline(current, buf, MAX_PROCTITLE_AUDIT_LEN); |
---|
1327 | 1506 | if (res == 0) { |
---|
1328 | 1507 | kfree(buf); |
---|
1329 | 1508 | goto out; |
---|
.. | .. |
---|
1343 | 1522 | audit_log_end(ab); |
---|
1344 | 1523 | } |
---|
1345 | 1524 | |
---|
1346 | | -static void audit_log_exit(struct audit_context *context, struct task_struct *tsk) |
---|
| 1525 | +static void audit_log_exit(void) |
---|
1347 | 1526 | { |
---|
1348 | 1527 | int i, call_panic = 0; |
---|
| 1528 | + struct audit_context *context = audit_context(); |
---|
1349 | 1529 | struct audit_buffer *ab; |
---|
1350 | 1530 | struct audit_aux_data *aux; |
---|
1351 | 1531 | struct audit_names *n; |
---|
1352 | 1532 | |
---|
1353 | | - /* tsk == current */ |
---|
1354 | | - context->personality = tsk->personality; |
---|
| 1533 | + context->personality = current->personality; |
---|
1355 | 1534 | |
---|
1356 | 1535 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_SYSCALL); |
---|
1357 | 1536 | if (!ab) |
---|
.. | .. |
---|
1373 | 1552 | context->argv[3], |
---|
1374 | 1553 | context->name_count); |
---|
1375 | 1554 | |
---|
1376 | | - audit_log_task_info(ab, tsk); |
---|
| 1555 | + audit_log_task_info(ab); |
---|
1377 | 1556 | audit_log_key(ab, context->filterkey); |
---|
1378 | 1557 | audit_log_end(ab); |
---|
1379 | 1558 | |
---|
.. | .. |
---|
1399 | 1578 | audit_log_cap(ab, "pi", &axs->new_pcap.inheritable); |
---|
1400 | 1579 | audit_log_cap(ab, "pe", &axs->new_pcap.effective); |
---|
1401 | 1580 | audit_log_cap(ab, "pa", &axs->new_pcap.ambient); |
---|
| 1581 | + audit_log_format(ab, " frootid=%d", |
---|
| 1582 | + from_kuid(&init_user_ns, |
---|
| 1583 | + axs->fcap.rootid)); |
---|
1402 | 1584 | break; } |
---|
1403 | 1585 | |
---|
1404 | 1586 | } |
---|
.. | .. |
---|
1462 | 1644 | audit_log_name(context, n, NULL, i++, &call_panic); |
---|
1463 | 1645 | } |
---|
1464 | 1646 | |
---|
1465 | | - audit_log_proctitle(tsk, context); |
---|
| 1647 | + audit_log_proctitle(); |
---|
1466 | 1648 | |
---|
1467 | 1649 | /* Send end of event record to help user space know we are finished */ |
---|
1468 | 1650 | ab = audit_log_start(context, GFP_KERNEL, AUDIT_EOE); |
---|
.. | .. |
---|
1480 | 1662 | */ |
---|
1481 | 1663 | void __audit_free(struct task_struct *tsk) |
---|
1482 | 1664 | { |
---|
1483 | | - struct audit_context *context; |
---|
| 1665 | + struct audit_context *context = tsk->audit_context; |
---|
1484 | 1666 | |
---|
1485 | | - context = audit_take_context(tsk, 0, 0); |
---|
1486 | 1667 | if (!context) |
---|
1487 | 1668 | return; |
---|
1488 | 1669 | |
---|
1489 | | - /* Check for system calls that do not go through the exit |
---|
1490 | | - * function (e.g., exit_group), then free context block. |
---|
1491 | | - * We use GFP_ATOMIC here because we might be doing this |
---|
1492 | | - * in the context of the idle thread */ |
---|
1493 | | - /* that can happen only if we are called from do_exit() */ |
---|
1494 | | - if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) |
---|
1495 | | - audit_log_exit(context, tsk); |
---|
1496 | 1670 | if (!list_empty(&context->killed_trees)) |
---|
1497 | | - audit_kill_trees(&context->killed_trees); |
---|
| 1671 | + audit_kill_trees(context); |
---|
1498 | 1672 | |
---|
| 1673 | + /* We are called either by do_exit() or the fork() error handling code; |
---|
| 1674 | + * in the former case tsk == current and in the latter tsk is a |
---|
| 1675 | + * random task_struct that doesn't doesn't have any meaningful data we |
---|
| 1676 | + * need to log via audit_log_exit(). |
---|
| 1677 | + */ |
---|
| 1678 | + if (tsk == current && !context->dummy && context->in_syscall) { |
---|
| 1679 | + context->return_valid = 0; |
---|
| 1680 | + context->return_code = 0; |
---|
| 1681 | + |
---|
| 1682 | + audit_filter_syscall(tsk, context, |
---|
| 1683 | + &audit_filter_list[AUDIT_FILTER_EXIT]); |
---|
| 1684 | + audit_filter_inodes(tsk, context); |
---|
| 1685 | + if (context->current_state == AUDIT_RECORD_CONTEXT) |
---|
| 1686 | + audit_log_exit(); |
---|
| 1687 | + } |
---|
| 1688 | + |
---|
| 1689 | + audit_set_context(tsk, NULL); |
---|
1499 | 1690 | audit_free_context(context); |
---|
1500 | 1691 | } |
---|
1501 | 1692 | |
---|
.. | .. |
---|
1537 | 1728 | return; |
---|
1538 | 1729 | } |
---|
1539 | 1730 | |
---|
1540 | | - context->arch = syscall_get_arch(); |
---|
| 1731 | + context->arch = syscall_get_arch(current); |
---|
1541 | 1732 | context->major = major; |
---|
1542 | 1733 | context->argv[0] = a1; |
---|
1543 | 1734 | context->argv[1] = a2; |
---|
.. | .. |
---|
1565 | 1756 | { |
---|
1566 | 1757 | struct audit_context *context; |
---|
1567 | 1758 | |
---|
1568 | | - if (success) |
---|
1569 | | - success = AUDITSC_SUCCESS; |
---|
1570 | | - else |
---|
1571 | | - success = AUDITSC_FAILURE; |
---|
1572 | | - |
---|
1573 | | - context = audit_take_context(current, success, return_code); |
---|
| 1759 | + context = audit_context(); |
---|
1574 | 1760 | if (!context) |
---|
1575 | 1761 | return; |
---|
1576 | 1762 | |
---|
1577 | | - if (context->in_syscall && context->current_state == AUDIT_RECORD_CONTEXT) |
---|
1578 | | - audit_log_exit(context, current); |
---|
| 1763 | + if (!list_empty(&context->killed_trees)) |
---|
| 1764 | + audit_kill_trees(context); |
---|
| 1765 | + |
---|
| 1766 | + if (!context->dummy && context->in_syscall) { |
---|
| 1767 | + if (success) |
---|
| 1768 | + context->return_valid = AUDITSC_SUCCESS; |
---|
| 1769 | + else |
---|
| 1770 | + context->return_valid = AUDITSC_FAILURE; |
---|
| 1771 | + |
---|
| 1772 | + /* |
---|
| 1773 | + * we need to fix up the return code in the audit logs if the |
---|
| 1774 | + * actual return codes are later going to be fixed up by the |
---|
| 1775 | + * arch specific signal handlers |
---|
| 1776 | + * |
---|
| 1777 | + * This is actually a test for: |
---|
| 1778 | + * (rc == ERESTARTSYS ) || (rc == ERESTARTNOINTR) || |
---|
| 1779 | + * (rc == ERESTARTNOHAND) || (rc == ERESTART_RESTARTBLOCK) |
---|
| 1780 | + * |
---|
| 1781 | + * but is faster than a bunch of || |
---|
| 1782 | + */ |
---|
| 1783 | + if (unlikely(return_code <= -ERESTARTSYS) && |
---|
| 1784 | + (return_code >= -ERESTART_RESTARTBLOCK) && |
---|
| 1785 | + (return_code != -ENOIOCTLCMD)) |
---|
| 1786 | + context->return_code = -EINTR; |
---|
| 1787 | + else |
---|
| 1788 | + context->return_code = return_code; |
---|
| 1789 | + |
---|
| 1790 | + audit_filter_syscall(current, context, |
---|
| 1791 | + &audit_filter_list[AUDIT_FILTER_EXIT]); |
---|
| 1792 | + audit_filter_inodes(current, context); |
---|
| 1793 | + if (context->current_state == AUDIT_RECORD_CONTEXT) |
---|
| 1794 | + audit_log_exit(); |
---|
| 1795 | + } |
---|
1579 | 1796 | |
---|
1580 | 1797 | context->in_syscall = 0; |
---|
1581 | 1798 | context->prio = context->state == AUDIT_RECORD_CONTEXT ? ~0ULL : 0; |
---|
1582 | 1799 | |
---|
1583 | | - if (!list_empty(&context->killed_trees)) |
---|
1584 | | - audit_kill_trees(&context->killed_trees); |
---|
1585 | | - |
---|
| 1800 | + audit_free_module(context); |
---|
1586 | 1801 | audit_free_names(context); |
---|
1587 | 1802 | unroll_tree_refs(context, NULL, 0); |
---|
1588 | 1803 | audit_free_aux(context); |
---|
.. | .. |
---|
1597 | 1812 | kfree(context->filterkey); |
---|
1598 | 1813 | context->filterkey = NULL; |
---|
1599 | 1814 | } |
---|
1600 | | - audit_set_context(current, context); |
---|
1601 | 1815 | } |
---|
1602 | 1816 | |
---|
1603 | 1817 | static inline void handle_one(const struct inode *inode) |
---|
1604 | 1818 | { |
---|
1605 | | -#ifdef CONFIG_AUDIT_TREE |
---|
1606 | 1819 | struct audit_context *context; |
---|
1607 | 1820 | struct audit_tree_refs *p; |
---|
1608 | 1821 | struct audit_chunk *chunk; |
---|
.. | .. |
---|
1627 | 1840 | return; |
---|
1628 | 1841 | } |
---|
1629 | 1842 | put_tree_ref(context, chunk); |
---|
1630 | | -#endif |
---|
1631 | 1843 | } |
---|
1632 | 1844 | |
---|
1633 | 1845 | static void handle_path(const struct dentry *dentry) |
---|
1634 | 1846 | { |
---|
1635 | | -#ifdef CONFIG_AUDIT_TREE |
---|
1636 | 1847 | struct audit_context *context; |
---|
1637 | 1848 | struct audit_tree_refs *p; |
---|
1638 | 1849 | const struct dentry *d, *parent; |
---|
.. | .. |
---|
1685 | 1896 | return; |
---|
1686 | 1897 | } |
---|
1687 | 1898 | rcu_read_unlock(); |
---|
1688 | | -#endif |
---|
1689 | 1899 | } |
---|
1690 | 1900 | |
---|
1691 | 1901 | static struct audit_names *audit_alloc_name(struct audit_context *context, |
---|
.. | .. |
---|
1736 | 1946 | return NULL; |
---|
1737 | 1947 | } |
---|
1738 | 1948 | |
---|
| 1949 | +inline void _audit_getcwd(struct audit_context *context) |
---|
| 1950 | +{ |
---|
| 1951 | + if (!context->pwd.dentry) |
---|
| 1952 | + get_fs_pwd(current->fs, &context->pwd); |
---|
| 1953 | +} |
---|
| 1954 | + |
---|
| 1955 | +void __audit_getcwd(void) |
---|
| 1956 | +{ |
---|
| 1957 | + struct audit_context *context = audit_context(); |
---|
| 1958 | + |
---|
| 1959 | + if (context->in_syscall) |
---|
| 1960 | + _audit_getcwd(context); |
---|
| 1961 | +} |
---|
| 1962 | + |
---|
1739 | 1963 | /** |
---|
1740 | 1964 | * __audit_getname - add a name to the list |
---|
1741 | 1965 | * @name: name to add |
---|
.. | .. |
---|
1760 | 1984 | name->aname = n; |
---|
1761 | 1985 | name->refcnt++; |
---|
1762 | 1986 | |
---|
1763 | | - if (!context->pwd.dentry) |
---|
1764 | | - get_fs_pwd(current->fs, &context->pwd); |
---|
| 1987 | + _audit_getcwd(context); |
---|
| 1988 | +} |
---|
| 1989 | + |
---|
| 1990 | +static inline int audit_copy_fcaps(struct audit_names *name, |
---|
| 1991 | + const struct dentry *dentry) |
---|
| 1992 | +{ |
---|
| 1993 | + struct cpu_vfs_cap_data caps; |
---|
| 1994 | + int rc; |
---|
| 1995 | + |
---|
| 1996 | + if (!dentry) |
---|
| 1997 | + return 0; |
---|
| 1998 | + |
---|
| 1999 | + rc = get_vfs_caps_from_disk(dentry, &caps); |
---|
| 2000 | + if (rc) |
---|
| 2001 | + return rc; |
---|
| 2002 | + |
---|
| 2003 | + name->fcap.permitted = caps.permitted; |
---|
| 2004 | + name->fcap.inheritable = caps.inheritable; |
---|
| 2005 | + name->fcap.fE = !!(caps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); |
---|
| 2006 | + name->fcap.rootid = caps.rootid; |
---|
| 2007 | + name->fcap_ver = (caps.magic_etc & VFS_CAP_REVISION_MASK) >> |
---|
| 2008 | + VFS_CAP_REVISION_SHIFT; |
---|
| 2009 | + |
---|
| 2010 | + return 0; |
---|
| 2011 | +} |
---|
| 2012 | + |
---|
| 2013 | +/* Copy inode data into an audit_names. */ |
---|
| 2014 | +static void audit_copy_inode(struct audit_names *name, |
---|
| 2015 | + const struct dentry *dentry, |
---|
| 2016 | + struct inode *inode, unsigned int flags) |
---|
| 2017 | +{ |
---|
| 2018 | + name->ino = inode->i_ino; |
---|
| 2019 | + name->dev = inode->i_sb->s_dev; |
---|
| 2020 | + name->mode = inode->i_mode; |
---|
| 2021 | + name->uid = inode->i_uid; |
---|
| 2022 | + name->gid = inode->i_gid; |
---|
| 2023 | + name->rdev = inode->i_rdev; |
---|
| 2024 | + security_inode_getsecid(inode, &name->osid); |
---|
| 2025 | + if (flags & AUDIT_INODE_NOEVAL) { |
---|
| 2026 | + name->fcap_ver = -1; |
---|
| 2027 | + return; |
---|
| 2028 | + } |
---|
| 2029 | + audit_copy_fcaps(name, dentry); |
---|
1765 | 2030 | } |
---|
1766 | 2031 | |
---|
1767 | 2032 | /** |
---|
.. | .. |
---|
1777 | 2042 | struct inode *inode = d_backing_inode(dentry); |
---|
1778 | 2043 | struct audit_names *n; |
---|
1779 | 2044 | bool parent = flags & AUDIT_INODE_PARENT; |
---|
| 2045 | + struct audit_entry *e; |
---|
| 2046 | + struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS]; |
---|
| 2047 | + int i; |
---|
1780 | 2048 | |
---|
1781 | 2049 | if (!context->in_syscall) |
---|
1782 | 2050 | return; |
---|
| 2051 | + |
---|
| 2052 | + rcu_read_lock(); |
---|
| 2053 | + list_for_each_entry_rcu(e, list, list) { |
---|
| 2054 | + for (i = 0; i < e->rule.field_count; i++) { |
---|
| 2055 | + struct audit_field *f = &e->rule.fields[i]; |
---|
| 2056 | + |
---|
| 2057 | + if (f->type == AUDIT_FSTYPE |
---|
| 2058 | + && audit_comparator(inode->i_sb->s_magic, |
---|
| 2059 | + f->op, f->val) |
---|
| 2060 | + && e->rule.action == AUDIT_NEVER) { |
---|
| 2061 | + rcu_read_unlock(); |
---|
| 2062 | + return; |
---|
| 2063 | + } |
---|
| 2064 | + } |
---|
| 2065 | + } |
---|
| 2066 | + rcu_read_unlock(); |
---|
1783 | 2067 | |
---|
1784 | 2068 | if (!name) |
---|
1785 | 2069 | goto out_alloc; |
---|
.. | .. |
---|
1846 | 2130 | n->type = AUDIT_TYPE_NORMAL; |
---|
1847 | 2131 | } |
---|
1848 | 2132 | handle_path(dentry); |
---|
1849 | | - audit_copy_inode(n, dentry, inode); |
---|
| 2133 | + audit_copy_inode(n, dentry, inode, flags & AUDIT_INODE_NOEVAL); |
---|
1850 | 2134 | } |
---|
1851 | 2135 | |
---|
1852 | 2136 | void __audit_file(const struct file *file) |
---|
.. | .. |
---|
1874 | 2158 | { |
---|
1875 | 2159 | struct audit_context *context = audit_context(); |
---|
1876 | 2160 | struct inode *inode = d_backing_inode(dentry); |
---|
1877 | | - const char *dname = dentry->d_name.name; |
---|
| 2161 | + const struct qstr *dname = &dentry->d_name; |
---|
1878 | 2162 | struct audit_names *n, *found_parent = NULL, *found_child = NULL; |
---|
1879 | 2163 | struct audit_entry *e; |
---|
1880 | 2164 | struct list_head *list = &audit_filter_list[AUDIT_FILTER_FS]; |
---|
.. | .. |
---|
1884 | 2168 | return; |
---|
1885 | 2169 | |
---|
1886 | 2170 | rcu_read_lock(); |
---|
1887 | | - if (!list_empty(list)) { |
---|
1888 | | - list_for_each_entry_rcu(e, list, list) { |
---|
1889 | | - for (i = 0; i < e->rule.field_count; i++) { |
---|
1890 | | - struct audit_field *f = &e->rule.fields[i]; |
---|
| 2171 | + list_for_each_entry_rcu(e, list, list) { |
---|
| 2172 | + for (i = 0; i < e->rule.field_count; i++) { |
---|
| 2173 | + struct audit_field *f = &e->rule.fields[i]; |
---|
1891 | 2174 | |
---|
1892 | | - if (f->type == AUDIT_FSTYPE) { |
---|
1893 | | - if (audit_comparator(parent->i_sb->s_magic, |
---|
1894 | | - f->op, f->val)) { |
---|
1895 | | - if (e->rule.action == AUDIT_NEVER) { |
---|
1896 | | - rcu_read_unlock(); |
---|
1897 | | - return; |
---|
1898 | | - } |
---|
1899 | | - } |
---|
1900 | | - } |
---|
| 2175 | + if (f->type == AUDIT_FSTYPE |
---|
| 2176 | + && audit_comparator(parent->i_sb->s_magic, |
---|
| 2177 | + f->op, f->val) |
---|
| 2178 | + && e->rule.action == AUDIT_NEVER) { |
---|
| 2179 | + rcu_read_unlock(); |
---|
| 2180 | + return; |
---|
1901 | 2181 | } |
---|
1902 | 2182 | } |
---|
1903 | 2183 | } |
---|
.. | .. |
---|
1923 | 2203 | } |
---|
1924 | 2204 | } |
---|
1925 | 2205 | |
---|
| 2206 | + cond_resched(); |
---|
| 2207 | + |
---|
1926 | 2208 | /* is there a matching child entry? */ |
---|
1927 | 2209 | list_for_each_entry(n, &context->names_list, list) { |
---|
1928 | 2210 | /* can only match entries that have a name */ |
---|
.. | .. |
---|
1930 | 2212 | (n->type != type && n->type != AUDIT_TYPE_UNKNOWN)) |
---|
1931 | 2213 | continue; |
---|
1932 | 2214 | |
---|
1933 | | - if (!strcmp(dname, n->name->name) || |
---|
| 2215 | + if (!strcmp(dname->name, n->name->name) || |
---|
1934 | 2216 | !audit_compare_dname_path(dname, n->name->name, |
---|
1935 | 2217 | found_parent ? |
---|
1936 | 2218 | found_parent->name_len : |
---|
.. | .. |
---|
1947 | 2229 | n = audit_alloc_name(context, AUDIT_TYPE_PARENT); |
---|
1948 | 2230 | if (!n) |
---|
1949 | 2231 | return; |
---|
1950 | | - audit_copy_inode(n, NULL, parent); |
---|
| 2232 | + audit_copy_inode(n, NULL, parent, 0); |
---|
1951 | 2233 | } |
---|
1952 | 2234 | |
---|
1953 | 2235 | if (!found_child) { |
---|
.. | .. |
---|
1966 | 2248 | } |
---|
1967 | 2249 | |
---|
1968 | 2250 | if (inode) |
---|
1969 | | - audit_copy_inode(found_child, dentry, inode); |
---|
| 2251 | + audit_copy_inode(found_child, dentry, inode, 0); |
---|
1970 | 2252 | else |
---|
1971 | 2253 | found_child->ino = AUDIT_INO_UNSET; |
---|
1972 | 2254 | } |
---|
.. | .. |
---|
1995 | 2277 | ctx->current_state = AUDIT_RECORD_CONTEXT; |
---|
1996 | 2278 | } |
---|
1997 | 2279 | return 1; |
---|
1998 | | -} |
---|
1999 | | - |
---|
2000 | | -/* global counter which is incremented every time something logs in */ |
---|
2001 | | -static atomic_t session_id = ATOMIC_INIT(0); |
---|
2002 | | - |
---|
2003 | | -static int audit_set_loginuid_perm(kuid_t loginuid) |
---|
2004 | | -{ |
---|
2005 | | - /* if we are unset, we don't need privs */ |
---|
2006 | | - if (!audit_loginuid_set(current)) |
---|
2007 | | - return 0; |
---|
2008 | | - /* if AUDIT_FEATURE_LOGINUID_IMMUTABLE means never ever allow a change*/ |
---|
2009 | | - if (is_audit_feature_set(AUDIT_FEATURE_LOGINUID_IMMUTABLE)) |
---|
2010 | | - return -EPERM; |
---|
2011 | | - /* it is set, you need permission */ |
---|
2012 | | - if (!capable(CAP_AUDIT_CONTROL)) |
---|
2013 | | - return -EPERM; |
---|
2014 | | - /* reject if this is not an unset and we don't allow that */ |
---|
2015 | | - if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid)) |
---|
2016 | | - return -EPERM; |
---|
2017 | | - return 0; |
---|
2018 | | -} |
---|
2019 | | - |
---|
2020 | | -static void audit_log_set_loginuid(kuid_t koldloginuid, kuid_t kloginuid, |
---|
2021 | | - unsigned int oldsessionid, unsigned int sessionid, |
---|
2022 | | - int rc) |
---|
2023 | | -{ |
---|
2024 | | - struct audit_buffer *ab; |
---|
2025 | | - uid_t uid, oldloginuid, loginuid; |
---|
2026 | | - struct tty_struct *tty; |
---|
2027 | | - |
---|
2028 | | - if (!audit_enabled) |
---|
2029 | | - return; |
---|
2030 | | - |
---|
2031 | | - ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_LOGIN); |
---|
2032 | | - if (!ab) |
---|
2033 | | - return; |
---|
2034 | | - |
---|
2035 | | - uid = from_kuid(&init_user_ns, task_uid(current)); |
---|
2036 | | - oldloginuid = from_kuid(&init_user_ns, koldloginuid); |
---|
2037 | | - loginuid = from_kuid(&init_user_ns, kloginuid), |
---|
2038 | | - tty = audit_get_tty(current); |
---|
2039 | | - |
---|
2040 | | - audit_log_format(ab, "pid=%d uid=%u", task_tgid_nr(current), uid); |
---|
2041 | | - audit_log_task_context(ab); |
---|
2042 | | - audit_log_format(ab, " old-auid=%u auid=%u tty=%s old-ses=%u ses=%u res=%d", |
---|
2043 | | - oldloginuid, loginuid, tty ? tty_name(tty) : "(none)", |
---|
2044 | | - oldsessionid, sessionid, !rc); |
---|
2045 | | - audit_put_tty(tty); |
---|
2046 | | - audit_log_end(ab); |
---|
2047 | | -} |
---|
2048 | | - |
---|
2049 | | -/** |
---|
2050 | | - * audit_set_loginuid - set current task's audit_context loginuid |
---|
2051 | | - * @loginuid: loginuid value |
---|
2052 | | - * |
---|
2053 | | - * Returns 0. |
---|
2054 | | - * |
---|
2055 | | - * Called (set) from fs/proc/base.c::proc_loginuid_write(). |
---|
2056 | | - */ |
---|
2057 | | -int audit_set_loginuid(kuid_t loginuid) |
---|
2058 | | -{ |
---|
2059 | | - struct task_struct *task = current; |
---|
2060 | | - unsigned int oldsessionid, sessionid = AUDIT_SID_UNSET; |
---|
2061 | | - kuid_t oldloginuid; |
---|
2062 | | - int rc; |
---|
2063 | | - |
---|
2064 | | - oldloginuid = audit_get_loginuid(current); |
---|
2065 | | - oldsessionid = audit_get_sessionid(current); |
---|
2066 | | - |
---|
2067 | | - rc = audit_set_loginuid_perm(loginuid); |
---|
2068 | | - if (rc) |
---|
2069 | | - goto out; |
---|
2070 | | - |
---|
2071 | | - /* are we setting or clearing? */ |
---|
2072 | | - if (uid_valid(loginuid)) { |
---|
2073 | | - sessionid = (unsigned int)atomic_inc_return(&session_id); |
---|
2074 | | - if (unlikely(sessionid == AUDIT_SID_UNSET)) |
---|
2075 | | - sessionid = (unsigned int)atomic_inc_return(&session_id); |
---|
2076 | | - } |
---|
2077 | | - |
---|
2078 | | - task->sessionid = sessionid; |
---|
2079 | | - task->loginuid = loginuid; |
---|
2080 | | -out: |
---|
2081 | | - audit_log_set_loginuid(oldloginuid, loginuid, oldsessionid, sessionid, rc); |
---|
2082 | | - return rc; |
---|
2083 | 2280 | } |
---|
2084 | 2281 | |
---|
2085 | 2282 | /** |
---|
.. | .. |
---|
2276 | 2473 | } |
---|
2277 | 2474 | |
---|
2278 | 2475 | /** |
---|
2279 | | - * audit_signal_info - record signal info for shutting down audit subsystem |
---|
2280 | | - * @sig: signal value |
---|
| 2476 | + * audit_signal_info_syscall - record signal info for syscalls |
---|
2281 | 2477 | * @t: task being signaled |
---|
2282 | 2478 | * |
---|
2283 | 2479 | * If the audit subsystem is being terminated, record the task (pid) |
---|
2284 | 2480 | * and uid that is doing that. |
---|
2285 | 2481 | */ |
---|
2286 | | -int audit_signal_info(int sig, struct task_struct *t) |
---|
| 2482 | +int audit_signal_info_syscall(struct task_struct *t) |
---|
2287 | 2483 | { |
---|
2288 | 2484 | struct audit_aux_data_pids *axp; |
---|
2289 | 2485 | struct audit_context *ctx = audit_context(); |
---|
2290 | | - kuid_t uid = current_uid(), auid, t_uid = task_uid(t); |
---|
2291 | | - |
---|
2292 | | - if (auditd_test_task(t) && |
---|
2293 | | - (sig == SIGTERM || sig == SIGHUP || |
---|
2294 | | - sig == SIGUSR1 || sig == SIGUSR2)) { |
---|
2295 | | - audit_sig_pid = task_tgid_nr(current); |
---|
2296 | | - auid = audit_get_loginuid(current); |
---|
2297 | | - if (uid_valid(auid)) |
---|
2298 | | - audit_sig_uid = auid; |
---|
2299 | | - else |
---|
2300 | | - audit_sig_uid = uid; |
---|
2301 | | - security_task_getsecid(current, &audit_sig_sid); |
---|
2302 | | - } |
---|
| 2486 | + kuid_t t_uid = task_uid(t); |
---|
2303 | 2487 | |
---|
2304 | 2488 | if (!audit_signals || audit_dummy_context()) |
---|
2305 | 2489 | return 0; |
---|
.. | .. |
---|
2370 | 2554 | ax->fcap.permitted = vcaps.permitted; |
---|
2371 | 2555 | ax->fcap.inheritable = vcaps.inheritable; |
---|
2372 | 2556 | ax->fcap.fE = !!(vcaps.magic_etc & VFS_CAP_FLAGS_EFFECTIVE); |
---|
| 2557 | + ax->fcap.rootid = vcaps.rootid; |
---|
2373 | 2558 | ax->fcap_ver = (vcaps.magic_etc & VFS_CAP_REVISION_MASK) >> VFS_CAP_REVISION_SHIFT; |
---|
2374 | 2559 | |
---|
2375 | 2560 | ax->old_pcap.permitted = old->cap_permitted; |
---|
.. | .. |
---|
2426 | 2611 | audit_log(audit_context(), GFP_KERNEL, |
---|
2427 | 2612 | AUDIT_FANOTIFY, "resp=%u", response); |
---|
2428 | 2613 | } |
---|
| 2614 | + |
---|
| 2615 | +void __audit_tk_injoffset(struct timespec64 offset) |
---|
| 2616 | +{ |
---|
| 2617 | + struct audit_context *context = audit_context(); |
---|
| 2618 | + |
---|
| 2619 | + /* only set type if not already set by NTP */ |
---|
| 2620 | + if (!context->type) |
---|
| 2621 | + context->type = AUDIT_TIME_INJOFFSET; |
---|
| 2622 | + memcpy(&context->time.tk_injoffset, &offset, sizeof(offset)); |
---|
| 2623 | +} |
---|
| 2624 | + |
---|
| 2625 | +void __audit_ntp_log(const struct audit_ntp_data *ad) |
---|
| 2626 | +{ |
---|
| 2627 | + struct audit_context *context = audit_context(); |
---|
| 2628 | + int type; |
---|
| 2629 | + |
---|
| 2630 | + for (type = 0; type < AUDIT_NTP_NVALS; type++) |
---|
| 2631 | + if (ad->vals[type].newval != ad->vals[type].oldval) { |
---|
| 2632 | + /* unconditionally set type, overwriting TK */ |
---|
| 2633 | + context->type = AUDIT_TIME_ADJNTPVAL; |
---|
| 2634 | + memcpy(&context->time.ntp_data, ad, sizeof(*ad)); |
---|
| 2635 | + break; |
---|
| 2636 | + } |
---|
| 2637 | +} |
---|
| 2638 | + |
---|
| 2639 | +void __audit_log_nfcfg(const char *name, u8 af, unsigned int nentries, |
---|
| 2640 | + enum audit_nfcfgop op, gfp_t gfp) |
---|
| 2641 | +{ |
---|
| 2642 | + struct audit_buffer *ab; |
---|
| 2643 | + char comm[sizeof(current->comm)]; |
---|
| 2644 | + |
---|
| 2645 | + ab = audit_log_start(audit_context(), gfp, AUDIT_NETFILTER_CFG); |
---|
| 2646 | + if (!ab) |
---|
| 2647 | + return; |
---|
| 2648 | + audit_log_format(ab, "table=%s family=%u entries=%u op=%s", |
---|
| 2649 | + name, af, nentries, audit_nfcfgs[op].s); |
---|
| 2650 | + |
---|
| 2651 | + audit_log_format(ab, " pid=%u", task_pid_nr(current)); |
---|
| 2652 | + audit_log_task_context(ab); /* subj= */ |
---|
| 2653 | + audit_log_format(ab, " comm="); |
---|
| 2654 | + audit_log_untrustedstring(ab, get_task_comm(comm, current)); |
---|
| 2655 | + audit_log_end(ab); |
---|
| 2656 | +} |
---|
| 2657 | +EXPORT_SYMBOL_GPL(__audit_log_nfcfg); |
---|
2429 | 2658 | |
---|
2430 | 2659 | static void audit_log_task(struct audit_buffer *ab) |
---|
2431 | 2660 | { |
---|
.. | .. |
---|
2495 | 2724 | return; |
---|
2496 | 2725 | audit_log_task(ab); |
---|
2497 | 2726 | audit_log_format(ab, " sig=%ld arch=%x syscall=%ld compat=%d ip=0x%lx code=0x%x", |
---|
2498 | | - signr, syscall_get_arch(), syscall, |
---|
| 2727 | + signr, syscall_get_arch(current), syscall, |
---|
2499 | 2728 | in_compat_syscall(), KSTK_EIP(current), code); |
---|
2500 | 2729 | audit_log_end(ab); |
---|
2501 | 2730 | } |
---|
.. | .. |
---|
2513 | 2742 | if (unlikely(!ab)) |
---|
2514 | 2743 | return; |
---|
2515 | 2744 | |
---|
2516 | | - audit_log_format(ab, "op=seccomp-logging"); |
---|
2517 | | - audit_log_format(ab, " actions=%s", names); |
---|
2518 | | - audit_log_format(ab, " old-actions=%s", old_names); |
---|
2519 | | - audit_log_format(ab, " res=%d", res); |
---|
| 2745 | + audit_log_format(ab, |
---|
| 2746 | + "op=seccomp-logging actions=%s old-actions=%s res=%d", |
---|
| 2747 | + names, old_names, res); |
---|
2520 | 2748 | audit_log_end(ab); |
---|
2521 | 2749 | } |
---|
2522 | 2750 | |
---|