1 // SPDX-License-Identifier: GPL-2.0-only
3 * AppArmor security module
5 * This file contains AppArmor network mediation
7 * Copyright (C) 1998-2008 Novell/SUSE
8 * Copyright 2009-2017 Canonical Ltd.
11 #include "include/apparmor.h"
12 #include "include/audit.h"
13 #include "include/cred.h"
14 #include "include/label.h"
15 #include "include/net.h"
16 #include "include/policy.h"
17 #include "include/secid.h"
19 #include "net_names.h"
22 struct aa_sfs_entry aa_sfs_entry_network
[] = {
23 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK
),
27 static const char * const net_mask_names
[] = {
70 /* audit callback for net specific fields */
71 void audit_net_cb(struct audit_buffer
*ab
, void *va
)
73 struct common_audit_data
*sa
= va
;
74 struct apparmor_audit_data
*ad
= aad(sa
);
76 if (address_family_names
[sa
->u
.net
->family
])
77 audit_log_format(ab
, " family=\"%s\"",
78 address_family_names
[sa
->u
.net
->family
]);
80 audit_log_format(ab
, " family=\"unknown(%d)\"",
82 if (sock_type_names
[ad
->net
.type
])
83 audit_log_format(ab
, " sock_type=\"%s\"",
84 sock_type_names
[ad
->net
.type
]);
86 audit_log_format(ab
, " sock_type=\"unknown(%d)\"",
88 audit_log_format(ab
, " protocol=%d", ad
->net
.protocol
);
90 if (ad
->request
& NET_PERMS_MASK
) {
91 audit_log_format(ab
, " requested_mask=");
92 aa_audit_perm_mask(ab
, ad
->request
, NULL
, 0,
93 net_mask_names
, NET_PERMS_MASK
);
95 if (ad
->denied
& NET_PERMS_MASK
) {
96 audit_log_format(ab
, " denied_mask=");
97 aa_audit_perm_mask(ab
, ad
->denied
, NULL
, 0,
98 net_mask_names
, NET_PERMS_MASK
);
102 audit_log_format(ab
, " peer=");
103 aa_label_xaudit(ab
, labels_ns(ad
->subj_label
), ad
->peer
,
104 FLAGS_NONE
, GFP_ATOMIC
);
108 /* Generic af perm */
109 int aa_profile_af_perm(struct aa_profile
*profile
,
110 struct apparmor_audit_data
*ad
, u32 request
, u16 family
,
113 struct aa_ruleset
*rules
= list_first_entry(&profile
->rules
,
114 typeof(*rules
), list
);
115 struct aa_perms perms
= { };
119 AA_BUG(family
>= AF_MAX
);
120 AA_BUG(type
< 0 || type
>= SOCK_MAX
);
122 if (profile_unconfined(profile
))
124 state
= RULE_MEDIATES(rules
, AA_CLASS_NET
);
128 buffer
[0] = cpu_to_be16(family
);
129 buffer
[1] = cpu_to_be16((u16
) type
);
130 state
= aa_dfa_match_len(rules
->policy
->dfa
, state
, (char *) &buffer
,
132 perms
= *aa_lookup_perms(rules
->policy
, state
);
133 aa_apply_modes_to_perms(profile
, &perms
);
135 return aa_check_perms(profile
, &perms
, request
, ad
, audit_net_cb
);
138 int aa_af_perm(const struct cred
*subj_cred
, struct aa_label
*label
,
139 const char *op
, u32 request
, u16 family
, int type
, int protocol
)
141 struct aa_profile
*profile
;
142 DEFINE_AUDIT_NET(ad
, op
, NULL
, family
, type
, protocol
);
144 return fn_for_each_confined(label
, profile
,
145 aa_profile_af_perm(profile
, &ad
, request
, family
,
149 static int aa_label_sk_perm(const struct cred
*subj_cred
,
150 struct aa_label
*label
,
151 const char *op
, u32 request
,
154 struct aa_sk_ctx
*ctx
= aa_sock(sk
);
160 if (ctx
->label
!= kernel_t
&& !unconfined(label
)) {
161 struct aa_profile
*profile
;
162 DEFINE_AUDIT_SK(ad
, op
, sk
);
164 ad
.subj_cred
= subj_cred
;
165 error
= fn_for_each_confined(label
, profile
,
166 aa_profile_af_sk_perm(profile
, &ad
, request
, sk
));
172 int aa_sk_perm(const char *op
, u32 request
, struct sock
*sk
)
174 struct aa_label
*label
;
178 AA_BUG(in_interrupt());
180 /* TODO: switch to begin_current_label ???? */
181 label
= begin_current_label_crit_section();
182 error
= aa_label_sk_perm(current_cred(), label
, op
, request
, sk
);
183 end_current_label_crit_section(label
);
189 int aa_sock_file_perm(const struct cred
*subj_cred
, struct aa_label
*label
,
190 const char *op
, u32 request
, struct socket
*sock
)
196 return aa_label_sk_perm(subj_cred
, label
, op
, request
, sock
->sk
);
199 #ifdef CONFIG_NETWORK_SECMARK
200 static int apparmor_secmark_init(struct aa_secmark
*secmark
)
202 struct aa_label
*label
;
204 if (secmark
->label
[0] == '*') {
205 secmark
->secid
= AA_SECID_WILDCARD
;
209 label
= aa_label_strn_parse(&root_ns
->unconfined
->label
,
210 secmark
->label
, strlen(secmark
->label
),
211 GFP_ATOMIC
, false, false);
214 return PTR_ERR(label
);
216 secmark
->secid
= label
->secid
;
221 static int aa_secmark_perm(struct aa_profile
*profile
, u32 request
, u32 secid
,
222 struct apparmor_audit_data
*ad
)
225 struct aa_perms perms
= { };
226 struct aa_ruleset
*rules
= list_first_entry(&profile
->rules
,
227 typeof(*rules
), list
);
229 if (rules
->secmark_count
== 0)
232 for (i
= 0; i
< rules
->secmark_count
; i
++) {
233 if (!rules
->secmark
[i
].secid
) {
234 ret
= apparmor_secmark_init(&rules
->secmark
[i
]);
239 if (rules
->secmark
[i
].secid
== secid
||
240 rules
->secmark
[i
].secid
== AA_SECID_WILDCARD
) {
241 if (rules
->secmark
[i
].deny
)
242 perms
.deny
= ALL_PERMS_MASK
;
244 perms
.allow
= ALL_PERMS_MASK
;
246 if (rules
->secmark
[i
].audit
)
247 perms
.audit
= ALL_PERMS_MASK
;
251 aa_apply_modes_to_perms(profile
, &perms
);
253 return aa_check_perms(profile
, &perms
, request
, ad
, audit_net_cb
);
256 int apparmor_secmark_check(struct aa_label
*label
, char *op
, u32 request
,
257 u32 secid
, const struct sock
*sk
)
259 struct aa_profile
*profile
;
260 DEFINE_AUDIT_SK(ad
, op
, sk
);
262 return fn_for_each_confined(label
, profile
,
263 aa_secmark_perm(profile
, request
, secid
,