1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3 * AppArmor security module
4 *
5 * This file contains AppArmor inet fine grained mediation
6 *
7 * Copyright 2024 Canonical Ltd.
8 *
9 */
10
11 #include <net/tcp_states.h>
12
13 #include "include/audit.h"
14 #include "include/af_inet.h"
15 #include "include/apparmor.h"
16 #include "include/file.h"
17 #include "include/label.h"
18 #include "include/net.h"
19 #include "include/path.h"
20 #include "include/policy.h"
21 #include "include/cred.h"
22
23
RULE_MEDIATES_SK(struct aa_ruleset * rules,const struct sock * sk)24 static inline aa_state_t RULE_MEDIATES_SK(struct aa_ruleset *rules,
25 const struct sock *sk)
26 {
27 return RULE_MEDIATES_NET(rules);
28 }
29
30
31 enum addr_type {
32 ADDR_LOCAL = 0,
33 ADDR_LOCAL_PRIV = 1,
34 ADDR_REMOTE = 2,
35 };
36
37 struct match_addr {
38 const char *addrp;
39 enum addr_type addrtype;
40 int len;
41 __be16 port;
42 };
43
44 struct stored_match_addr {
45 union {
46 struct sockaddr addr;
47 struct sockaddr_in addr4;
48 struct sockaddr_in6 addr6;
49 };
50 int addrlen;
51 struct match_addr maddr;
52 };
53
set_ad_create(struct apparmor_audit_data * ad,int family,int type,int protocol)54 static void set_ad_create(struct apparmor_audit_data *ad,
55 int family, int type, int protocol)
56 {
57 ad->common.u.net->family = family;
58 ad->net.type = type;
59 ad->net.protocol = protocol;
60 }
61
set_ad_addr(struct apparmor_audit_data * ad,u16 family,bool source,struct match_addr * maddr)62 static int set_ad_addr(struct apparmor_audit_data *ad,
63 u16 family, bool source, struct match_addr *maddr)
64 {
65 ad->common.u.net->family = family;
66
67 if (source) {
68 ad->common.u.net->sport = maddr->port;
69 if (maddr->addrp) {
70 if (family == AF_INET)
71 /* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */
72 ad->common.u.net->v4info.saddr = *(__be32 *)maddr->addrp;
73 else
74 /* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */
75 ad->common.u.net->v6info.saddr = *(struct in6_addr *)maddr->addrp;
76 }
77 } else {
78 ad->common.u.net->dport = maddr->port;
79 if (maddr->addrp) {
80 if (family == AF_INET)
81 /* ad.u.net->v4info.saddr = addr4->sin_addr.s_addr; */
82 ad->common.u.net->v4info.daddr = *(__be32 *)maddr->addrp;
83 else
84 /* ad.u.net->v4info.saddr = addr6->sin6_addr.s6_addr; */
85 ad->common.u.net->v6info.daddr = *(struct in6_addr *)maddr->addrp;
86 }
87 }
88 return 0;
89 }
90
91 /* returns 0 on success
92 * raw_port - if set raw_port (protocol) when SOCK_RAW */
map_addr(struct sockaddr * addr,int addrlen,u16 raw_port,enum addr_type addrtype,struct match_addr * maddr,struct apparmor_audit_data * ad)93 static int map_addr(struct sockaddr *addr, int addrlen, u16 raw_port,
94 enum addr_type addrtype, struct match_addr *maddr,
95 struct apparmor_audit_data *ad)
96 {
97 struct sockaddr_in *addr4 = NULL;
98 struct sockaddr_in6 *addr6 = NULL;
99
100 AA_BUG(!addr);
101 AA_BUG(!maddr);
102
103 maddr->addrtype = addrtype;
104 if (!addr || addrlen < offsetofend(struct sockaddr, sa_family)) {
105 maddr->addrp = NULL;
106 maddr->port = 0;
107 maddr->len = 0;
108 return 0;
109 }
110
111 /*
112 * its possibly to have sk->sk_family == PF_INET6 and
113 * addr->sa_family == AF_INET. sk_family is used for socket
114 * mediation, sa_family for when we have address ...
115 */
116 switch (addr->sa_family) {
117 case AF_INET:
118 addr4 = (struct sockaddr_in *)addr;
119 if (addrlen < sizeof(struct sockaddr_in))
120 return -EINVAL;
121 maddr->port = addr4->sin_port;
122 maddr->addrp = (char *)&addr4->sin_addr.s_addr;
123 maddr->len = 4;
124 break;
125 case AF_INET6:
126 addr6 = (struct sockaddr_in6 *)addr;
127 if (addrlen < SIN6_LEN_RFC2133)
128 return -EINVAL;
129 maddr->port = addr6->sin6_port;
130 maddr->addrp = (char *)&addr6->sin6_addr.s6_addr;
131 maddr->len = 16;
132 break;
133 default:
134 return -EAFNOSUPPORT;
135 }
136 /* per ip spec, && sk->sk_type == SOCK_RAW*/
137 if (raw_port && addrtype != ADDR_REMOTE)
138 maddr->port = htons(raw_port);
139 if (ad)
140 set_ad_addr(ad, addr->sa_family, addrtype != ADDR_REMOTE, maddr);
141
142 return 0;
143 }
144
145 /* -ENOTCONN if not connected */
map_sock_addr(struct socket * sock,enum addr_type addrtype,struct stored_match_addr * maddr,struct apparmor_audit_data * ad)146 static int map_sock_addr(struct socket *sock, enum addr_type addrtype,
147 struct stored_match_addr *maddr,
148 struct apparmor_audit_data *ad)
149 {
150 /* do we need early bailout for !family ... */
151 maddr->addrlen = sock->ops->getname(sock, (struct sockaddr *) &maddr->addr, addrtype != ADDR_REMOTE ? 0 : 1);
152 if (maddr->addrlen == -ENOTCONN) {
153 maddr->addrlen = 0;
154 return map_addr(NULL, 0, 0, addrtype, &maddr->maddr, ad);
155 } else if (maddr->addrlen < 0)
156 return maddr->addrlen;
157 return map_addr(&maddr->addr, maddr->addrlen, 0, addrtype,
158 &maddr->maddr, ad);
159 }
160
161 /* TODO: combine with connect map addr */
162 /* TODO: raw_port */
bind_map_addr(const struct sock * sk,struct sockaddr * addr,int addrlen,struct match_addr * maddr,struct apparmor_audit_data * ad)163 static int bind_map_addr(const struct sock *sk, struct sockaddr *addr,
164 int addrlen,
165 struct match_addr *maddr,
166 struct apparmor_audit_data *ad)
167 {
168 struct sockaddr_in *addr4 = NULL;
169 struct sockaddr_in6 *addr6 = NULL;
170 u16 family;
171
172 AA_BUG(!sk);
173 AA_BUG(!addr);
174 AA_BUG(!maddr);
175
176 if (addrlen < offsetofend(struct sockaddr, sa_family))
177 return -EINVAL;
178
179 maddr->addrtype = ADDR_LOCAL;
180 /*
181 * its possibly to have sk->sk_family == PF_INET6 and
182 * addr->sa_family == AF_INET. sk_family is used for socket
183 * mediation, sa_family for when we have address ...
184 */
185 family = addr->sa_family;
186 switch (addr->sa_family) {
187 case AF_UNSPEC:
188 if (sk->sk_family == PF_INET6) {
189 /* Length check from inet6_bind_sk() */
190 if (addrlen < SIN6_LEN_RFC2133)
191 return -EINVAL;
192 /* Family check from __inet6_bind() */
193 return -EAFNOSUPPORT;
194 }
195 /* see __inet_bind(), we only want to allow
196 * AF_UNSPEC if the address is INADDR_ANY
197 */
198 addr4 = (struct sockaddr_in *)addr;
199 if (addr4->sin_addr.s_addr != htonl(INADDR_ANY))
200 return -EAFNOSUPPORT;
201 family = AF_INET;
202 fallthrough;
203 case AF_INET:
204 addr4 = (struct sockaddr_in *)addr;
205 if (addrlen < sizeof(struct sockaddr_in))
206 return -EINVAL;
207 maddr->port = addr4->sin_port;
208 maddr->addrp = (char *)&addr4->sin_addr.s_addr;
209 maddr->len = 4;
210 break;
211 case AF_INET6:
212 addr6 = (struct sockaddr_in6 *)addr;
213 if (addrlen < SIN6_LEN_RFC2133)
214 return -EINVAL;
215 maddr->port = addr6->sin6_port;
216 maddr->addrp = (char *)&addr6->sin6_addr.s6_addr;
217 maddr->len = 16;
218 break;
219 default:
220 return -EAFNOSUPPORT;
221 }
222
223 if (ad)
224 set_ad_addr(ad, family, true, maddr);
225
226 return 0;
227 }
228
229
profile_sk_perm(struct aa_profile * profile,u32 request,const struct sock * sk,struct match_addr * maddr,struct apparmor_audit_data * ad)230 static inline int profile_sk_perm(struct aa_profile *profile, u32 request,
231 const struct sock *sk,
232 struct match_addr *maddr,
233 struct apparmor_audit_data *ad)
234 {
235 AA_BUG(!profile);
236 AA_BUG(!sk);
237
238 return aa_profile_af_sk_perm(profile, ad, request, sk);
239 }
240
241 /* no kernel_t bailout */
profile_create_perm(struct aa_profile * profile,int family,int type,int protocol,struct apparmor_audit_data * ad)242 static int profile_create_perm(struct aa_profile *profile, int family,
243 int type, int protocol,
244 struct apparmor_audit_data *ad)
245 {
246 AA_BUG(!profile);
247
248 return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type,
249 protocol);
250 }
251
252
253 /* sendmsg/rcvmsg/connect */
profile_remote_perm(struct aa_profile * profile,const struct sock * sk,u32 request,struct match_addr * raddr,struct match_addr * laddr,struct apparmor_audit_data * ad)254 static int profile_remote_perm(struct aa_profile *profile,
255 const struct sock *sk,
256 u32 request, struct match_addr *raddr,
257 struct match_addr *laddr,
258 struct apparmor_audit_data *ad)
259 {
260 AA_BUG(!profile);
261 AA_BUG(!sk);
262 AA_BUG(!raddr);
263 AA_BUG(!laddr);
264 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
265 "family=%d", sk->sk_family);
266
267 return aa_profile_af_sk_perm(profile, ad, request, sk);
268 }
269
profile_bind_perm(struct aa_profile * profile,const struct sock * sk,struct match_addr * maddr,struct apparmor_audit_data * ad)270 static int profile_bind_perm(struct aa_profile *profile,
271 const struct sock *sk,
272 struct match_addr *maddr,
273 struct apparmor_audit_data *ad)
274 {
275 return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk);
276
277 }
278
profile_listen_perm(struct aa_profile * profile,const struct sock * sk,struct match_addr * maddr,int backlog,struct apparmor_audit_data * ad)279 static int profile_listen_perm(struct aa_profile *profile,
280 const struct sock *sk,
281 struct match_addr *maddr, int backlog,
282 struct apparmor_audit_data *ad)
283 {
284 AA_BUG(!profile);
285 AA_BUG(!sk);
286 AA_BUG(!maddr);
287 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
288 "family=%d", sk->sk_family);
289
290 return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk);
291 }
292
profile_accept_perm(struct aa_profile * profile,const struct sock * sk,struct match_addr * maddr,const struct sock * newsk,struct apparmor_audit_data * ad)293 static inline int profile_accept_perm(struct aa_profile *profile,
294 const struct sock *sk,
295 struct match_addr *maddr,
296 const struct sock *newsk,
297 struct apparmor_audit_data *ad)
298 {
299 AA_BUG(!profile);
300 AA_BUG(!sk);
301 /* AA_BUG(!newsk); newsk can be null here, since not using atm ... */
302 AA_BUG(!maddr);
303 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
304 "family=%d", sk->sk_family);
305
306 return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk);
307 }
308
309 /* getopt/setopt */
profile_opt_perm(struct aa_profile * profile,u32 request,const struct sock * sk,struct match_addr * maddr,int level,int optname,struct apparmor_audit_data * ad)310 static int profile_opt_perm(struct aa_profile *profile, u32 request,
311 const struct sock *sk, struct match_addr *maddr,
312 int level, int optname,
313 struct apparmor_audit_data *ad)
314 {
315 AA_BUG(!profile);
316 AA_BUG(!sk);
317 AA_BUG(!maddr);
318 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
319 "family=%d", sk->sk_family);
320
321 return aa_profile_af_sk_perm(profile, ad, request, sk);
322 }
323
324 /* ---------------------------------------------------------------------- */
325
326 // TODO: cleanup init to use recursion, so we can have N init fns, in 1 macro
327 // TODO: lift DEFINE_AUDIT out of macro into init fn???
328
329 /* no kernel_t bailout */
330 #define label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, YYYY, CALLBACKFN) \
331 ({ \
332 int __EERROR = 0; \
333 if (label_mediates(LABEL, AA_CLASS_NET)) { \
334 struct aa_profile *PROFILE; \
335 DEFINE_AUDIT_SK(AAD, OP, CRED, SOCKSK); \
336 (AAD).subj_cred = (CRED); \
337 (AAD).request = (REQUEST); \
338 __EERROR = (XXXX); \
339 if (__EERROR == 0) { \
340 __EERROR = (YYYY); \
341 if (__EERROR == 0) { \
342 __EERROR = fn_for_each(LABEL, PROFILE, \
343 (CALLBACKFN)); \
344 } \
345 } \
346 } \
347 __EERROR; \
348 })
349
350 /* no kernel_t bailout */
351 #define label_sk_has_perm(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN) \
352 label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \
353 0, 0, CALLBACKFN)
354
355 /* no kernel_t bailout */
356 #define label_sk_has_perm1(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXX, CALLBACKFN) \
357 label_sk_has_perm2(CRED, LABEL, SOCKSK, OP, REQUEST, PROFILE, AAD, \
358 XXXX, 0, CALLBACKFN)
359
360
361 /* Early bailout for kernel_t - 2 init args before callback */
362 #define sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN) \
363 ({ \
364 struct aa_label *__label; \
365 struct aa_sk_ctx *__ctx = aa_sock(SOCKSK); \
366 int __ERROR = 0; \
367 bool __needput; \
368 if (rcu_access_pointer(__ctx->label) != kernel_t) { \
369 \
370 __label = begin_current_label_crit_section(&__needput); \
371 __ERROR = label_sk_has_perm2(current_cred(), __label, SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, YYYYX, CALLBACKFN); \
372 end_current_label_crit_section(__label, __needput); \
373 } \
374 __ERROR; \
375 })
376
377 /* Early bailout for kernel_t - no init args before callback */
378 #define sk_has_perm(SOCKSK, OP, REQUEST, PROFILE, AAD, CALLBACKFN) \
379 sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, 0, 0, CALLBACKFN)
380
381
382 /* Early bailout for kernel_t - 1 init arg before callback */
383 #define sk_has_perm1(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, CALLBACKFN) \
384 sk_has_perm2(SOCKSK, OP, REQUEST, PROFILE, AAD, XXXXY, 0, CALLBACKFN)
385
386
387
388 /* no kernel_t early bailout */
389 /* NOTE: already lifted label_mediates into lsm.c */
aa_inet_create_perm(struct aa_label * label,int family,int type,int protocol)390 int aa_inet_create_perm(struct aa_label *label, int family, int type,
391 int protocol)
392 {
393 struct aa_profile *profile;
394 int error = 0;
395 DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family, type,
396 protocol);
397
398 ad.subj_cred = current_cred();
399 set_ad_create(&ad, family, type, protocol);
400 error = fn_for_each(label, profile,
401 profile_create_perm(profile, family, type,
402 protocol, &ad));
403
404 return error;
405 }
406
aa_inet_bind_perm(struct socket * sock,struct sockaddr * addr,int addrlen)407 int aa_inet_bind_perm(struct socket *sock, struct sockaddr *addr,
408 int addrlen)
409 {
410 struct match_addr maddr;
411
412 return sk_has_perm1(sock->sk, OP_BIND, AA_MAY_BIND, profile, ad,
413 bind_map_addr(sock->sk, addr, addrlen, &maddr,
414 &ad),
415 profile_bind_perm(profile, sock->sk, &maddr, &ad));
416 }
417
aa_inet_connect_perm(struct socket * sock,struct sockaddr * addr,int addrlen)418 int aa_inet_connect_perm(struct socket *sock, struct sockaddr *addr,
419 int addrlen)
420 {
421 struct stored_match_addr laddr;
422 struct match_addr raddr;
423
424 /* disconnect socket */
425 if (addrlen < offsetofend(struct sockaddr, sa_family))
426 return -EINVAL;
427 if (addr->sa_family == AF_UNSPEC)
428 return 0;
429
430 /* do we need early bailout for !family ... */
431 return sk_has_perm2(sock->sk, OP_CONNECT, AA_MAY_CONNECT, profile, ad,
432 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
433 map_addr(addr, addrlen, 0, ADDR_REMOTE, &raddr,
434 &ad),
435 profile_remote_perm(profile, sock->sk,
436 AA_MAY_CONNECT, &raddr,
437 &laddr.maddr, &ad));
438 }
439
aa_inet_listen_perm(struct socket * sock,int backlog)440 int aa_inet_listen_perm(struct socket *sock, int backlog)
441 {
442 struct stored_match_addr maddr;
443
444 /* do we need early bailout for !family ... */
445 return sk_has_perm1(sock->sk, OP_LISTEN, AA_MAY_LISTEN, profile, ad,
446 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
447 profile_listen_perm(profile, sock->sk, &maddr.maddr,
448 backlog, &ad));
449 }
450
451 /* ability of sock to connect, not peer address binding */
aa_inet_accept_perm(struct socket * sock,struct socket * newsock)452 int aa_inet_accept_perm(struct socket *sock, struct socket *newsock)
453 {
454 struct stored_match_addr maddr;
455 int error;
456
457 error = sk_has_perm1(sock->sk, OP_ACCEPT, AA_MAY_ACCEPT, profile, ad,
458 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
459 profile_accept_perm(profile, sock->sk,
460 &maddr.maddr,
461 newsock->sk, &ad));
462
463 /* selinux updates inode - need to investigate this more */
464 return error;
465 }
466
467 /* sendmsg, recvmsg. */
aa_inet_msg_perm(const char * op,u32 request,struct socket * sock,struct msghdr * msg,int size)468 int aa_inet_msg_perm(const char *op, u32 request, struct socket *sock,
469 struct msghdr *msg, int size)
470 {
471 struct stored_match_addr laddr;
472 struct match_addr raddr;
473
474 /* do we need early bailout for !family ... */
475 return sk_has_perm2(sock->sk, op, request, profile, ad,
476 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
477 map_addr(msg->msg_name, msg->msg_namelen, 0,
478 ADDR_REMOTE, &raddr, &ad),
479 profile_remote_perm(profile, sock->sk, request,
480 &raddr, &laddr.maddr, &ad));
481 }
482
483 /* getopt, setopt */
aa_inet_opt_perm(const char * op,u32 request,struct socket * sock,int level,int optname)484 int aa_inet_opt_perm(const char *op, u32 request, struct socket *sock,
485 int level, int optname)
486 {
487 struct stored_match_addr maddr;
488
489 return sk_has_perm1(sock->sk, op, request, profile, ad,
490 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
491 profile_opt_perm(profile, request, sock->sk,
492 &maddr.maddr, level, optname, &ad));
493 }
494
inet_label_sock_perm(const struct cred * cred,struct aa_label * label,const char * op,u32 request,struct socket * sock)495 static int inet_label_sock_perm(const struct cred *cred, struct aa_label *label,
496 const char *op, u32 request,
497 struct socket *sock)
498 {
499 struct stored_match_addr maddr;
500
501 return label_sk_has_perm1(cred, label, sock->sk, op, request, profile,
502 ad,
503 map_sock_addr(sock, ADDR_LOCAL, &maddr, &ad),
504 profile_sk_perm(profile, request, sock->sk,
505 &maddr.maddr, &ad));
506 }
507
508 /* revalidation, get/set attr/getsockname/peername */
aa_inet_sock_perm(const char * op,u32 request,struct socket * sock)509 int aa_inet_sock_perm(const char *op, u32 request, struct socket *sock)
510 {
511 struct aa_sk_ctx *ctx = aa_sock(sock->sk);
512 struct aa_label *label;
513 bool needput;
514 int error;
515
516 if (rcu_access_pointer(ctx->label) == kernel_t)
517 return 0;
518
519 label = begin_current_label_crit_section(&needput);
520 error = inet_label_sock_perm(current_cred(), label, op, request, sock);
521 end_current_label_crit_section(label, needput);
522
523 return error;
524 }
525
aa_inet_file_perm(const struct cred * subj_cred,struct aa_label * label,const char * op,u32 request,struct socket * sock)526 int aa_inet_file_perm(const struct cred *subj_cred, struct aa_label *label,
527 const char *op, u32 request, struct socket *sock)
528 {
529 u32 sk_req = request & ~NET_PEER_MASK;
530 struct stored_match_addr laddr;
531 const struct sock *sk = sock->sk;
532 int error = 0;
533
534 AA_BUG(!label);
535 AA_BUG(!sock);
536 AA_BUG(!sock->sk);
537 AA_BUG(sk->sk_family != PF_INET && sk->sk_family != PF_INET6,
538 "family=%d", sk->sk_family);
539
540 /* access to the local sock */
541 error = label_sk_has_perm1(subj_cred, label, sock->sk, op, request,
542 profile, ad,
543 map_sock_addr(sock, ADDR_LOCAL, &laddr, &ad),
544 profile_sk_perm(profile, sk_req, sock->sk, &laddr.maddr,
545 &ad));
546
547 if (!error) {
548 struct stored_match_addr raddr;
549
550 /* TODO: have ad here: instead of in CB so we do have to redo */
551 error = map_sock_addr(sock, ADDR_REMOTE, &raddr, NULL);
552 if (!error && raddr.maddr.addrp) {
553 error = label_sk_has_perm1(subj_cred, label, sock->sk,
554 op, request, profile, ad,
555 set_ad_addr(&ad, raddr.addr.sa_family,
556 false, &raddr.maddr),
557 profile_remote_perm(profile, sock->sk,
558 request,
559 &raddr.maddr,
560 &laddr.maddr, &ad));
561 }
562 }
563
564 return error;
565 }
566