diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-11-03 09:48:17 -1000 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-11-03 09:48:17 -1000 |
commit | 6bdfe2d88b9ff8b0cce32ce87cd47c0e9d665f48 (patch) | |
tree | a8a43da53fa84ce69adfb252ddbdaa38fc15e303 /security/apparmor/net.c | |
parent | 136cc1e1f5be75f57f1e0404b94ee1c8792cb07d (diff) | |
parent | 6cede10161be00d129a24e8b84c2674785a32cf8 (diff) |
Merge tag 'apparmor-pr-2023-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor
Pull apparmor updates from John Johansen:
"This adds initial support for mediating io_uring and userns creation.
Adds a new restriction that tightens the use of change_profile, and a
couple of optimizations to reduce performance bottle necks that have
been found when retrieving the current task's secid and allocating
work buffers.
The majority of the patch set continues cleaning up and simplifying
the code (fixing comments, removing now dead functions, and macros
etc). Finally there are 4 bug fixes, with the regression fix having
had a couple months of testing.
Features:
- optimize retrieving current task secid
- add base io_uring mediation
- add base userns mediation
- improve buffer allocation
- allow restricting unprivilege change_profile
Cleanups:
- Fix kernel doc comments
- remove unused declarations
- remove unused functions
- remove unneeded #ifdef
- remove unused macros
- mark fns static
- cleanup fn with unused return values
- cleanup audit data
- pass cred through to audit data
- refcount the pdb instead of using duplicates
- make SK_CTX macro an inline fn
- some comment cleanups
Bug fixes:
- fix regression in mount mediation
- fix invalid refenece
- use passed in gfp flags
- advertise avaiability of extended perms and disconnected.path"
* tag 'apparmor-pr-2023-11-03' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (39 commits)
apparmor: Fix some kernel-doc comments
apparmor: Fix one kernel-doc comment
apparmor: Fix some kernel-doc comments
apparmor: mark new functions static
apparmor: Fix regression in mount mediation
apparmor: cache buffers on percpu list if there is lock contention
apparmor: add io_uring mediation
apparmor: add user namespace creation mediation
apparmor: allow restricting unprivileged change_profile
apparmor: advertise disconnected.path is available
apparmor: refcount the pdb
apparmor: provide separate audit messages for file and policy checks
apparmor: pass cred through to audit info.
apparmor: rename audit_data->label to audit_data->subj_label
apparmor: combine common_audit_data and apparmor_audit_data
apparmor: rename SK_CTX() to aa_sock and make it an inline fn
apparmor: Optimize retrieving current task secid
apparmor: remove unused functions in policy_ns.c/.h
apparmor: remove unneeded #ifdef in decompress_zstd()
apparmor: fix invalid reference on profile->disconnected
...
Diffstat (limited to 'security/apparmor/net.c')
-rw-r--r-- | security/apparmor/net.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/security/apparmor/net.c b/security/apparmor/net.c index 788be1609a86..87e934b2b548 100644 --- a/security/apparmor/net.c +++ b/security/apparmor/net.c @@ -71,6 +71,7 @@ static const char * const net_mask_names[] = { void audit_net_cb(struct audit_buffer *ab, void *va) { struct common_audit_data *sa = va; + struct apparmor_audit_data *ad = aad(sa); if (address_family_names[sa->u.net->family]) audit_log_format(ab, " family=\"%s\"", @@ -78,35 +79,36 @@ void audit_net_cb(struct audit_buffer *ab, void *va) else audit_log_format(ab, " family=\"unknown(%d)\"", sa->u.net->family); - if (sock_type_names[aad(sa)->net.type]) + if (sock_type_names[ad->net.type]) audit_log_format(ab, " sock_type=\"%s\"", - sock_type_names[aad(sa)->net.type]); + sock_type_names[ad->net.type]); else audit_log_format(ab, " sock_type=\"unknown(%d)\"", - aad(sa)->net.type); - audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); + ad->net.type); + audit_log_format(ab, " protocol=%d", ad->net.protocol); - if (aad(sa)->request & NET_PERMS_MASK) { + if (ad->request & NET_PERMS_MASK) { audit_log_format(ab, " requested_mask="); - aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, + aa_audit_perm_mask(ab, ad->request, NULL, 0, net_mask_names, NET_PERMS_MASK); - if (aad(sa)->denied & NET_PERMS_MASK) { + if (ad->denied & NET_PERMS_MASK) { audit_log_format(ab, " denied_mask="); - aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, + aa_audit_perm_mask(ab, ad->denied, NULL, 0, net_mask_names, NET_PERMS_MASK); } } - if (aad(sa)->peer) { + if (ad->peer) { audit_log_format(ab, " peer="); - aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, + aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, FLAGS_NONE, GFP_ATOMIC); } } /* Generic af perm */ -int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, - u32 request, u16 family, int type) +int aa_profile_af_perm(struct aa_profile *profile, + struct apparmor_audit_data *ad, u32 request, u16 family, + int type) { struct aa_ruleset *rules = list_first_entry(&profile->rules, typeof(*rules), list); @@ -125,26 +127,28 @@ int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, buffer[0] = cpu_to_be16(family); buffer[1] = cpu_to_be16((u16) type); - state = aa_dfa_match_len(rules->policy.dfa, state, (char *) &buffer, + state = aa_dfa_match_len(rules->policy->dfa, state, (char *) &buffer, 4); - perms = *aa_lookup_perms(&rules->policy, state); + perms = *aa_lookup_perms(rules->policy, state); aa_apply_modes_to_perms(profile, &perms); - return aa_check_perms(profile, &perms, request, sa, audit_net_cb); + return aa_check_perms(profile, &perms, request, ad, audit_net_cb); } -int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, - int type, int protocol) +int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, + const char *op, u32 request, u16 family, int type, int protocol) { struct aa_profile *profile; - DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); + DEFINE_AUDIT_NET(ad, op, NULL, family, type, protocol); return fn_for_each_confined(label, profile, - aa_profile_af_perm(profile, &sa, request, family, + aa_profile_af_perm(profile, &ad, request, family, type)); } -static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, +static int aa_label_sk_perm(const struct cred *subj_cred, + struct aa_label *label, + const char *op, u32 request, struct sock *sk) { struct aa_sk_ctx *ctx = SK_CTX(sk); @@ -155,10 +159,11 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, if (ctx->label != kernel_t && !unconfined(label)) { struct aa_profile *profile; - DEFINE_AUDIT_SK(sa, op, sk); + DEFINE_AUDIT_SK(ad, op, sk); + ad.subj_cred = subj_cred; error = fn_for_each_confined(label, profile, - aa_profile_af_sk_perm(profile, &sa, request, sk)); + aa_profile_af_sk_perm(profile, &ad, request, sk)); } return error; @@ -174,21 +179,21 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk) /* TODO: switch to begin_current_label ???? */ label = begin_current_label_crit_section(); - error = aa_label_sk_perm(label, op, request, sk); + error = aa_label_sk_perm(current_cred(), label, op, request, sk); end_current_label_crit_section(label); return error; } -int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, - struct socket *sock) +int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, + const char *op, u32 request, struct socket *sock) { AA_BUG(!label); AA_BUG(!sock); AA_BUG(!sock->sk); - return aa_label_sk_perm(label, op, request, sock->sk); + return aa_label_sk_perm(subj_cred, label, op, request, sock->sk); } #ifdef CONFIG_NETWORK_SECMARK @@ -214,7 +219,7 @@ static int apparmor_secmark_init(struct aa_secmark *secmark) } static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, - struct common_audit_data *sa) + struct apparmor_audit_data *ad) { int i, ret; struct aa_perms perms = { }; @@ -245,17 +250,17 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, aa_apply_modes_to_perms(profile, &perms); - return aa_check_perms(profile, &perms, request, sa, audit_net_cb); + return aa_check_perms(profile, &perms, request, ad, audit_net_cb); } int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, u32 secid, const struct sock *sk) { struct aa_profile *profile; - DEFINE_AUDIT_SK(sa, op, sk); + DEFINE_AUDIT_SK(ad, op, sk); return fn_for_each_confined(label, profile, aa_secmark_perm(profile, request, secid, - &sa)); + &ad)); } #endif |