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 audit_log_format(ab
, " family=");
76 if (address_family_names
[sa
->u
.net
->family
])
77 audit_log_string(ab
, address_family_names
[sa
->u
.net
->family
]);
79 audit_log_format(ab
, "\"unknown(%d)\"", sa
->u
.net
->family
);
80 audit_log_format(ab
, " sock_type=");
81 if (sock_type_names
[aad(sa
)->net
.type
])
82 audit_log_string(ab
, sock_type_names
[aad(sa
)->net
.type
]);
84 audit_log_format(ab
, "\"unknown(%d)\"", aad(sa
)->net
.type
);
85 audit_log_format(ab
, " protocol=%d", aad(sa
)->net
.protocol
);
87 if (aad(sa
)->request
& NET_PERMS_MASK
) {
88 audit_log_format(ab
, " requested_mask=");
89 aa_audit_perm_mask(ab
, aad(sa
)->request
, NULL
, 0,
90 net_mask_names
, NET_PERMS_MASK
);
92 if (aad(sa
)->denied
& NET_PERMS_MASK
) {
93 audit_log_format(ab
, " denied_mask=");
94 aa_audit_perm_mask(ab
, aad(sa
)->denied
, NULL
, 0,
95 net_mask_names
, NET_PERMS_MASK
);
99 audit_log_format(ab
, " peer=");
100 aa_label_xaudit(ab
, labels_ns(aad(sa
)->label
), aad(sa
)->peer
,
101 FLAGS_NONE
, GFP_ATOMIC
);
105 /* Generic af perm */
106 int aa_profile_af_perm(struct aa_profile
*profile
, struct common_audit_data
*sa
,
107 u32 request
, u16 family
, int type
)
109 struct aa_perms perms
= { };
113 AA_BUG(family
>= AF_MAX
);
114 AA_BUG(type
< 0 || type
>= SOCK_MAX
);
116 if (profile_unconfined(profile
))
118 state
= PROFILE_MEDIATES(profile
, AA_CLASS_NET
);
122 buffer
[0] = cpu_to_be16(family
);
123 buffer
[1] = cpu_to_be16((u16
) type
);
124 state
= aa_dfa_match_len(profile
->policy
.dfa
, state
, (char *) &buffer
,
126 aa_compute_perms(profile
->policy
.dfa
, state
, &perms
);
127 aa_apply_modes_to_perms(profile
, &perms
);
129 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
132 int aa_af_perm(struct aa_label
*label
, const char *op
, u32 request
, u16 family
,
133 int type
, int protocol
)
135 struct aa_profile
*profile
;
136 DEFINE_AUDIT_NET(sa
, op
, NULL
, family
, type
, protocol
);
138 return fn_for_each_confined(label
, profile
,
139 aa_profile_af_perm(profile
, &sa
, request
, family
,
143 static int aa_label_sk_perm(struct aa_label
*label
, const char *op
, u32 request
,
151 if (!unconfined(label
)) {
152 struct aa_profile
*profile
;
153 DEFINE_AUDIT_SK(sa
, op
, sk
);
155 error
= fn_for_each_confined(label
, profile
,
156 aa_profile_af_sk_perm(profile
, &sa
, request
, sk
));
162 int aa_sk_perm(const char *op
, u32 request
, struct sock
*sk
)
164 struct aa_label
*label
;
168 AA_BUG(in_interrupt());
170 /* TODO: switch to begin_current_label ???? */
171 label
= begin_current_label_crit_section();
172 error
= aa_label_sk_perm(label
, op
, request
, sk
);
173 end_current_label_crit_section(label
);
179 int aa_sock_file_perm(struct aa_label
*label
, const char *op
, u32 request
,
186 return aa_label_sk_perm(label
, op
, request
, sock
->sk
);
189 #ifdef CONFIG_NETWORK_SECMARK
190 static int apparmor_secmark_init(struct aa_secmark
*secmark
)
192 struct aa_label
*label
;
194 if (secmark
->label
[0] == '*') {
195 secmark
->secid
= AA_SECID_WILDCARD
;
199 label
= aa_label_strn_parse(&root_ns
->unconfined
->label
,
200 secmark
->label
, strlen(secmark
->label
),
201 GFP_ATOMIC
, false, false);
204 return PTR_ERR(label
);
206 secmark
->secid
= label
->secid
;
211 static int aa_secmark_perm(struct aa_profile
*profile
, u32 request
, u32 secid
,
212 struct common_audit_data
*sa
, struct sock
*sk
)
215 struct aa_perms perms
= { };
217 if (profile
->secmark_count
== 0)
220 for (i
= 0; i
< profile
->secmark_count
; i
++) {
221 if (!profile
->secmark
[i
].secid
) {
222 ret
= apparmor_secmark_init(&profile
->secmark
[i
]);
227 if (profile
->secmark
[i
].secid
== secid
||
228 profile
->secmark
[i
].secid
== AA_SECID_WILDCARD
) {
229 if (profile
->secmark
[i
].deny
)
230 perms
.deny
= ALL_PERMS_MASK
;
232 perms
.allow
= ALL_PERMS_MASK
;
234 if (profile
->secmark
[i
].audit
)
235 perms
.audit
= ALL_PERMS_MASK
;
239 aa_apply_modes_to_perms(profile
, &perms
);
241 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
244 int apparmor_secmark_check(struct aa_label
*label
, char *op
, u32 request
,
245 u32 secid
, struct sock
*sk
)
247 struct aa_profile
*profile
;
248 DEFINE_AUDIT_SK(sa
, op
, sk
);
250 return fn_for_each_confined(label
, profile
,
251 aa_secmark_perm(profile
, request
, secid
,