2 * AppArmor security module
4 * This file contains AppArmor network mediation
6 * Copyright (C) 1998-2008 Novell/SUSE
7 * Copyright 2009-2017 Canonical Ltd.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2 of the
15 #include "include/apparmor.h"
16 #include "include/audit.h"
17 #include "include/cred.h"
18 #include "include/label.h"
19 #include "include/net.h"
20 #include "include/policy.h"
21 #include "include/secid.h"
23 #include "net_names.h"
26 struct aa_sfs_entry aa_sfs_entry_network
[] = {
27 AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK
),
31 static const char * const net_mask_names
[] = {
74 /* audit callback for net specific fields */
75 void audit_net_cb(struct audit_buffer
*ab
, void *va
)
77 struct common_audit_data
*sa
= va
;
79 audit_log_format(ab
, " family=");
80 if (address_family_names
[sa
->u
.net
->family
])
81 audit_log_string(ab
, address_family_names
[sa
->u
.net
->family
]);
83 audit_log_format(ab
, "\"unknown(%d)\"", sa
->u
.net
->family
);
84 audit_log_format(ab
, " sock_type=");
85 if (sock_type_names
[aad(sa
)->net
.type
])
86 audit_log_string(ab
, sock_type_names
[aad(sa
)->net
.type
]);
88 audit_log_format(ab
, "\"unknown(%d)\"", aad(sa
)->net
.type
);
89 audit_log_format(ab
, " protocol=%d", aad(sa
)->net
.protocol
);
91 if (aad(sa
)->request
& NET_PERMS_MASK
) {
92 audit_log_format(ab
, " requested_mask=");
93 aa_audit_perm_mask(ab
, aad(sa
)->request
, NULL
, 0,
94 net_mask_names
, NET_PERMS_MASK
);
96 if (aad(sa
)->denied
& NET_PERMS_MASK
) {
97 audit_log_format(ab
, " denied_mask=");
98 aa_audit_perm_mask(ab
, aad(sa
)->denied
, NULL
, 0,
99 net_mask_names
, NET_PERMS_MASK
);
103 audit_log_format(ab
, " peer=");
104 aa_label_xaudit(ab
, labels_ns(aad(sa
)->label
), aad(sa
)->peer
,
105 FLAGS_NONE
, GFP_ATOMIC
);
109 /* Generic af perm */
110 int aa_profile_af_perm(struct aa_profile
*profile
, struct common_audit_data
*sa
,
111 u32 request
, u16 family
, int type
)
113 struct aa_perms perms
= { };
117 AA_BUG(family
>= AF_MAX
);
118 AA_BUG(type
< 0 || type
>= SOCK_MAX
);
120 if (profile_unconfined(profile
))
122 state
= PROFILE_MEDIATES(profile
, AA_CLASS_NET
);
126 buffer
[0] = cpu_to_be16(family
);
127 buffer
[1] = cpu_to_be16((u16
) type
);
128 state
= aa_dfa_match_len(profile
->policy
.dfa
, state
, (char *) &buffer
,
130 aa_compute_perms(profile
->policy
.dfa
, state
, &perms
);
131 aa_apply_modes_to_perms(profile
, &perms
);
133 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
136 int aa_af_perm(struct aa_label
*label
, const char *op
, u32 request
, u16 family
,
137 int type
, int protocol
)
139 struct aa_profile
*profile
;
140 DEFINE_AUDIT_NET(sa
, op
, NULL
, family
, type
, protocol
);
142 return fn_for_each_confined(label
, profile
,
143 aa_profile_af_perm(profile
, &sa
, request
, family
,
147 static int aa_label_sk_perm(struct aa_label
*label
, const char *op
, u32 request
,
155 if (!unconfined(label
)) {
156 struct aa_profile
*profile
;
157 DEFINE_AUDIT_SK(sa
, op
, sk
);
159 error
= fn_for_each_confined(label
, profile
,
160 aa_profile_af_sk_perm(profile
, &sa
, request
, sk
));
166 int aa_sk_perm(const char *op
, u32 request
, struct sock
*sk
)
168 struct aa_label
*label
;
172 AA_BUG(in_interrupt());
174 /* TODO: switch to begin_current_label ???? */
175 label
= begin_current_label_crit_section();
176 error
= aa_label_sk_perm(label
, op
, request
, sk
);
177 end_current_label_crit_section(label
);
183 int aa_sock_file_perm(struct aa_label
*label
, const char *op
, u32 request
,
190 return aa_label_sk_perm(label
, op
, request
, sock
->sk
);
193 #ifdef CONFIG_NETWORK_SECMARK
194 static int apparmor_secmark_init(struct aa_secmark
*secmark
)
196 struct aa_label
*label
;
198 if (secmark
->label
[0] == '*') {
199 secmark
->secid
= AA_SECID_WILDCARD
;
203 label
= aa_label_strn_parse(&root_ns
->unconfined
->label
,
204 secmark
->label
, strlen(secmark
->label
),
205 GFP_ATOMIC
, false, false);
208 return PTR_ERR(label
);
210 secmark
->secid
= label
->secid
;
215 static int aa_secmark_perm(struct aa_profile
*profile
, u32 request
, u32 secid
,
216 struct common_audit_data
*sa
, struct sock
*sk
)
219 struct aa_perms perms
= { };
221 if (profile
->secmark_count
== 0)
224 for (i
= 0; i
< profile
->secmark_count
; i
++) {
225 if (!profile
->secmark
[i
].secid
) {
226 ret
= apparmor_secmark_init(&profile
->secmark
[i
]);
231 if (profile
->secmark
[i
].secid
== secid
||
232 profile
->secmark
[i
].secid
== AA_SECID_WILDCARD
) {
233 if (profile
->secmark
[i
].deny
)
234 perms
.deny
= ALL_PERMS_MASK
;
236 perms
.allow
= ALL_PERMS_MASK
;
238 if (profile
->secmark
[i
].audit
)
239 perms
.audit
= ALL_PERMS_MASK
;
243 aa_apply_modes_to_perms(profile
, &perms
);
245 return aa_check_perms(profile
, &perms
, request
, sa
, audit_net_cb
);
248 int apparmor_secmark_check(struct aa_label
*label
, char *op
, u32 request
,
249 u32 secid
, struct sock
*sk
)
251 struct aa_profile
*profile
;
252 DEFINE_AUDIT_SK(sa
, op
, sk
);
254 return fn_for_each_confined(label
, profile
,
255 aa_secmark_perm(profile
, request
, secid
,