0008-apparmor-af_unix-mediation.patch 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. From c59a2789cc146827c225f9f9035b9fc23a82fc45 Mon Sep 17 00:00:00 2001
  2. From: John Johansen <[email protected]>
  3. Date: Tue, 18 Jul 2017 23:27:23 -0700
  4. Subject: UBUNTU: SAUCE: apparmor: af_unix mediation
  5. af_socket mediation did not make it into 4.17 so add remaining out
  6. of tree patch
  7. Signed-off-by: John Johansen <[email protected]>
  8. Signed-off-by: Seth Forshee <[email protected]>
  9. ---
  10. security/apparmor/Makefile | 3 +-
  11. security/apparmor/af_unix.c | 652 ++++++++++++++++++++++++++++++++++++
  12. security/apparmor/apparmorfs.c | 6 +
  13. security/apparmor/file.c | 4 +-
  14. security/apparmor/include/af_unix.h | 114 +++++++
  15. security/apparmor/include/net.h | 4 +
  16. security/apparmor/include/path.h | 1 +
  17. security/apparmor/include/policy.h | 10 +-
  18. security/apparmor/lsm.c | 112 +++++++
  19. security/apparmor/net.c | 53 ++-
  20. 10 files changed, 953 insertions(+), 6 deletions(-)
  21. create mode 100644 security/apparmor/af_unix.c
  22. create mode 100644 security/apparmor/include/af_unix.h
  23. (limited to 'security/apparmor')
  24. diff --git a/security/apparmor/Makefile b/security/apparmor/Makefile
  25. index ff23fcf..fad407f 100644
  26. --- a/security/apparmor/Makefile
  27. +++ b/security/apparmor/Makefile
  28. @@ -5,7 +5,8 @@ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor.o
  29. apparmor-y := apparmorfs.o audit.o capability.o task.o ipc.o lib.o match.o \
  30. path.o domain.o policy.o policy_unpack.o procattr.o lsm.o \
  31. - resource.o secid.o file.o policy_ns.o label.o mount.o net.o
  32. + resource.o secid.o file.o policy_ns.o label.o mount.o net.o \
  33. + af_unix.o
  34. apparmor-$(CONFIG_SECURITY_APPARMOR_HASH) += crypto.o
  35. clean-files := capability_names.h rlim_names.h net_names.h
  36. diff --git a/security/apparmor/af_unix.c b/security/apparmor/af_unix.c
  37. new file mode 100644
  38. index 0000000..54b3796
  39. --- /dev/null
  40. +++ b/security/apparmor/af_unix.c
  41. @@ -0,0 +1,652 @@
  42. +/*
  43. + * AppArmor security module
  44. + *
  45. + * This file contains AppArmor af_unix fine grained mediation
  46. + *
  47. + * Copyright 2018 Canonical Ltd.
  48. + *
  49. + * This program is free software; you can redistribute it and/or
  50. + * modify it under the terms of the GNU General Public License as
  51. + * published by the Free Software Foundation, version 2 of the
  52. + * License.
  53. + */
  54. +
  55. +#include <net/tcp_states.h>
  56. +
  57. +#include "include/audit.h"
  58. +#include "include/af_unix.h"
  59. +#include "include/apparmor.h"
  60. +#include "include/file.h"
  61. +#include "include/label.h"
  62. +#include "include/path.h"
  63. +#include "include/policy.h"
  64. +#include "include/cred.h"
  65. +
  66. +static inline struct sock *aa_sock(struct unix_sock *u)
  67. +{
  68. + return &u->sk;
  69. +}
  70. +
  71. +static inline int unix_fs_perm(const char *op, u32 mask, struct aa_label *label,
  72. + struct unix_sock *u, int flags)
  73. +{
  74. + AA_BUG(!label);
  75. + AA_BUG(!u);
  76. + AA_BUG(!UNIX_FS(aa_sock(u)));
  77. +
  78. + if (unconfined(label) || !LABEL_MEDIATES(label, AA_CLASS_FILE))
  79. + return 0;
  80. +
  81. + mask &= NET_FS_PERMS;
  82. + if (!u->path.dentry) {
  83. + struct path_cond cond = { };
  84. + struct aa_perms perms = { };
  85. + struct aa_profile *profile;
  86. +
  87. + /* socket path has been cleared because it is being shutdown
  88. + * can only fall back to original sun_path request
  89. + */
  90. + struct aa_sk_ctx *ctx = SK_CTX(&u->sk);
  91. + if (ctx->path.dentry)
  92. + return aa_path_perm(op, label, &ctx->path, flags, mask,
  93. + &cond);
  94. + return fn_for_each_confined(label, profile,
  95. + ((flags | profile->path_flags) & PATH_MEDIATE_DELETED) ?
  96. + __aa_path_perm(op, profile,
  97. + u->addr->name->sun_path, mask,
  98. + &cond, flags, &perms) :
  99. + aa_audit_file(profile, &nullperms, op, mask,
  100. + u->addr->name->sun_path, NULL,
  101. + NULL, cond.uid,
  102. + "Failed name lookup - "
  103. + "deleted entry", -EACCES));
  104. + } else {
  105. + /* the sunpath may not be valid for this ns so use the path */
  106. + struct path_cond cond = { u->path.dentry->d_inode->i_uid,
  107. + u->path.dentry->d_inode->i_mode
  108. + };
  109. +
  110. + return aa_path_perm(op, label, &u->path, flags, mask, &cond);
  111. + }
  112. +
  113. + return 0;
  114. +}
  115. +
  116. +/* passing in state returned by PROFILE_MEDIATES_AF */
  117. +static unsigned int match_to_prot(struct aa_profile *profile,
  118. + unsigned int state, int type, int protocol,
  119. + const char **info)
  120. +{
  121. + __be16 buffer[2];
  122. + buffer[0] = cpu_to_be16(type);
  123. + buffer[1] = cpu_to_be16(protocol);
  124. + state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &buffer,
  125. + 4);
  126. + if (!state)
  127. + *info = "failed type and protocol match";
  128. + return state;
  129. +}
  130. +
  131. +static unsigned int match_addr(struct aa_profile *profile, unsigned int state,
  132. + struct sockaddr_un *addr, int addrlen)
  133. +{
  134. + if (addr)
  135. + /* include leading \0 */
  136. + state = aa_dfa_match_len(profile->policy.dfa, state,
  137. + addr->sun_path,
  138. + unix_addr_len(addrlen));
  139. + else
  140. + /* anonymous end point */
  141. + state = aa_dfa_match_len(profile->policy.dfa, state, "\x01",
  142. + 1);
  143. + /* todo change to out of band */
  144. + state = aa_dfa_null_transition(profile->policy.dfa, state);
  145. + return state;
  146. +}
  147. +
  148. +static unsigned int match_to_local(struct aa_profile *profile,
  149. + unsigned int state, int type, int protocol,
  150. + struct sockaddr_un *addr, int addrlen,
  151. + const char **info)
  152. +{
  153. + state = match_to_prot(profile, state, type, protocol, info);
  154. + if (state) {
  155. + state = match_addr(profile, state, addr, addrlen);
  156. + if (state) {
  157. + /* todo: local label matching */
  158. + state = aa_dfa_null_transition(profile->policy.dfa,
  159. + state);
  160. + if (!state)
  161. + *info = "failed local label match";
  162. + } else
  163. + *info = "failed local address match";
  164. + }
  165. +
  166. + return state;
  167. +}
  168. +
  169. +static unsigned int match_to_sk(struct aa_profile *profile,
  170. + unsigned int state, struct unix_sock *u,
  171. + const char **info)
  172. +{
  173. + struct sockaddr_un *addr = NULL;
  174. + int addrlen = 0;
  175. +
  176. + if (u->addr) {
  177. + addr = u->addr->name;
  178. + addrlen = u->addr->len;
  179. + }
  180. +
  181. + return match_to_local(profile, state, u->sk.sk_type, u->sk.sk_protocol,
  182. + addr, addrlen, info);
  183. +}
  184. +
  185. +#define CMD_ADDR 1
  186. +#define CMD_LISTEN 2
  187. +#define CMD_OPT 4
  188. +
  189. +static inline unsigned int match_to_cmd(struct aa_profile *profile,
  190. + unsigned int state, struct unix_sock *u,
  191. + char cmd, const char **info)
  192. +{
  193. + state = match_to_sk(profile, state, u, info);
  194. + if (state) {
  195. + state = aa_dfa_match_len(profile->policy.dfa, state, &cmd, 1);
  196. + if (!state)
  197. + *info = "failed cmd selection match";
  198. + }
  199. +
  200. + return state;
  201. +}
  202. +
  203. +static inline unsigned int match_to_peer(struct aa_profile *profile,
  204. + unsigned int state,
  205. + struct unix_sock *u,
  206. + struct sockaddr_un *peer_addr,
  207. + int peer_addrlen,
  208. + const char **info)
  209. +{
  210. + state = match_to_cmd(profile, state, u, CMD_ADDR, info);
  211. + if (state) {
  212. + state = match_addr(profile, state, peer_addr, peer_addrlen);
  213. + if (!state)
  214. + *info = "failed peer address match";
  215. + }
  216. + return state;
  217. +}
  218. +
  219. +static int do_perms(struct aa_profile *profile, unsigned int state, u32 request,
  220. + struct common_audit_data *sa)
  221. +{
  222. + struct aa_perms perms;
  223. +
  224. + AA_BUG(!profile);
  225. +
  226. + aa_compute_perms(profile->policy.dfa, state, &perms);
  227. + aa_apply_modes_to_perms(profile, &perms);
  228. + return aa_check_perms(profile, &perms, request, sa,
  229. + audit_net_cb);
  230. +}
  231. +
  232. +static int match_label(struct aa_profile *profile, struct aa_profile *peer,
  233. + unsigned int state, u32 request,
  234. + struct common_audit_data *sa)
  235. +{
  236. + AA_BUG(!profile);
  237. + AA_BUG(!peer);
  238. +
  239. + aad(sa)->peer = &peer->label;
  240. +
  241. + if (state) {
  242. + state = aa_dfa_match(profile->policy.dfa, state,
  243. + peer->base.hname);
  244. + if (!state)
  245. + aad(sa)->info = "failed peer label match";
  246. + }
  247. + return do_perms(profile, state, request, sa);
  248. +}
  249. +
  250. +
  251. +/* unix sock creation comes before we know if the socket will be an fs
  252. + * socket
  253. + * v6 - semantics are handled by mapping in profile load
  254. + * v7 - semantics require sock create for tasks creating an fs socket.
  255. + */
  256. +static int profile_create_perm(struct aa_profile *profile, int family,
  257. + int type, int protocol)
  258. +{
  259. + unsigned int state;
  260. + DEFINE_AUDIT_NET(sa, OP_CREATE, NULL, family, type, protocol);
  261. +
  262. + AA_BUG(!profile);
  263. + AA_BUG(profile_unconfined(profile));
  264. +
  265. + if ((state = PROFILE_MEDIATES_AF(profile, AF_UNIX))) {
  266. + state = match_to_prot(profile, state, type, protocol,
  267. + &aad(&sa)->info);
  268. + return do_perms(profile, state, AA_MAY_CREATE, &sa);
  269. + }
  270. +
  271. + return aa_profile_af_perm(profile, &sa, AA_MAY_CREATE, family, type);
  272. +}
  273. +
  274. +int aa_unix_create_perm(struct aa_label *label, int family, int type,
  275. + int protocol)
  276. +{
  277. + struct aa_profile *profile;
  278. +
  279. + if (unconfined(label))
  280. + return 0;
  281. +
  282. + return fn_for_each_confined(label, profile,
  283. + profile_create_perm(profile, family, type, protocol));
  284. +}
  285. +
  286. +
  287. +static inline int profile_sk_perm(struct aa_profile *profile, const char *op,
  288. + u32 request, struct sock *sk)
  289. +{
  290. + unsigned int state;
  291. + DEFINE_AUDIT_SK(sa, op, sk);
  292. +
  293. + AA_BUG(!profile);
  294. + AA_BUG(!sk);
  295. + AA_BUG(UNIX_FS(sk));
  296. + AA_BUG(profile_unconfined(profile));
  297. +
  298. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  299. + if (state) {
  300. + state = match_to_sk(profile, state, unix_sk(sk),
  301. + &aad(&sa)->info);
  302. + return do_perms(profile, state, request, &sa);
  303. + }
  304. +
  305. + return aa_profile_af_sk_perm(profile, &sa, request, sk);
  306. +}
  307. +
  308. +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
  309. + struct sock *sk)
  310. +{
  311. + struct aa_profile *profile;
  312. +
  313. + return fn_for_each_confined(label, profile,
  314. + profile_sk_perm(profile, op, request, sk));
  315. +}
  316. +
  317. +static int unix_label_sock_perm(struct aa_label *label, const char *op, u32 request,
  318. + struct socket *sock)
  319. +{
  320. + if (unconfined(label))
  321. + return 0;
  322. + if (UNIX_FS(sock->sk))
  323. + return unix_fs_perm(op, request, label, unix_sk(sock->sk), 0);
  324. +
  325. + return aa_unix_label_sk_perm(label, op, request, sock->sk);
  326. +}
  327. +
  328. +/* revaliation, get/set attr */
  329. +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock)
  330. +{
  331. + struct aa_label *label;
  332. + int error;
  333. +
  334. + label = begin_current_label_crit_section();
  335. + error = unix_label_sock_perm(label, op, request, sock);
  336. + end_current_label_crit_section(label);
  337. +
  338. + return error;
  339. +}
  340. +
  341. +static int profile_bind_perm(struct aa_profile *profile, struct sock *sk,
  342. + struct sockaddr *addr, int addrlen)
  343. +{
  344. + unsigned int state;
  345. + DEFINE_AUDIT_SK(sa, OP_BIND, sk);
  346. +
  347. + AA_BUG(!profile);
  348. + AA_BUG(!sk);
  349. + AA_BUG(addr->sa_family != AF_UNIX);
  350. + AA_BUG(profile_unconfined(profile));
  351. + AA_BUG(unix_addr_fs(addr, addrlen));
  352. +
  353. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  354. + if (state) {
  355. + /* bind for abstract socket */
  356. + aad(&sa)->net.addr = unix_addr(addr);
  357. + aad(&sa)->net.addrlen = addrlen;
  358. +
  359. + state = match_to_local(profile, state,
  360. + sk->sk_type, sk->sk_protocol,
  361. + unix_addr(addr), addrlen,
  362. + &aad(&sa)->info);
  363. + return do_perms(profile, state, AA_MAY_BIND, &sa);
  364. + }
  365. +
  366. + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_BIND, sk);
  367. +}
  368. +
  369. +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
  370. + int addrlen)
  371. +{
  372. + struct aa_profile *profile;
  373. + struct aa_label *label;
  374. + int error = 0;
  375. +
  376. + label = begin_current_label_crit_section();
  377. + /* fs bind is handled by mknod */
  378. + if (!(unconfined(label) || unix_addr_fs(address, addrlen)))
  379. + error = fn_for_each_confined(label, profile,
  380. + profile_bind_perm(profile, sock->sk, address,
  381. + addrlen));
  382. + end_current_label_crit_section(label);
  383. +
  384. + return error;
  385. +}
  386. +
  387. +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
  388. + int addrlen)
  389. +{
  390. + /* unix connections are covered by the
  391. + * - unix_stream_connect (stream) and unix_may_send hooks (dgram)
  392. + * - fs connect is handled by open
  393. + */
  394. + return 0;
  395. +}
  396. +
  397. +static int profile_listen_perm(struct aa_profile *profile, struct sock *sk,
  398. + int backlog)
  399. +{
  400. + unsigned int state;
  401. + DEFINE_AUDIT_SK(sa, OP_LISTEN, sk);
  402. +
  403. + AA_BUG(!profile);
  404. + AA_BUG(!sk);
  405. + AA_BUG(UNIX_FS(sk));
  406. + AA_BUG(profile_unconfined(profile));
  407. +
  408. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  409. + if (state) {
  410. + __be16 b = cpu_to_be16(backlog);
  411. +
  412. + state = match_to_cmd(profile, state, unix_sk(sk), CMD_LISTEN,
  413. + &aad(&sa)->info);
  414. + if (state) {
  415. + state = aa_dfa_match_len(profile->policy.dfa, state,
  416. + (char *) &b, 2);
  417. + if (!state)
  418. + aad(&sa)->info = "failed listen backlog match";
  419. + }
  420. + return do_perms(profile, state, AA_MAY_LISTEN, &sa);
  421. + }
  422. +
  423. + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_LISTEN, sk);
  424. +}
  425. +
  426. +int aa_unix_listen_perm(struct socket *sock, int backlog)
  427. +{
  428. + struct aa_profile *profile;
  429. + struct aa_label *label;
  430. + int error = 0;
  431. +
  432. + label = begin_current_label_crit_section();
  433. + if (!(unconfined(label) || UNIX_FS(sock->sk)))
  434. + error = fn_for_each_confined(label, profile,
  435. + profile_listen_perm(profile, sock->sk,
  436. + backlog));
  437. + end_current_label_crit_section(label);
  438. +
  439. + return error;
  440. +}
  441. +
  442. +
  443. +static inline int profile_accept_perm(struct aa_profile *profile,
  444. + struct sock *sk,
  445. + struct sock *newsk)
  446. +{
  447. + unsigned int state;
  448. + DEFINE_AUDIT_SK(sa, OP_ACCEPT, sk);
  449. +
  450. + AA_BUG(!profile);
  451. + AA_BUG(!sk);
  452. + AA_BUG(UNIX_FS(sk));
  453. + AA_BUG(profile_unconfined(profile));
  454. +
  455. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  456. + if (state) {
  457. + state = match_to_sk(profile, state, unix_sk(sk),
  458. + &aad(&sa)->info);
  459. + return do_perms(profile, state, AA_MAY_ACCEPT, &sa);
  460. + }
  461. +
  462. + return aa_profile_af_sk_perm(profile, &sa, AA_MAY_ACCEPT, sk);
  463. +}
  464. +
  465. +/* ability of sock to connect, not peer address binding */
  466. +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock)
  467. +{
  468. + struct aa_profile *profile;
  469. + struct aa_label *label;
  470. + int error = 0;
  471. +
  472. + label = begin_current_label_crit_section();
  473. + if (!(unconfined(label) || UNIX_FS(sock->sk)))
  474. + error = fn_for_each_confined(label, profile,
  475. + profile_accept_perm(profile, sock->sk,
  476. + newsock->sk));
  477. + end_current_label_crit_section(label);
  478. +
  479. + return error;
  480. +}
  481. +
  482. +
  483. +/* dgram handled by unix_may_sendmsg, right to send on stream done at connect
  484. + * could do per msg unix_stream here
  485. + */
  486. +/* sendmsg, recvmsg */
  487. +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
  488. + struct msghdr *msg, int size)
  489. +{
  490. + return 0;
  491. +}
  492. +
  493. +
  494. +static int profile_opt_perm(struct aa_profile *profile, const char *op, u32 request,
  495. + struct sock *sk, int level, int optname)
  496. +{
  497. + unsigned int state;
  498. + DEFINE_AUDIT_SK(sa, op, sk);
  499. +
  500. + AA_BUG(!profile);
  501. + AA_BUG(!sk);
  502. + AA_BUG(UNIX_FS(sk));
  503. + AA_BUG(profile_unconfined(profile));
  504. +
  505. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  506. + if (state) {
  507. + __be16 b = cpu_to_be16(optname);
  508. +
  509. + state = match_to_cmd(profile, state, unix_sk(sk), CMD_OPT,
  510. + &aad(&sa)->info);
  511. + if (state) {
  512. + state = aa_dfa_match_len(profile->policy.dfa, state,
  513. + (char *) &b, 2);
  514. + if (!state)
  515. + aad(&sa)->info = "failed sockopt match";
  516. + }
  517. + return do_perms(profile, state, request, &sa);
  518. + }
  519. +
  520. + return aa_profile_af_sk_perm(profile, &sa, request, sk);
  521. +}
  522. +
  523. +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
  524. + int optname)
  525. +{
  526. + struct aa_profile *profile;
  527. + struct aa_label *label;
  528. + int error = 0;
  529. +
  530. + label = begin_current_label_crit_section();
  531. + if (!(unconfined(label) || UNIX_FS(sock->sk)))
  532. + error = fn_for_each_confined(label, profile,
  533. + profile_opt_perm(profile, op, request,
  534. + sock->sk, level, optname));
  535. + end_current_label_crit_section(label);
  536. +
  537. + return error;
  538. +}
  539. +
  540. +/* null peer_label is allowed, in which case the peer_sk label is used */
  541. +static int profile_peer_perm(struct aa_profile *profile, const char *op, u32 request,
  542. + struct sock *sk, struct sock *peer_sk,
  543. + struct aa_label *peer_label,
  544. + struct common_audit_data *sa)
  545. +{
  546. + unsigned int state;
  547. +
  548. + AA_BUG(!profile);
  549. + AA_BUG(profile_unconfined(profile));
  550. + AA_BUG(!sk);
  551. + AA_BUG(!peer_sk);
  552. + AA_BUG(UNIX_FS(peer_sk));
  553. +
  554. + state = PROFILE_MEDIATES_AF(profile, AF_UNIX);
  555. + if (state) {
  556. + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
  557. + struct aa_profile *peerp;
  558. + struct sockaddr_un *addr = NULL;
  559. + int len = 0;
  560. + if (unix_sk(peer_sk)->addr) {
  561. + addr = unix_sk(peer_sk)->addr->name;
  562. + len = unix_sk(peer_sk)->addr->len;
  563. + }
  564. + state = match_to_peer(profile, state, unix_sk(sk),
  565. + addr, len, &aad(sa)->info);
  566. + if (!peer_label)
  567. + peer_label = peer_ctx->label;
  568. + return fn_for_each_in_ns(peer_label, peerp,
  569. + match_label(profile, peerp, state, request,
  570. + sa));
  571. + }
  572. +
  573. + return aa_profile_af_sk_perm(profile, sa, request, sk);
  574. +}
  575. +
  576. +/**
  577. + *
  578. + * Requires: lock held on both @sk and @peer_sk
  579. + */
  580. +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
  581. + struct sock *sk, struct sock *peer_sk,
  582. + struct aa_label *peer_label)
  583. +{
  584. + struct unix_sock *peeru = unix_sk(peer_sk);
  585. + struct unix_sock *u = unix_sk(sk);
  586. +
  587. + AA_BUG(!label);
  588. + AA_BUG(!sk);
  589. + AA_BUG(!peer_sk);
  590. +
  591. + if (UNIX_FS(aa_sock(peeru)))
  592. + return unix_fs_perm(op, request, label, peeru, 0);
  593. + else if (UNIX_FS(aa_sock(u)))
  594. + return unix_fs_perm(op, request, label, u, 0);
  595. + else {
  596. + struct aa_profile *profile;
  597. + DEFINE_AUDIT_SK(sa, op, sk);
  598. + aad(&sa)->net.peer_sk = peer_sk;
  599. +
  600. + /* TODO: ns!!! */
  601. + if (!net_eq(sock_net(sk), sock_net(peer_sk))) {
  602. + ;
  603. + }
  604. +
  605. + if (unconfined(label))
  606. + return 0;
  607. +
  608. + return fn_for_each_confined(label, profile,
  609. + profile_peer_perm(profile, op, request, sk,
  610. + peer_sk, peer_label, &sa));
  611. + }
  612. +}
  613. +
  614. +
  615. +/* from net/unix/af_unix.c */
  616. +static void unix_state_double_lock(struct sock *sk1, struct sock *sk2)
  617. +{
  618. + if (unlikely(sk1 == sk2) || !sk2) {
  619. + unix_state_lock(sk1);
  620. + return;
  621. + }
  622. + if (sk1 < sk2) {
  623. + unix_state_lock(sk1);
  624. + unix_state_lock_nested(sk2);
  625. + } else {
  626. + unix_state_lock(sk2);
  627. + unix_state_lock_nested(sk1);
  628. + }
  629. +}
  630. +
  631. +static void unix_state_double_unlock(struct sock *sk1, struct sock *sk2)
  632. +{
  633. + if (unlikely(sk1 == sk2) || !sk2) {
  634. + unix_state_unlock(sk1);
  635. + return;
  636. + }
  637. + unix_state_unlock(sk1);
  638. + unix_state_unlock(sk2);
  639. +}
  640. +
  641. +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
  642. + struct socket *sock)
  643. +{
  644. + struct sock *peer_sk = NULL;
  645. + u32 sk_req = request & ~NET_PEER_MASK;
  646. + int error = 0;
  647. +
  648. + AA_BUG(!label);
  649. + AA_BUG(!sock);
  650. + AA_BUG(!sock->sk);
  651. + AA_BUG(sock->sk->sk_family != AF_UNIX);
  652. +
  653. + /* TODO: update sock label with new task label */
  654. + unix_state_lock(sock->sk);
  655. + peer_sk = unix_peer(sock->sk);
  656. + if (peer_sk)
  657. + sock_hold(peer_sk);
  658. + if (!unix_connected(sock) && sk_req) {
  659. + error = unix_label_sock_perm(label, op, sk_req, sock);
  660. + if (!error) {
  661. + // update label
  662. + }
  663. + }
  664. + unix_state_unlock(sock->sk);
  665. + if (!peer_sk)
  666. + return error;
  667. +
  668. + unix_state_double_lock(sock->sk, peer_sk);
  669. + if (UNIX_FS(sock->sk)) {
  670. + error = unix_fs_perm(op, request, label, unix_sk(sock->sk),
  671. + PATH_SOCK_COND);
  672. + } else if (UNIX_FS(peer_sk)) {
  673. + error = unix_fs_perm(op, request, label, unix_sk(peer_sk),
  674. + PATH_SOCK_COND);
  675. + } else {
  676. + struct aa_sk_ctx *pctx = SK_CTX(peer_sk);
  677. + if (sk_req)
  678. + error = aa_unix_label_sk_perm(label, op, sk_req,
  679. + sock->sk);
  680. + last_error(error,
  681. + xcheck(aa_unix_peer_perm(label, op,
  682. + MAY_READ | MAY_WRITE,
  683. + sock->sk, peer_sk, NULL),
  684. + aa_unix_peer_perm(pctx->label, op,
  685. + MAY_READ | MAY_WRITE,
  686. + peer_sk, sock->sk, label)));
  687. + }
  688. +
  689. + unix_state_double_unlock(sock->sk, peer_sk);
  690. + sock_put(peer_sk);
  691. +
  692. + return error;
  693. +}
  694. diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
  695. index 0aef8e3..d581800 100644
  696. --- a/security/apparmor/apparmorfs.c
  697. +++ b/security/apparmor/apparmorfs.c
  698. @@ -2346,6 +2346,11 @@ static struct aa_sfs_entry aa_sfs_entry_ns[] = {
  699. { }
  700. };
  701. +static struct aa_sfs_entry aa_sfs_entry_dbus[] = {
  702. + AA_SFS_FILE_STRING("mask", "acquire send receive"),
  703. + { }
  704. +};
  705. +
  706. static struct aa_sfs_entry aa_sfs_entry_query_label[] = {
  707. AA_SFS_FILE_STRING("perms", "allow deny audit quiet"),
  708. AA_SFS_FILE_BOOLEAN("data", 1),
  709. @@ -2370,6 +2375,7 @@ static struct aa_sfs_entry aa_sfs_entry_features[] = {
  710. AA_SFS_DIR("caps", aa_sfs_entry_caps),
  711. AA_SFS_DIR("ptrace", aa_sfs_entry_ptrace),
  712. AA_SFS_DIR("signal", aa_sfs_entry_signal),
  713. + AA_SFS_DIR("dbus", aa_sfs_entry_dbus),
  714. AA_SFS_DIR("query", aa_sfs_entry_query),
  715. { }
  716. };
  717. diff --git a/security/apparmor/file.c b/security/apparmor/file.c
  718. index e1b7e936..866272c 100644
  719. --- a/security/apparmor/file.c
  720. +++ b/security/apparmor/file.c
  721. @@ -14,6 +14,7 @@
  722. #include <linux/fs.h>
  723. #include <linux/mount.h>
  724. +#include "include/af_unix.h"
  725. #include "include/apparmor.h"
  726. #include "include/audit.h"
  727. #include "include/cred.h"
  728. @@ -271,7 +272,8 @@ int __aa_path_perm(const char *op, struct aa_profile *profile, const char *name,
  729. {
  730. int e = 0;
  731. - if (profile_unconfined(profile))
  732. + if (profile_unconfined(profile) ||
  733. + ((flags & PATH_SOCK_COND) && !PROFILE_MEDIATES_AF(profile, AF_UNIX)))
  734. return 0;
  735. aa_str_perms(profile->file.dfa, profile->file.start, name, cond, perms);
  736. if (request & ~perms->allow)
  737. diff --git a/security/apparmor/include/af_unix.h b/security/apparmor/include/af_unix.h
  738. new file mode 100644
  739. index 0000000..d1b7f23
  740. --- /dev/null
  741. +++ b/security/apparmor/include/af_unix.h
  742. @@ -0,0 +1,114 @@
  743. +/*
  744. + * AppArmor security module
  745. + *
  746. + * This file contains AppArmor af_unix fine grained mediation
  747. + *
  748. + * Copyright 2014 Canonical Ltd.
  749. + *
  750. + * This program is free software; you can redistribute it and/or
  751. + * modify it under the terms of the GNU General Public License as
  752. + * published by the Free Software Foundation, version 2 of the
  753. + * License.
  754. + */
  755. +#ifndef __AA_AF_UNIX_H
  756. +
  757. +#include <net/af_unix.h>
  758. +
  759. +#include "label.h"
  760. +//#include "include/net.h"
  761. +
  762. +#define unix_addr_len(L) ((L) - sizeof(sa_family_t))
  763. +#define unix_abstract_name_len(L) (unix_addr_len(L) - 1)
  764. +#define unix_abstract_len(U) (unix_abstract_name_len((U)->addr->len))
  765. +#define addr_unix_abstract_name(B) ((B)[0] == 0)
  766. +#define addr_unix_anonymous(U) (addr_unix_len(U) <= 0)
  767. +#define addr_unix_abstract(U) (!addr_unix_anonymous(U) && addr_unix_abstract_name((U)->addr))
  768. +//#define unix_addr_fs(U) (!unix_addr_anonymous(U) && !unix_addr_abstract_name((U)->addr))
  769. +
  770. +#define unix_addr(A) ((struct sockaddr_un *)(A))
  771. +#define unix_addr_anon(A, L) ((A) && unix_addr_len(L) <= 0)
  772. +#define unix_addr_fs(A, L) (!unix_addr_anon(A, L) && !addr_unix_abstract_name(unix_addr(A)->sun_path))
  773. +
  774. +#define UNIX_ANONYMOUS(U) (!unix_sk(U)->addr)
  775. +/* from net/unix/af_unix.c */
  776. +#define UNIX_ABSTRACT(U) (!UNIX_ANONYMOUS(U) && \
  777. + unix_sk(U)->addr->hash < UNIX_HASH_SIZE)
  778. +#define UNIX_FS(U) (!UNIX_ANONYMOUS(U) && unix_sk(U)->addr->name->sun_path[0])
  779. +#define unix_peer(sk) (unix_sk(sk)->peer)
  780. +#define unix_connected(S) ((S)->state == SS_CONNECTED)
  781. +
  782. +static inline void print_unix_addr(struct sockaddr_un *A, int L)
  783. +{
  784. + char *buf = (A) ? (char *) &(A)->sun_path : NULL;
  785. + int len = unix_addr_len(L);
  786. + if (!buf || len <= 0)
  787. + printk(" <anonymous>");
  788. + else if (buf[0])
  789. + printk(" %s", buf);
  790. + else
  791. + /* abstract name len includes leading \0 */
  792. + printk(" %d @%.*s", len - 1, len - 1, buf+1);
  793. +};
  794. +
  795. +/*
  796. + printk("%s: %s: f %d, t %d, p %d", __FUNCTION__, \
  797. + #SK , \
  798. +*/
  799. +#define print_unix_sk(SK) \
  800. +do { \
  801. + struct unix_sock *u = unix_sk(SK); \
  802. + printk("%s: f %d, t %d, p %d", #SK , \
  803. + (SK)->sk_family, (SK)->sk_type, (SK)->sk_protocol); \
  804. + if (u->addr) \
  805. + print_unix_addr(u->addr->name, u->addr->len); \
  806. + else \
  807. + print_unix_addr(NULL, sizeof(sa_family_t)); \
  808. + /* printk("\n");*/ \
  809. +} while (0)
  810. +
  811. +#define print_sk(SK) \
  812. +do { \
  813. + if (!(SK)) { \
  814. + printk("%s: %s is null\n", __FUNCTION__, #SK); \
  815. + } else if ((SK)->sk_family == PF_UNIX) { \
  816. + print_unix_sk(SK); \
  817. + printk("\n"); \
  818. + } else { \
  819. + printk("%s: %s: family %d\n", __FUNCTION__, #SK , \
  820. + (SK)->sk_family); \
  821. + } \
  822. +} while (0)
  823. +
  824. +#define print_sock_addr(U) \
  825. +do { \
  826. + printk("%s:\n", __FUNCTION__); \
  827. + printk(" sock %s:", sock_ctx && sock_ctx->label ? aa_label_printk(sock_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(sock); \
  828. + printk(" other %s:", other_ctx && other_ctx->label ? aa_label_printk(other_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(other); \
  829. + printk(" new %s", new_ctx && new_ctx->label ? aa_label_printk(new_ctx->label, GFP_ATOMIC); : "<null>"); print_sk(newsk); \
  830. +} while (0)
  831. +
  832. +
  833. +
  834. +
  835. +int aa_unix_peer_perm(struct aa_label *label, const char *op, u32 request,
  836. + struct sock *sk, struct sock *peer_sk,
  837. + struct aa_label *peer_label);
  838. +int aa_unix_label_sk_perm(struct aa_label *label, const char *op, u32 request,
  839. + struct sock *sk);
  840. +int aa_unix_sock_perm(const char *op, u32 request, struct socket *sock);
  841. +int aa_unix_create_perm(struct aa_label *label, int family, int type,
  842. + int protocol);
  843. +int aa_unix_bind_perm(struct socket *sock, struct sockaddr *address,
  844. + int addrlen);
  845. +int aa_unix_connect_perm(struct socket *sock, struct sockaddr *address,
  846. + int addrlen);
  847. +int aa_unix_listen_perm(struct socket *sock, int backlog);
  848. +int aa_unix_accept_perm(struct socket *sock, struct socket *newsock);
  849. +int aa_unix_msg_perm(const char *op, u32 request, struct socket *sock,
  850. + struct msghdr *msg, int size);
  851. +int aa_unix_opt_perm(const char *op, u32 request, struct socket *sock, int level,
  852. + int optname);
  853. +int aa_unix_file_perm(struct aa_label *label, const char *op, u32 request,
  854. + struct socket *sock);
  855. +
  856. +#endif /* __AA_AF_UNIX_H */
  857. diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h
  858. index 98a42ef..b4044fa 100644
  859. --- a/security/apparmor/include/net.h
  860. +++ b/security/apparmor/include/net.h
  861. @@ -49,6 +49,7 @@
  862. struct aa_sk_ctx {
  863. struct aa_label *label;
  864. struct aa_label *peer;
  865. + struct path path;
  866. };
  867. #define SK_CTX(X) ((X)->sk_security)
  868. @@ -83,6 +84,9 @@ struct aa_net_compat {
  869. ({ \
  870. int __e; \
  871. switch ((FAMILY)) { \
  872. + case AF_UNIX: \
  873. + __e = aa_unix_ ## FN; \
  874. + break; \
  875. default: \
  876. __e = DEF_FN; \
  877. } \
  878. diff --git a/security/apparmor/include/path.h b/security/apparmor/include/path.h
  879. index 44a7945..44592cd 100644
  880. --- a/security/apparmor/include/path.h
  881. +++ b/security/apparmor/include/path.h
  882. @@ -13,6 +13,7 @@
  883. enum path_flags {
  884. PATH_IS_DIR = 0x1, /* path is a directory */
  885. + PATH_SOCK_COND = 0x2,
  886. PATH_CONNECT_PATH = 0x4, /* connect disconnected paths to / */
  887. PATH_CHROOT_REL = 0x8, /* do path lookup relative to chroot */
  888. PATH_CHROOT_NSCONNECT = 0x10, /* connect paths that are at ns root */
  889. diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h
  890. index f904105..f1c9cdc 100644
  891. --- a/security/apparmor/include/policy.h
  892. +++ b/security/apparmor/include/policy.h
  893. @@ -230,9 +230,13 @@ static inline unsigned int PROFILE_MEDIATES_AF(struct aa_profile *profile,
  894. unsigned int state = PROFILE_MEDIATES(profile, AA_CLASS_NET);
  895. __be16 be_af = cpu_to_be16(AF);
  896. - if (!state)
  897. - return 0;
  898. - return aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
  899. + if (!state) {
  900. + state = PROFILE_MEDIATES(profile, AA_CLASS_NET_COMPAT);
  901. + if (!state)
  902. + return 0;
  903. + }
  904. + state = aa_dfa_match_len(profile->policy.dfa, state, (char *) &be_af, 2);
  905. + return state;
  906. }
  907. /**
  908. diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
  909. index f72406f..59a8ddd 100644
  910. --- a/security/apparmor/lsm.c
  911. +++ b/security/apparmor/lsm.c
  912. @@ -25,6 +25,7 @@
  913. #include <net/sock.h>
  914. #include <uapi/linux/mount.h>
  915. +#include "include/af_unix.h"
  916. #include "include/apparmor.h"
  917. #include "include/apparmorfs.h"
  918. #include "include/audit.h"
  919. @@ -801,6 +802,7 @@ static void apparmor_sk_free_security(struct sock *sk)
  920. SK_CTX(sk) = NULL;
  921. aa_put_label(ctx->label);
  922. aa_put_label(ctx->peer);
  923. + path_put(&ctx->path);
  924. kfree(ctx);
  925. }
  926. @@ -820,6 +822,99 @@ static void apparmor_sk_clone_security(const struct sock *sk,
  927. if (new->peer)
  928. aa_put_label(new->peer);
  929. new->peer = aa_get_label(ctx->peer);
  930. + new->path = ctx->path;
  931. + path_get(&new->path);
  932. +}
  933. +
  934. +static struct path *UNIX_FS_CONN_PATH(struct sock *sk, struct sock *newsk)
  935. +{
  936. + if (sk->sk_family == PF_UNIX && UNIX_FS(sk))
  937. + return &unix_sk(sk)->path;
  938. + else if (newsk->sk_family == PF_UNIX && UNIX_FS(newsk))
  939. + return &unix_sk(newsk)->path;
  940. + return NULL;
  941. +}
  942. +
  943. +/**
  944. + * apparmor_unix_stream_connect - check perms before making unix domain conn
  945. + *
  946. + * peer is locked when this hook is called
  947. + */
  948. +static int apparmor_unix_stream_connect(struct sock *sk, struct sock *peer_sk,
  949. + struct sock *newsk)
  950. +{
  951. + struct aa_sk_ctx *sk_ctx = SK_CTX(sk);
  952. + struct aa_sk_ctx *peer_ctx = SK_CTX(peer_sk);
  953. + struct aa_sk_ctx *new_ctx = SK_CTX(newsk);
  954. + struct aa_label *label;
  955. + struct path *path;
  956. + int error;
  957. +
  958. + label = __begin_current_label_crit_section();
  959. + error = aa_unix_peer_perm(label, OP_CONNECT,
  960. + (AA_MAY_CONNECT | AA_MAY_SEND | AA_MAY_RECEIVE),
  961. + sk, peer_sk, NULL);
  962. + if (!UNIX_FS(peer_sk)) {
  963. + last_error(error,
  964. + aa_unix_peer_perm(peer_ctx->label, OP_CONNECT,
  965. + (AA_MAY_ACCEPT | AA_MAY_SEND | AA_MAY_RECEIVE),
  966. + peer_sk, sk, label));
  967. + }
  968. + __end_current_label_crit_section(label);
  969. +
  970. + if (error)
  971. + return error;
  972. +
  973. + /* label newsk if it wasn't labeled in post_create. Normally this
  974. + * would be done in sock_graft, but because we are directly looking
  975. + * at the peer_sk to obtain peer_labeling for unix socks this
  976. + * does not work
  977. + */
  978. + if (!new_ctx->label)
  979. + new_ctx->label = aa_get_label(peer_ctx->label);
  980. +
  981. + /* Cross reference the peer labels for SO_PEERSEC */
  982. + if (new_ctx->peer)
  983. + aa_put_label(new_ctx->peer);
  984. +
  985. + if (sk_ctx->peer)
  986. + aa_put_label(sk_ctx->peer);
  987. +
  988. + new_ctx->peer = aa_get_label(sk_ctx->label);
  989. + sk_ctx->peer = aa_get_label(peer_ctx->label);
  990. +
  991. + path = UNIX_FS_CONN_PATH(sk, peer_sk);
  992. + if (path) {
  993. + new_ctx->path = *path;
  994. + sk_ctx->path = *path;
  995. + path_get(path);
  996. + path_get(path);
  997. + }
  998. + return 0;
  999. +}
  1000. +
  1001. +/**
  1002. + * apparmor_unix_may_send - check perms before conn or sending unix dgrams
  1003. + *
  1004. + * other is locked when this hook is called
  1005. + *
  1006. + * dgram connect calls may_send, peer setup but path not copied?????
  1007. + */
  1008. +static int apparmor_unix_may_send(struct socket *sock, struct socket *peer)
  1009. +{
  1010. + struct aa_sk_ctx *peer_ctx = SK_CTX(peer->sk);
  1011. + struct aa_label *label;
  1012. + int error;
  1013. +
  1014. + label = __begin_current_label_crit_section();
  1015. + error = xcheck(aa_unix_peer_perm(label, OP_SENDMSG, AA_MAY_SEND,
  1016. + sock->sk, peer->sk, NULL),
  1017. + aa_unix_peer_perm(peer_ctx->label, OP_SENDMSG,
  1018. + AA_MAY_RECEIVE,
  1019. + peer->sk, sock->sk, label));
  1020. + __end_current_label_crit_section(label);
  1021. +
  1022. + return error;
  1023. }
  1024. /**
  1025. @@ -1065,11 +1160,25 @@ static int apparmor_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
  1026. static struct aa_label *sk_peer_label(struct sock *sk)
  1027. {
  1028. + struct sock *peer_sk;
  1029. struct aa_sk_ctx *ctx = SK_CTX(sk);
  1030. if (ctx->peer)
  1031. return ctx->peer;
  1032. + if (sk->sk_family != PF_UNIX)
  1033. + return ERR_PTR(-ENOPROTOOPT);
  1034. +
  1035. + /* check for sockpair peering which does not go through
  1036. + * security_unix_stream_connect
  1037. + */
  1038. + peer_sk = unix_peer(sk);
  1039. + if (peer_sk) {
  1040. + ctx = SK_CTX(peer_sk);
  1041. + if (ctx->label)
  1042. + return ctx->label;
  1043. + }
  1044. +
  1045. return ERR_PTR(-ENOPROTOOPT);
  1046. }
  1047. @@ -1216,6 +1325,9 @@ static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
  1048. LSM_HOOK_INIT(sk_free_security, apparmor_sk_free_security),
  1049. LSM_HOOK_INIT(sk_clone_security, apparmor_sk_clone_security),
  1050. + LSM_HOOK_INIT(unix_stream_connect, apparmor_unix_stream_connect),
  1051. + LSM_HOOK_INIT(unix_may_send, apparmor_unix_may_send),
  1052. +
  1053. LSM_HOOK_INIT(socket_create, apparmor_socket_create),
  1054. LSM_HOOK_INIT(socket_post_create, apparmor_socket_post_create),
  1055. LSM_HOOK_INIT(socket_bind, apparmor_socket_bind),
  1056. diff --git a/security/apparmor/net.c b/security/apparmor/net.c
  1057. index e693df8..e2e759b 100644
  1058. --- a/security/apparmor/net.c
  1059. +++ b/security/apparmor/net.c
  1060. @@ -8,6 +8,7 @@
  1061. * Copyright 2009-2017 Canonical Ltd.
  1062. */
  1063. +#include "include/af_unix.h"
  1064. #include "include/apparmor.h"
  1065. #include "include/audit.h"
  1066. #include "include/cred.h"
  1067. @@ -26,6 +27,7 @@ struct aa_sfs_entry aa_sfs_entry_network[] = {
  1068. struct aa_sfs_entry aa_sfs_entry_network_compat[] = {
  1069. AA_SFS_FILE_STRING("af_mask", AA_SFS_AF_MASK),
  1070. + AA_SFS_FILE_BOOLEAN("af_unix", 1),
  1071. { }
  1072. };
  1073. @@ -71,6 +73,36 @@ static const char * const net_mask_names[] = {
  1074. "unknown",
  1075. };
  1076. +static void audit_unix_addr(struct audit_buffer *ab, const char *str,
  1077. + struct sockaddr_un *addr, int addrlen)
  1078. +{
  1079. + int len = unix_addr_len(addrlen);
  1080. +
  1081. + if (!addr || len <= 0) {
  1082. + audit_log_format(ab, " %s=none", str);
  1083. + } else if (addr->sun_path[0]) {
  1084. + audit_log_format(ab, " %s=", str);
  1085. + audit_log_untrustedstring(ab, addr->sun_path);
  1086. + } else {
  1087. + audit_log_format(ab, " %s=\"@", str);
  1088. + if (audit_string_contains_control(&addr->sun_path[1], len - 1))
  1089. + audit_log_n_hex(ab, &addr->sun_path[1], len - 1);
  1090. + else
  1091. + audit_log_format(ab, "%.*s", len - 1,
  1092. + &addr->sun_path[1]);
  1093. + audit_log_format(ab, "\"");
  1094. + }
  1095. +}
  1096. +
  1097. +static void audit_unix_sk_addr(struct audit_buffer *ab, const char *str,
  1098. + struct sock *sk)
  1099. +{
  1100. + struct unix_sock *u = unix_sk(sk);
  1101. + if (u && u->addr)
  1102. + audit_unix_addr(ab, str, u->addr->name, u->addr->len);
  1103. + else
  1104. + audit_unix_addr(ab, str, NULL, 0);
  1105. +}
  1106. /* audit callback for net specific fields */
  1107. void audit_net_cb(struct audit_buffer *ab, void *va)
  1108. @@ -102,6 +134,23 @@ void audit_net_cb(struct audit_buffer *ab, void *va)
  1109. net_mask_names, NET_PERMS_MASK);
  1110. }
  1111. }
  1112. + if (sa->u.net->family == AF_UNIX) {
  1113. + if ((aad(sa)->request & ~NET_PEER_MASK) && aad(sa)->net.addr)
  1114. + audit_unix_addr(ab, "addr",
  1115. + unix_addr(aad(sa)->net.addr),
  1116. + aad(sa)->net.addrlen);
  1117. + else
  1118. + audit_unix_sk_addr(ab, "addr", sa->u.net->sk);
  1119. + if (aad(sa)->request & NET_PEER_MASK) {
  1120. + if (aad(sa)->net.addr)
  1121. + audit_unix_addr(ab, "peer_addr",
  1122. + unix_addr(aad(sa)->net.addr),
  1123. + aad(sa)->net.addrlen);
  1124. + else
  1125. + audit_unix_sk_addr(ab, "peer_addr",
  1126. + aad(sa)->net.peer_sk);
  1127. + }
  1128. + }
  1129. if (aad(sa)->peer) {
  1130. audit_log_format(ab, " peer=");
  1131. aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
  1132. @@ -202,7 +251,9 @@ int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request,
  1133. AA_BUG(!sock);
  1134. AA_BUG(!sock->sk);
  1135. - return aa_label_sk_perm(label, op, request, sock->sk);
  1136. + return af_select(sock->sk->sk_family,
  1137. + file_perm(label, op, request, sock),
  1138. + aa_label_sk_perm(label, op, request, sock->sk));
  1139. }
  1140. #ifdef CONFIG_NETWORK_SECMARK