af_unix.c 21 KB

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