Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/security/apparmor/af_unix.c
26377 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* AppArmor security module
4
*
5
* This file contains AppArmor af_unix fine grained mediation
6
*
7
* Copyright 2023 Canonical Ltd.
8
*
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
12
* License.
13
*/
14
15
#include <linux/fs.h>
16
#include <net/tcp_states.h>
17
18
#include "include/audit.h"
19
#include "include/af_unix.h"
20
#include "include/apparmor.h"
21
#include "include/file.h"
22
#include "include/label.h"
23
#include "include/path.h"
24
#include "include/policy.h"
25
#include "include/cred.h"
26
27
28
static inline struct sock *aa_unix_sk(struct unix_sock *u)
29
{
30
return &u->sk;
31
}
32
33
static int unix_fs_perm(const char *op, u32 mask, const struct cred *subj_cred,
34
struct aa_label *label, struct path *path)
35
{
36
AA_BUG(!label);
37
AA_BUG(!path);
38
39
if (unconfined(label) || !label_mediates(label, AA_CLASS_FILE))
40
return 0;
41
42
mask &= NET_FS_PERMS;
43
/* if !u->path.dentry socket is being shutdown - implicit delegation
44
* until obj delegation is supported
45
*/
46
if (path->dentry) {
47
/* the sunpath may not be valid for this ns so use the path */
48
struct inode *inode = path->dentry->d_inode;
49
vfsuid_t vfsuid = i_uid_into_vfsuid(mnt_idmap(path->mnt), inode);
50
struct path_cond cond = {
51
.uid = vfsuid_into_kuid(vfsuid),
52
.mode = inode->i_mode,
53
};
54
55
return aa_path_perm(op, subj_cred, label, path,
56
PATH_SOCK_COND, mask, &cond);
57
} /* else implicitly delegated */
58
59
return 0;
60
}
61
62
/* match_addr special constants */
63
#define ABSTRACT_ADDR "\x00" /* abstract socket addr */
64
#define ANONYMOUS_ADDR "\x01" /* anonymous endpoint, no addr */
65
#define DISCONNECTED_ADDR "\x02" /* addr is another namespace */
66
#define SHUTDOWN_ADDR "\x03" /* path addr is shutdown and cleared */
67
#define FS_ADDR "/" /* path addr in fs */
68
69
static aa_state_t match_addr(struct aa_dfa *dfa, aa_state_t state,
70
struct sockaddr_un *addr, int addrlen)
71
{
72
if (addr)
73
/* include leading \0 */
74
state = aa_dfa_match_len(dfa, state, addr->sun_path,
75
unix_addr_len(addrlen));
76
else
77
state = aa_dfa_match_len(dfa, state, ANONYMOUS_ADDR, 1);
78
/* todo: could change to out of band for cleaner separation */
79
state = aa_dfa_null_transition(dfa, state);
80
81
return state;
82
}
83
84
static aa_state_t match_to_local(struct aa_policydb *policy,
85
aa_state_t state, u32 request,
86
int type, int protocol,
87
struct sockaddr_un *addr, int addrlen,
88
struct aa_perms **p,
89
const char **info)
90
{
91
state = aa_match_to_prot(policy, state, request, PF_UNIX, type,
92
protocol, NULL, info);
93
if (state) {
94
state = match_addr(policy->dfa, state, addr, addrlen);
95
if (state) {
96
/* todo: local label matching */
97
state = aa_dfa_null_transition(policy->dfa, state);
98
if (!state)
99
*info = "failed local label match";
100
} else {
101
*info = "failed local address match";
102
}
103
}
104
105
return state;
106
}
107
108
struct sockaddr_un *aa_sunaddr(const struct unix_sock *u, int *addrlen)
109
{
110
struct unix_address *addr;
111
112
/* memory barrier is sufficient see note in net/unix/af_unix.c */
113
addr = smp_load_acquire(&u->addr);
114
if (addr) {
115
*addrlen = addr->len;
116
return addr->name;
117
}
118
*addrlen = 0;
119
return NULL;
120
}
121
122
static aa_state_t match_to_sk(struct aa_policydb *policy,
123
aa_state_t state, u32 request,
124
struct unix_sock *u, struct aa_perms **p,
125
const char **info)
126
{
127
int addrlen;
128
struct sockaddr_un *addr = aa_sunaddr(u, &addrlen);
129
130
return match_to_local(policy, state, request, u->sk.sk_type,
131
u->sk.sk_protocol, addr, addrlen, p, info);
132
}
133
134
#define CMD_ADDR 1
135
#define CMD_LISTEN 2
136
#define CMD_OPT 4
137
138
static aa_state_t match_to_cmd(struct aa_policydb *policy, aa_state_t state,
139
u32 request, struct unix_sock *u,
140
char cmd, struct aa_perms **p,
141
const char **info)
142
{
143
AA_BUG(!p);
144
145
state = match_to_sk(policy, state, request, u, p, info);
146
if (state && !*p) {
147
state = aa_dfa_match_len(policy->dfa, state, &cmd, 1);
148
if (!state)
149
*info = "failed cmd selection match";
150
}
151
152
return state;
153
}
154
155
static aa_state_t match_to_peer(struct aa_policydb *policy, aa_state_t state,
156
u32 request, struct unix_sock *u,
157
struct sockaddr_un *peer_addr, int peer_addrlen,
158
struct aa_perms **p, const char **info)
159
{
160
AA_BUG(!p);
161
162
state = match_to_cmd(policy, state, request, u, CMD_ADDR, p, info);
163
if (state && !*p) {
164
state = match_addr(policy->dfa, state, peer_addr, peer_addrlen);
165
if (!state)
166
*info = "failed peer address match";
167
}
168
169
return state;
170
}
171
172
static aa_state_t match_label(struct aa_profile *profile,
173
struct aa_ruleset *rule, aa_state_t state,
174
u32 request, struct aa_profile *peer,
175
struct aa_perms *p,
176
struct apparmor_audit_data *ad)
177
{
178
AA_BUG(!profile);
179
AA_BUG(!peer);
180
181
ad->peer = &peer->label;
182
183
if (state && !p) {
184
state = aa_dfa_match(rule->policy->dfa, state,
185
peer->base.hname);
186
if (!state)
187
ad->info = "failed peer label match";
188
189
}
190
191
return aa_do_perms(profile, rule->policy, state, request, p, ad);
192
}
193
194
195
/* unix sock creation comes before we know if the socket will be an fs
196
* socket
197
* v6 - semantics are handled by mapping in profile load
198
* v7 - semantics require sock create for tasks creating an fs socket.
199
* v8 - same as v7
200
*/
201
static int profile_create_perm(struct aa_profile *profile, int family,
202
int type, int protocol,
203
struct apparmor_audit_data *ad)
204
{
205
struct aa_ruleset *rules = profile->label.rules[0];
206
aa_state_t state;
207
208
AA_BUG(!profile);
209
AA_BUG(profile_unconfined(profile));
210
211
state = RULE_MEDIATES_v9NET(rules);
212
if (state) {
213
state = aa_match_to_prot(rules->policy, state, AA_MAY_CREATE,
214
PF_UNIX, type, protocol, NULL,
215
&ad->info);
216
217
return aa_do_perms(profile, rules->policy, state, AA_MAY_CREATE,
218
NULL, ad);
219
}
220
221
return aa_profile_af_perm(profile, ad, AA_MAY_CREATE, family, type,
222
protocol);
223
}
224
225
static int profile_sk_perm(struct aa_profile *profile,
226
struct apparmor_audit_data *ad,
227
u32 request, struct sock *sk, struct path *path)
228
{
229
struct aa_ruleset *rules = profile->label.rules[0];
230
struct aa_perms *p = NULL;
231
aa_state_t state;
232
233
AA_BUG(!profile);
234
AA_BUG(!sk);
235
AA_BUG(profile_unconfined(profile));
236
237
state = RULE_MEDIATES_v9NET(rules);
238
if (state) {
239
if (is_unix_fs(sk))
240
return unix_fs_perm(ad->op, request, ad->subj_cred,
241
&profile->label,
242
&unix_sk(sk)->path);
243
244
state = match_to_sk(rules->policy, state, request, unix_sk(sk),
245
&p, &ad->info);
246
247
return aa_do_perms(profile, rules->policy, state, request, p,
248
ad);
249
}
250
251
return aa_profile_af_sk_perm(profile, ad, request, sk);
252
}
253
254
static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
255
struct apparmor_audit_data *ad)
256
{
257
struct aa_ruleset *rules = profile->label.rules[0];
258
struct aa_perms *p = NULL;
259
aa_state_t state;
260
261
AA_BUG(!profile);
262
AA_BUG(!sk);
263
AA_BUG(!ad);
264
AA_BUG(profile_unconfined(profile));
265
266
state = RULE_MEDIATES_v9NET(rules);
267
if (state) {
268
if (is_unix_addr_fs(ad->net.addr, ad->net.addrlen))
269
/* under v7-9 fs hook handles bind */
270
return 0;
271
/* bind for abstract socket */
272
state = match_to_local(rules->policy, state, AA_MAY_BIND,
273
sk->sk_type, sk->sk_protocol,
274
unix_addr(ad->net.addr),
275
ad->net.addrlen,
276
&p, &ad->info);
277
278
return aa_do_perms(profile, rules->policy, state, AA_MAY_BIND,
279
p, ad);
280
}
281
282
return aa_profile_af_sk_perm(profile, ad, AA_MAY_BIND, sk);
283
}
284
285
static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
286
int backlog, struct apparmor_audit_data *ad)
287
{
288
struct aa_ruleset *rules = profile->label.rules[0];
289
struct aa_perms *p = NULL;
290
aa_state_t state;
291
292
AA_BUG(!profile);
293
AA_BUG(!sk);
294
AA_BUG(!ad);
295
AA_BUG(profile_unconfined(profile));
296
297
state = RULE_MEDIATES_v9NET(rules);
298
if (state) {
299
__be16 b = cpu_to_be16(backlog);
300
301
if (is_unix_fs(sk))
302
return unix_fs_perm(ad->op, AA_MAY_LISTEN,
303
ad->subj_cred, &profile->label,
304
&unix_sk(sk)->path);
305
306
state = match_to_cmd(rules->policy, state, AA_MAY_LISTEN,
307
unix_sk(sk), CMD_LISTEN, &p, &ad->info);
308
if (state && !p) {
309
state = aa_dfa_match_len(rules->policy->dfa, state,
310
(char *) &b, 2);
311
if (!state)
312
ad->info = "failed listen backlog match";
313
}
314
return aa_do_perms(profile, rules->policy, state, AA_MAY_LISTEN,
315
p, ad);
316
}
317
318
return aa_profile_af_sk_perm(profile, ad, AA_MAY_LISTEN, sk);
319
}
320
321
static int profile_accept_perm(struct aa_profile *profile,
322
struct sock *sk,
323
struct apparmor_audit_data *ad)
324
{
325
struct aa_ruleset *rules = profile->label.rules[0];
326
struct aa_perms *p = NULL;
327
aa_state_t state;
328
329
AA_BUG(!profile);
330
AA_BUG(!sk);
331
AA_BUG(!ad);
332
AA_BUG(profile_unconfined(profile));
333
334
state = RULE_MEDIATES_v9NET(rules);
335
if (state) {
336
if (is_unix_fs(sk))
337
return unix_fs_perm(ad->op, AA_MAY_ACCEPT,
338
ad->subj_cred, &profile->label,
339
&unix_sk(sk)->path);
340
341
state = match_to_sk(rules->policy, state, AA_MAY_ACCEPT,
342
unix_sk(sk), &p, &ad->info);
343
344
return aa_do_perms(profile, rules->policy, state, AA_MAY_ACCEPT,
345
p, ad);
346
}
347
348
return aa_profile_af_sk_perm(profile, ad, AA_MAY_ACCEPT, sk);
349
}
350
351
static int profile_opt_perm(struct aa_profile *profile, u32 request,
352
struct sock *sk, int optname,
353
struct apparmor_audit_data *ad)
354
{
355
struct aa_ruleset *rules = profile->label.rules[0];
356
struct aa_perms *p = NULL;
357
aa_state_t state;
358
359
AA_BUG(!profile);
360
AA_BUG(!sk);
361
AA_BUG(!ad);
362
AA_BUG(profile_unconfined(profile));
363
364
state = RULE_MEDIATES_v9NET(rules);
365
if (state) {
366
__be16 b = cpu_to_be16(optname);
367
if (is_unix_fs(sk))
368
return unix_fs_perm(ad->op, request,
369
ad->subj_cred, &profile->label,
370
&unix_sk(sk)->path);
371
372
state = match_to_cmd(rules->policy, state, request, unix_sk(sk),
373
CMD_OPT, &p, &ad->info);
374
if (state && !p) {
375
state = aa_dfa_match_len(rules->policy->dfa, state,
376
(char *) &b, 2);
377
if (!state)
378
ad->info = "failed sockopt match";
379
}
380
return aa_do_perms(profile, rules->policy, state, request, p,
381
ad);
382
}
383
384
return aa_profile_af_sk_perm(profile, ad, request, sk);
385
}
386
387
/* null peer_label is allowed, in which case the peer_sk label is used */
388
static int profile_peer_perm(struct aa_profile *profile, u32 request,
389
struct sock *sk, struct path *path,
390
struct sockaddr_un *peer_addr,
391
int peer_addrlen, struct path *peer_path,
392
struct aa_label *peer_label,
393
struct apparmor_audit_data *ad)
394
{
395
struct aa_ruleset *rules = profile->label.rules[0];
396
struct aa_perms *p = NULL;
397
aa_state_t state;
398
399
AA_BUG(!profile);
400
AA_BUG(profile_unconfined(profile));
401
AA_BUG(!sk);
402
AA_BUG(!peer_label);
403
AA_BUG(!ad);
404
405
state = RULE_MEDIATES_v9NET(rules);
406
if (state) {
407
struct aa_profile *peerp;
408
409
if (peer_path)
410
return unix_fs_perm(ad->op, request, ad->subj_cred,
411
&profile->label, peer_path);
412
else if (path)
413
return unix_fs_perm(ad->op, request, ad->subj_cred,
414
&profile->label, path);
415
state = match_to_peer(rules->policy, state, request,
416
unix_sk(sk),
417
peer_addr, peer_addrlen, &p, &ad->info);
418
419
return fn_for_each_in_ns(peer_label, peerp,
420
match_label(profile, rules, state, request,
421
peerp, p, ad));
422
}
423
424
return aa_profile_af_sk_perm(profile, ad, request, sk);
425
}
426
427
/* -------------------------------- */
428
429
int aa_unix_create_perm(struct aa_label *label, int family, int type,
430
int protocol)
431
{
432
if (!unconfined(label)) {
433
struct aa_profile *profile;
434
DEFINE_AUDIT_NET(ad, OP_CREATE, current_cred(), NULL, family,
435
type, protocol);
436
437
return fn_for_each_confined(label, profile,
438
profile_create_perm(profile, family, type,
439
protocol, &ad));
440
}
441
442
return 0;
443
}
444
445
static int aa_unix_label_sk_perm(const struct cred *subj_cred,
446
struct aa_label *label,
447
const char *op, u32 request, struct sock *sk,
448
struct path *path)
449
{
450
if (!unconfined(label)) {
451
struct aa_profile *profile;
452
DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
453
454
return fn_for_each_confined(label, profile,
455
profile_sk_perm(profile, &ad, request, sk,
456
path));
457
}
458
return 0;
459
}
460
461
/* revalidation, get/set attr, shutdown */
462
int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
463
{
464
struct aa_label *label;
465
int error;
466
467
label = begin_current_label_crit_section();
468
error = aa_unix_label_sk_perm(current_cred(), label, op,
469
request, sock->sk,
470
is_unix_fs(sock->sk) ? &unix_sk(sock->sk)->path : NULL);
471
end_current_label_crit_section(label);
472
473
return error;
474
}
475
476
static int valid_addr(struct sockaddr *addr, int addr_len)
477
{
478
struct sockaddr_un *sunaddr = unix_addr(addr);
479
480
/* addr_len == offsetof(struct sockaddr_un, sun_path) is autobind */
481
if (addr_len < offsetof(struct sockaddr_un, sun_path) ||
482
addr_len > sizeof(*sunaddr))
483
return -EINVAL;
484
return 0;
485
}
486
487
int aa_unix_bind_perm(struct socket *sock, struct sockaddr *addr,
488
int addrlen)
489
{
490
struct aa_profile *profile;
491
struct aa_label *label;
492
int error = 0;
493
494
error = valid_addr(addr, addrlen);
495
if (error)
496
return error;
497
498
label = begin_current_label_crit_section();
499
/* fs bind is handled by mknod */
500
if (!unconfined(label)) {
501
DEFINE_AUDIT_SK(ad, OP_BIND, current_cred(), sock->sk);
502
503
ad.net.addr = unix_addr(addr);
504
ad.net.addrlen = addrlen;
505
506
error = fn_for_each_confined(label, profile,
507
profile_bind_perm(profile, sock->sk, &ad));
508
}
509
end_current_label_crit_section(label);
510
511
return error;
512
}
513
514
/*
515
* unix connections are covered by the
516
* - unix_stream_connect (stream) and unix_may_send hooks (dgram)
517
* - fs connect is handled by open
518
* This is just here to document this is not needed for af_unix
519
*
520
int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
521
int addrlen)
522
{
523
return 0;
524
}
525
*/
526
527
int aa_unix_listen_perm(struct socket *sock, int backlog)
528
{
529
struct aa_profile *profile;
530
struct aa_label *label;
531
int error = 0;
532
533
label = begin_current_label_crit_section();
534
if (!unconfined(label)) {
535
DEFINE_AUDIT_SK(ad, OP_LISTEN, current_cred(), sock->sk);
536
537
error = fn_for_each_confined(label, profile,
538
profile_listen_perm(profile, sock->sk,
539
backlog, &ad));
540
}
541
end_current_label_crit_section(label);
542
543
return error;
544
}
545
546
547
/* ability of sock to connect, not peer address binding */
548
int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
549
{
550
struct aa_profile *profile;
551
struct aa_label *label;
552
int error = 0;
553
554
label = begin_current_label_crit_section();
555
if (!unconfined(label)) {
556
DEFINE_AUDIT_SK(ad, OP_ACCEPT, current_cred(), sock->sk);
557
558
error = fn_for_each_confined(label, profile,
559
profile_accept_perm(profile, sock->sk, &ad));
560
}
561
end_current_label_crit_section(label);
562
563
return error;
564
}
565
566
567
/*
568
* dgram handled by unix_may_sendmsg, right to send on stream done at connect
569
* could do per msg unix_stream here, but connect + socket transfer is
570
* sufficient. This is just here to document this is not needed for af_unix
571
*
572
* sendmsg, recvmsg
573
int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
574
struct msghdr *msg, int size)
575
{
576
return 0;
577
}
578
*/
579
580
int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock,
581
int level, int optname)
582
{
583
struct aa_profile *profile;
584
struct aa_label *label;
585
int error = 0;
586
587
label = begin_current_label_crit_section();
588
if (!unconfined(label)) {
589
DEFINE_AUDIT_SK(ad, op, current_cred(), sock->sk);
590
591
error = fn_for_each_confined(label, profile,
592
profile_opt_perm(profile, request, sock->sk,
593
optname, &ad));
594
}
595
end_current_label_crit_section(label);
596
597
return error;
598
}
599
600
static int unix_peer_perm(const struct cred *subj_cred,
601
struct aa_label *label, const char *op, u32 request,
602
struct sock *sk, struct path *path,
603
struct sockaddr_un *peer_addr, int peer_addrlen,
604
struct path *peer_path, struct aa_label *peer_label)
605
{
606
struct aa_profile *profile;
607
DEFINE_AUDIT_SK(ad, op, subj_cred, sk);
608
609
ad.net.peer.addr = peer_addr;
610
ad.net.peer.addrlen = peer_addrlen;
611
612
return fn_for_each_confined(label, profile,
613
profile_peer_perm(profile, request, sk, path,
614
peer_addr, peer_addrlen, peer_path,
615
peer_label, &ad));
616
}
617
618
/**
619
*
620
* Requires: lock held on both @sk and @peer_sk
621
* called by unix_stream_connect, unix_may_send
622
*/
623
int aa_unix_peer_perm(const struct cred *subj_cred,
624
struct aa_label *label, const char *op, u32 request,
625
struct sock *sk, struct sock *peer_sk,
626
struct aa_label *peer_label)
627
{
628
struct unix_sock *peeru = unix_sk(peer_sk);
629
struct unix_sock *u = unix_sk(sk);
630
int plen;
631
struct sockaddr_un *paddr = aa_sunaddr(unix_sk(peer_sk), &plen);
632
633
AA_BUG(!label);
634
AA_BUG(!sk);
635
AA_BUG(!peer_sk);
636
AA_BUG(!peer_label);
637
638
return unix_peer_perm(subj_cred, label, op, request, sk,
639
is_unix_fs(sk) ? &u->path : NULL,
640
paddr, plen,
641
is_unix_fs(peer_sk) ? &peeru->path : NULL,
642
peer_label);
643
}
644
645
/* sk_plabel for comparison only */
646
static void update_sk_ctx(struct sock *sk, struct aa_label *label,
647
struct aa_label *plabel)
648
{
649
struct aa_label *l, *old;
650
struct aa_sk_ctx *ctx = aa_sock(sk);
651
bool update_sk;
652
653
rcu_read_lock();
654
update_sk = (plabel &&
655
(plabel != rcu_access_pointer(ctx->peer_lastupdate) ||
656
!aa_label_is_subset(plabel, rcu_dereference(ctx->peer)))) ||
657
!__aa_subj_label_is_cached(label, rcu_dereference(ctx->label));
658
rcu_read_unlock();
659
if (!update_sk)
660
return;
661
662
spin_lock(&unix_sk(sk)->lock);
663
old = rcu_dereference_protected(ctx->label,
664
lockdep_is_held(&unix_sk(sk)->lock));
665
l = aa_label_merge(old, label, GFP_ATOMIC);
666
if (l) {
667
if (l != old) {
668
rcu_assign_pointer(ctx->label, l);
669
aa_put_label(old);
670
} else
671
aa_put_label(l);
672
}
673
if (plabel && rcu_access_pointer(ctx->peer_lastupdate) != plabel) {
674
old = rcu_dereference_protected(ctx->peer, lockdep_is_held(&unix_sk(sk)->lock));
675
676
if (old == plabel) {
677
rcu_assign_pointer(ctx->peer_lastupdate, plabel);
678
} else if (aa_label_is_subset(plabel, old)) {
679
rcu_assign_pointer(ctx->peer_lastupdate, plabel);
680
rcu_assign_pointer(ctx->peer, aa_get_label(plabel));
681
aa_put_label(old);
682
} /* else race or a subset - don't update */
683
}
684
spin_unlock(&unix_sk(sk)->lock);
685
}
686
687
static void update_peer_ctx(struct sock *sk, struct aa_sk_ctx *ctx,
688
struct aa_label *label)
689
{
690
struct aa_label *l, *old;
691
692
spin_lock(&unix_sk(sk)->lock);
693
old = rcu_dereference_protected(ctx->peer,
694
lockdep_is_held(&unix_sk(sk)->lock));
695
l = aa_label_merge(old, label, GFP_ATOMIC);
696
if (l) {
697
if (l != old) {
698
rcu_assign_pointer(ctx->peer, l);
699
aa_put_label(old);
700
} else
701
aa_put_label(l);
702
}
703
spin_unlock(&unix_sk(sk)->lock);
704
}
705
706
/* This fn is only checked if something has changed in the security
707
* boundaries. Otherwise cached info off file is sufficient
708
*/
709
int aa_unix_file_perm(const struct cred *subj_cred, struct aa_label *label,
710
const char *op, u32 request, struct file *file)
711
{
712
struct socket *sock = (struct socket *) file->private_data;
713
struct sockaddr_un *addr, *peer_addr;
714
int addrlen, peer_addrlen;
715
struct aa_label *plabel = NULL;
716
struct sock *peer_sk = NULL;
717
u32 sk_req = request & ~NET_PEER_MASK;
718
struct path path;
719
bool is_sk_fs;
720
int error = 0;
721
722
AA_BUG(!label);
723
AA_BUG(!sock);
724
AA_BUG(!sock->sk);
725
AA_BUG(sock->sk->sk_family != PF_UNIX);
726
727
/* investigate only using lock via unix_peer_get()
728
* addr only needs the memory barrier, but need to investigate
729
* path
730
*/
731
unix_state_lock(sock->sk);
732
peer_sk = unix_peer(sock->sk);
733
if (peer_sk)
734
sock_hold(peer_sk);
735
736
is_sk_fs = is_unix_fs(sock->sk);
737
addr = aa_sunaddr(unix_sk(sock->sk), &addrlen);
738
path = unix_sk(sock->sk)->path;
739
unix_state_unlock(sock->sk);
740
741
if (is_sk_fs && peer_sk)
742
sk_req = request;
743
if (sk_req) {
744
error = aa_unix_label_sk_perm(subj_cred, label, op,
745
sk_req, sock->sk,
746
is_sk_fs ? &path : NULL);
747
}
748
if (!peer_sk)
749
goto out;
750
751
peer_addr = aa_sunaddr(unix_sk(peer_sk), &peer_addrlen);
752
753
struct path peer_path;
754
755
peer_path = unix_sk(peer_sk)->path;
756
if (!is_sk_fs && is_unix_fs(peer_sk)) {
757
last_error(error,
758
unix_fs_perm(op, request, subj_cred, label,
759
is_unix_fs(peer_sk) ? &peer_path : NULL));
760
} else if (!is_sk_fs) {
761
struct aa_label *plabel;
762
struct aa_sk_ctx *pctx = aa_sock(peer_sk);
763
764
rcu_read_lock();
765
plabel = aa_get_label_rcu(&pctx->label);
766
rcu_read_unlock();
767
/* no fs check of aa_unix_peer_perm because conditions above
768
* ensure they will never be done
769
*/
770
last_error(error,
771
xcheck(unix_peer_perm(subj_cred, label, op,
772
MAY_READ | MAY_WRITE, sock->sk,
773
is_sk_fs ? &path : NULL,
774
peer_addr, peer_addrlen,
775
is_unix_fs(peer_sk) ?
776
&peer_path : NULL,
777
plabel),
778
unix_peer_perm(file->f_cred, plabel, op,
779
MAY_READ | MAY_WRITE, peer_sk,
780
is_unix_fs(peer_sk) ?
781
&peer_path : NULL,
782
addr, addrlen,
783
is_sk_fs ? &path : NULL,
784
label)));
785
if (!error && !__aa_subj_label_is_cached(plabel, label))
786
update_peer_ctx(peer_sk, pctx, label);
787
}
788
sock_put(peer_sk);
789
790
out:
791
792
/* update peer cache to latest successful perm check */
793
if (error == 0)
794
update_sk_ctx(sock->sk, label, plabel);
795
aa_put_label(plabel);
796
797
return error;
798
}
799
800
801