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/af_unix.h"
12 #include "include/apparmor.h"
13 #include "include/audit.h"
14 #include "include/cred.h"
15 #include "include/label.h"
16 #include "include/net.h"
17 #include "include/policy.h"
18 #include "include/secid.h"
20 #include "net_names.h"
23 struct aa_sfs_entry aa_sfs_entry_network
[] = {
24 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK
),
28 struct aa_sfs_entry aa_sfs_entry_network_compat
[] = {
29 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK
),
30 AA_SFS_FILE_BOOLEAN("af_unix", 1),
34 static const char * const net_mask_names
[] = {
76 static void audit_unix_addr(struct audit_buffer
*ab
, const char *str
,
77 struct sockaddr_un
*addr
, int addrlen
)
79 int len
= unix_addr_len(addrlen
);
81 if (!addr
|| len
<= 0) {
82 audit_log_format(ab
, " %s=none", str
);
83 } else if (addr
->sun_path
[0]) {
84 audit_log_format(ab
, " %s=", str
);
85 audit_log_untrustedstring(ab
, addr
->sun_path
);
87 audit_log_format(ab
, " %s=\"@", str
);
88 if (audit_string_contains_control(&addr
->sun_path
[1], len
- 1))
89 audit_log_n_hex(ab
, &addr
->sun_path
[1], len
- 1);
91 audit_log_format(ab
, "%.*s", len
- 1,
93 audit_log_format(ab
, "\"");
97 static void audit_unix_sk_addr(struct audit_buffer
*ab
, const char *str
,
100 struct unix_sock
*u
= unix_sk(sk
);
102 audit_unix_addr(ab
, str
, u
->addr
->name
, u
->addr
->len
);
104 audit_unix_addr(ab
, str
, NULL
, 0);
107 /* audit callback for net specific fields */
108 void audit_net_cb(struct audit_buffer
*ab
, void *va
)
110 struct common_audit_data
*sa
= va
;
112 audit_log_format(ab
, " family=");
113 if (address_family_names
[sa
->u
.net
->family
])
114 audit_log_string(ab
, address_family_names
[sa
->u
.net
->family
]);
116 audit_log_format(ab
, "\"unknown(%d)\"", sa
->u
.net
->family
);
117 audit_log_format(ab
, " sock_type=");
118 if (sock_type_names
[aad(sa
)->net
.type
])
119 audit_log_string(ab
, sock_type_names
[aad(sa
)->net
.type
]);
121 audit_log_format(ab
, "\"unknown(%d)\"", aad(sa
)->net
.type
);
122 audit_log_format(ab
, " protocol=%d", aad(sa
)->net
.protocol
);
124 if (aad(sa
)->request
& NET_PERMS_MASK
) {
125 audit_log_format(ab
, " requested_mask=");
126 aa_audit_perm_mask(ab
, aad(sa
)->request
, NULL
, 0,
127 net_mask_names
, NET_PERMS_MASK
);
129 if (aad(sa
)->denied
& NET_PERMS_MASK
) {
130 audit_log_format(ab
, " denied_mask=");
131 aa_audit_perm_mask(ab
, aad(sa
)->denied
, NULL
, 0,
132 net_mask_names
, NET_PERMS_MASK
);
135 if (sa
->u
.net
->family
== AF_UNIX
) {
136 if ((aad(sa
)->request
& ~NET_PEER_MASK
) && aad(sa
)->net
.addr
)
137 audit_unix_addr(ab
, "addr",
138 unix_addr(aad(sa
)->net
.addr
),
139 aad(sa
)->net
.addrlen
);
141 audit_unix_sk_addr(ab
, "addr", sa
->u
.net
->sk
);
142 if (aad(sa
)->request
& NET_PEER_MASK
) {
143 if (aad(sa
)->net
.addr
)
144 audit_unix_addr(ab
, "peer_addr",
145 unix_addr(aad(sa
)->net
.addr
),
146 aad(sa
)->net
.addrlen
);
148 audit_unix_sk_addr(ab
, "peer_addr",
149 aad(sa
)->net
.peer_sk
);
153 audit_log_format(ab
, " peer=");
154 aa_label_xaudit(ab
, labels_ns(aad(sa
)->label
), aad(sa
)->peer
,
155 FLAGS_NONE
, GFP_ATOMIC
);
159 /* Generic af perm */
160 int aa_profile_af_perm(struct aa_profile
*profile
, struct common_audit_data
*sa
,
161 u32 request
, u16 family
, int type
)
163 struct aa_perms perms
= { };
167 AA_BUG(family
>= AF_MAX
);
168 AA_BUG(type
< 0 || type
>= SOCK_MAX
);
170 if (profile_unconfined(profile
))
172 state
= PROFILE_MEDIATES(profile
, AA_CLASS_NET
);
176 buffer
[0] = cpu_to_be16(family
);
177 buffer
[1] = cpu_to_be16((u16
) type
);
178 state
= aa_dfa_match_len(profile
->policy
.dfa
, state
,
179 (char *) &buffer
, 4);
180 aa_compute_perms(profile
->policy
.dfa
, state
, &perms
);
181 } else if (profile
->net_compat
) {
182 /* 2.x socket mediation compat */
183 perms
.allow
= (profile
->net_compat
->allow
[family
] & (1 << type
)) ?
185 perms
.audit
= (profile
->net_compat
->audit
[family
] & (1 << type
)) ?
187 perms
.quiet
= (profile
->net_compat
->quiet
[family
] & (1 << type
)) ?
193 aa_apply_modes_to_perms(profile
, &perms
);
195 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
198 int aa_af_perm(struct aa_label
*label
, const char *op
, u32 request
, u16 family
,
199 int type
, int protocol
)
201 struct aa_profile
*profile
;
202 DEFINE_AUDIT_NET(sa
, op
, NULL
, family
, type
, protocol
);
204 return fn_for_each_confined(label
, profile
,
205 aa_profile_af_perm(profile
, &sa
, request
, family
,
209 static int aa_label_sk_perm(struct aa_label
*label
, const char *op
, u32 request
,
217 if (!unconfined(label
)) {
218 struct aa_profile
*profile
;
219 DEFINE_AUDIT_SK(sa
, op
, sk
);
221 error
= fn_for_each_confined(label
, profile
,
222 aa_profile_af_sk_perm(profile
, &sa
, request
, sk
));
228 int aa_sk_perm(const char *op
, u32 request
, struct sock
*sk
)
230 struct aa_label
*label
;
234 AA_BUG(in_interrupt());
236 /* TODO: switch to begin_current_label ???? */
237 label
= begin_current_label_crit_section();
238 error
= aa_label_sk_perm(label
, op
, request
, sk
);
239 end_current_label_crit_section(label
);
245 int aa_sock_file_perm(struct aa_label
*label
, const char *op
, u32 request
,
252 return af_select(sock
->sk
->sk_family
,
253 file_perm(label
, op
, request
, sock
),
254 aa_label_sk_perm(label
, op
, request
, sock
->sk
));
257 #ifdef CONFIG_NETWORK_SECMARK
258 static int apparmor_secmark_init(struct aa_secmark
*secmark
)
260 struct aa_label
*label
;
262 if (secmark
->label
[0] == '*') {
263 secmark
->secid
= AA_SECID_WILDCARD
;
267 label
= aa_label_strn_parse(&root_ns
->unconfined
->label
,
268 secmark
->label
, strlen(secmark
->label
),
269 GFP_ATOMIC
, false, false);
272 return PTR_ERR(label
);
274 secmark
->secid
= label
->secid
;
279 static int aa_secmark_perm(struct aa_profile
*profile
, u32 request
, u32 secid
,
280 struct common_audit_data
*sa
, struct sock
*sk
)
283 struct aa_perms perms
= { };
285 if (profile
->secmark_count
== 0)
288 for (i
= 0; i
< profile
->secmark_count
; i
++) {
289 if (!profile
->secmark
[i
].secid
) {
290 ret
= apparmor_secmark_init(&profile
->secmark
[i
]);
295 if (profile
->secmark
[i
].secid
== secid
||
296 profile
->secmark
[i
].secid
== AA_SECID_WILDCARD
) {
297 if (profile
->secmark
[i
].deny
)
298 perms
.deny
= ALL_PERMS_MASK
;
300 perms
.allow
= ALL_PERMS_MASK
;
302 if (profile
->secmark
[i
].audit
)
303 perms
.audit
= ALL_PERMS_MASK
;
307 aa_apply_modes_to_perms(profile
, &perms
);
309 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
312 int apparmor_secmark_check(struct aa_label
*label
, char *op
, u32 request
,
313 u32 secid
, struct sock
*sk
)
315 struct aa_profile
*profile
;
316 DEFINE_AUDIT_SK(sa
, op
, sk
);
318 return fn_for_each_confined(label
, profile
,
319 aa_secmark_perm(profile
, request
, secid
,