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
;
75 if (address_family_names
[sa
->u
.net
->family
])
76 audit_log_format(ab
, " family=\"%s\"",
77 address_family_names
[sa
->u
.net
->family
]);
79 audit_log_format(ab
, " family=\"unknown(%d)\"",
81 if (sock_type_names
[aad(sa
)->net
.type
])
82 audit_log_format(ab
, " sock_type=\"%s\"",
83 sock_type_names
[aad(sa
)->net
.type
]);
85 audit_log_format(ab
, " sock_type=\"unknown(%d)\"",
87 audit_log_format(ab
, " protocol=%d", aad(sa
)->net
.protocol
);
89 if (aad(sa
)->request
& NET_PERMS_MASK
) {
90 audit_log_format(ab
, " requested_mask=");
91 aa_audit_perm_mask(ab
, aad(sa
)->request
, NULL
, 0,
92 net_mask_names
, NET_PERMS_MASK
);
94 if (aad(sa
)->denied
& NET_PERMS_MASK
) {
95 audit_log_format(ab
, " denied_mask=");
96 aa_audit_perm_mask(ab
, aad(sa
)->denied
, NULL
, 0,
97 net_mask_names
, NET_PERMS_MASK
);
101 audit_log_format(ab
, " peer=");
102 aa_label_xaudit(ab
, labels_ns(aad(sa
)->label
), aad(sa
)->peer
,
103 FLAGS_NONE
, GFP_ATOMIC
);
107 /* Generic af perm */
108 int aa_profile_af_perm(struct aa_profile
*profile
, struct common_audit_data
*sa
,
109 u32 request
, u16 family
, int type
)
111 struct aa_perms perms
= { };
115 AA_BUG(family
>= AF_MAX
);
116 AA_BUG(type
< 0 || type
>= SOCK_MAX
);
118 if (profile_unconfined(profile
))
120 state
= PROFILE_MEDIATES(profile
, AA_CLASS_NET
);
124 buffer
[0] = cpu_to_be16(family
);
125 buffer
[1] = cpu_to_be16((u16
) type
);
126 state
= aa_dfa_match_len(profile
->policy
.dfa
, state
, (char *) &buffer
,
128 aa_compute_perms(profile
->policy
.dfa
, state
, &perms
);
129 aa_apply_modes_to_perms(profile
, &perms
);
131 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
134 int aa_af_perm(struct aa_label
*label
, const char *op
, u32 request
, u16 family
,
135 int type
, int protocol
)
137 struct aa_profile
*profile
;
138 DEFINE_AUDIT_NET(sa
, op
, NULL
, family
, type
, protocol
);
140 return fn_for_each_confined(label
, profile
,
141 aa_profile_af_perm(profile
, &sa
, request
, family
,
145 static int aa_label_sk_perm(struct aa_label
*label
, const char *op
, u32 request
,
153 if (!unconfined(label
)) {
154 struct aa_profile
*profile
;
155 DEFINE_AUDIT_SK(sa
, op
, sk
);
157 error
= fn_for_each_confined(label
, profile
,
158 aa_profile_af_sk_perm(profile
, &sa
, request
, sk
));
164 int aa_sk_perm(const char *op
, u32 request
, struct sock
*sk
)
166 struct aa_label
*label
;
170 AA_BUG(in_interrupt());
172 /* TODO: switch to begin_current_label ???? */
173 label
= begin_current_label_crit_section();
174 error
= aa_label_sk_perm(label
, op
, request
, sk
);
175 end_current_label_crit_section(label
);
181 int aa_sock_file_perm(struct aa_label
*label
, const char *op
, u32 request
,
188 return aa_label_sk_perm(label
, op
, request
, sock
->sk
);
191 #ifdef CONFIG_NETWORK_SECMARK
192 static int apparmor_secmark_init(struct aa_secmark
*secmark
)
194 struct aa_label
*label
;
196 if (secmark
->label
[0] == '*') {
197 secmark
->secid
= AA_SECID_WILDCARD
;
201 label
= aa_label_strn_parse(&root_ns
->unconfined
->label
,
202 secmark
->label
, strlen(secmark
->label
),
203 GFP_ATOMIC
, false, false);
206 return PTR_ERR(label
);
208 secmark
->secid
= label
->secid
;
213 static int aa_secmark_perm(struct aa_profile
*profile
, u32 request
, u32 secid
,
214 struct common_audit_data
*sa
)
217 struct aa_perms perms
= { };
219 if (profile
->secmark_count
== 0)
222 for (i
= 0; i
< profile
->secmark_count
; i
++) {
223 if (!profile
->secmark
[i
].secid
) {
224 ret
= apparmor_secmark_init(&profile
->secmark
[i
]);
229 if (profile
->secmark
[i
].secid
== secid
||
230 profile
->secmark
[i
].secid
== AA_SECID_WILDCARD
) {
231 if (profile
->secmark
[i
].deny
)
232 perms
.deny
= ALL_PERMS_MASK
;
234 perms
.allow
= ALL_PERMS_MASK
;
236 if (profile
->secmark
[i
].audit
)
237 perms
.audit
= ALL_PERMS_MASK
;
241 aa_apply_modes_to_perms(profile
, &perms
);
243 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
246 int apparmor_secmark_check(struct aa_label
*label
, char *op
, u32 request
,
247 u32 secid
, const struct sock
*sk
)
249 struct aa_profile
*profile
;
250 DEFINE_AUDIT_SK(sa
, op
, sk
);
252 return fn_for_each_confined(label
, profile
,
253 aa_secmark_perm(profile
, request
, secid
,