network.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * security/tomoyo/network.c
  4. *
  5. * Copyright (C) 2005-2011 NTT DATA CORPORATION
  6. */
  7. #include "common.h"
  8. #include <linux/slab.h>
  9. /* Structure for holding inet domain socket's address. */
  10. struct tomoyo_inet_addr_info {
  11. __be16 port; /* In network byte order. */
  12. const __be32 *address; /* In network byte order. */
  13. bool is_ipv6;
  14. };
  15. /* Structure for holding unix domain socket's address. */
  16. struct tomoyo_unix_addr_info {
  17. u8 *addr; /* This may not be '\0' terminated string. */
  18. unsigned int addr_len;
  19. };
  20. /* Structure for holding socket address. */
  21. struct tomoyo_addr_info {
  22. u8 protocol;
  23. u8 operation;
  24. struct tomoyo_inet_addr_info inet;
  25. struct tomoyo_unix_addr_info unix0;
  26. };
  27. /* String table for socket's protocols. */
  28. const char * const tomoyo_proto_keyword[TOMOYO_SOCK_MAX] = {
  29. [SOCK_STREAM] = "stream",
  30. [SOCK_DGRAM] = "dgram",
  31. [SOCK_RAW] = "raw",
  32. [SOCK_SEQPACKET] = "seqpacket",
  33. [0] = " ", /* Dummy for avoiding NULL pointer dereference. */
  34. [4] = " ", /* Dummy for avoiding NULL pointer dereference. */
  35. };
  36. /**
  37. * tomoyo_parse_ipaddr_union - Parse an IP address.
  38. *
  39. * @param: Pointer to "struct tomoyo_acl_param".
  40. * @ptr: Pointer to "struct tomoyo_ipaddr_union".
  41. *
  42. * Returns true on success, false otherwise.
  43. */
  44. bool tomoyo_parse_ipaddr_union(struct tomoyo_acl_param *param,
  45. struct tomoyo_ipaddr_union *ptr)
  46. {
  47. u8 * const min = ptr->ip[0].in6_u.u6_addr8;
  48. u8 * const max = ptr->ip[1].in6_u.u6_addr8;
  49. char *address = tomoyo_read_token(param);
  50. const char *end;
  51. if (!strchr(address, ':') &&
  52. in4_pton(address, -1, min, '-', &end) > 0) {
  53. ptr->is_ipv6 = false;
  54. if (!*end)
  55. ptr->ip[1].s6_addr32[0] = ptr->ip[0].s6_addr32[0];
  56. else if (*end++ != '-' ||
  57. in4_pton(end, -1, max, '\0', &end) <= 0 || *end)
  58. return false;
  59. return true;
  60. }
  61. if (in6_pton(address, -1, min, '-', &end) > 0) {
  62. ptr->is_ipv6 = true;
  63. if (!*end)
  64. memmove(max, min, sizeof(u16) * 8);
  65. else if (*end++ != '-' ||
  66. in6_pton(end, -1, max, '\0', &end) <= 0 || *end)
  67. return false;
  68. return true;
  69. }
  70. return false;
  71. }
  72. /**
  73. * tomoyo_print_ipv4 - Print an IPv4 address.
  74. *
  75. * @buffer: Buffer to write to.
  76. * @buffer_len: Size of @buffer.
  77. * @min_ip: Pointer to __be32.
  78. * @max_ip: Pointer to __be32.
  79. *
  80. * Returns nothing.
  81. */
  82. static void tomoyo_print_ipv4(char *buffer, const unsigned int buffer_len,
  83. const __be32 *min_ip, const __be32 *max_ip)
  84. {
  85. snprintf(buffer, buffer_len, "%pI4%c%pI4", min_ip,
  86. *min_ip == *max_ip ? '\0' : '-', max_ip);
  87. }
  88. /**
  89. * tomoyo_print_ipv6 - Print an IPv6 address.
  90. *
  91. * @buffer: Buffer to write to.
  92. * @buffer_len: Size of @buffer.
  93. * @min_ip: Pointer to "struct in6_addr".
  94. * @max_ip: Pointer to "struct in6_addr".
  95. *
  96. * Returns nothing.
  97. */
  98. static void tomoyo_print_ipv6(char *buffer, const unsigned int buffer_len,
  99. const struct in6_addr *min_ip,
  100. const struct in6_addr *max_ip)
  101. {
  102. snprintf(buffer, buffer_len, "%pI6c%c%pI6c", min_ip,
  103. !memcmp(min_ip, max_ip, 16) ? '\0' : '-', max_ip);
  104. }
  105. /**
  106. * tomoyo_print_ip - Print an IP address.
  107. *
  108. * @buf: Buffer to write to.
  109. * @size: Size of @buf.
  110. * @ptr: Pointer to "struct ipaddr_union".
  111. *
  112. * Returns nothing.
  113. */
  114. void tomoyo_print_ip(char *buf, const unsigned int size,
  115. const struct tomoyo_ipaddr_union *ptr)
  116. {
  117. if (ptr->is_ipv6)
  118. tomoyo_print_ipv6(buf, size, &ptr->ip[0], &ptr->ip[1]);
  119. else
  120. tomoyo_print_ipv4(buf, size, &ptr->ip[0].s6_addr32[0],
  121. &ptr->ip[1].s6_addr32[0]);
  122. }
  123. /*
  124. * Mapping table from "enum tomoyo_network_acl_index" to
  125. * "enum tomoyo_mac_index" for inet domain socket.
  126. */
  127. static const u8 tomoyo_inet2mac
  128. [TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
  129. [SOCK_STREAM] = {
  130. [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_STREAM_BIND,
  131. [TOMOYO_NETWORK_LISTEN] =
  132. TOMOYO_MAC_NETWORK_INET_STREAM_LISTEN,
  133. [TOMOYO_NETWORK_CONNECT] =
  134. TOMOYO_MAC_NETWORK_INET_STREAM_CONNECT,
  135. },
  136. [SOCK_DGRAM] = {
  137. [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_DGRAM_BIND,
  138. [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_DGRAM_SEND,
  139. },
  140. [SOCK_RAW] = {
  141. [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_INET_RAW_BIND,
  142. [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_INET_RAW_SEND,
  143. },
  144. };
  145. /*
  146. * Mapping table from "enum tomoyo_network_acl_index" to
  147. * "enum tomoyo_mac_index" for unix domain socket.
  148. */
  149. static const u8 tomoyo_unix2mac
  150. [TOMOYO_SOCK_MAX][TOMOYO_MAX_NETWORK_OPERATION] = {
  151. [SOCK_STREAM] = {
  152. [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_STREAM_BIND,
  153. [TOMOYO_NETWORK_LISTEN] =
  154. TOMOYO_MAC_NETWORK_UNIX_STREAM_LISTEN,
  155. [TOMOYO_NETWORK_CONNECT] =
  156. TOMOYO_MAC_NETWORK_UNIX_STREAM_CONNECT,
  157. },
  158. [SOCK_DGRAM] = {
  159. [TOMOYO_NETWORK_BIND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_BIND,
  160. [TOMOYO_NETWORK_SEND] = TOMOYO_MAC_NETWORK_UNIX_DGRAM_SEND,
  161. },
  162. [SOCK_SEQPACKET] = {
  163. [TOMOYO_NETWORK_BIND] =
  164. TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_BIND,
  165. [TOMOYO_NETWORK_LISTEN] =
  166. TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_LISTEN,
  167. [TOMOYO_NETWORK_CONNECT] =
  168. TOMOYO_MAC_NETWORK_UNIX_SEQPACKET_CONNECT,
  169. },
  170. };
  171. /**
  172. * tomoyo_same_inet_acl - Check for duplicated "struct tomoyo_inet_acl" entry.
  173. *
  174. * @a: Pointer to "struct tomoyo_acl_info".
  175. * @b: Pointer to "struct tomoyo_acl_info".
  176. *
  177. * Returns true if @a == @b except permission bits, false otherwise.
  178. */
  179. static bool tomoyo_same_inet_acl(const struct tomoyo_acl_info *a,
  180. const struct tomoyo_acl_info *b)
  181. {
  182. const struct tomoyo_inet_acl *p1 = container_of(a, typeof(*p1), head);
  183. const struct tomoyo_inet_acl *p2 = container_of(b, typeof(*p2), head);
  184. return p1->protocol == p2->protocol &&
  185. tomoyo_same_ipaddr_union(&p1->address, &p2->address) &&
  186. tomoyo_same_number_union(&p1->port, &p2->port);
  187. }
  188. /**
  189. * tomoyo_same_unix_acl - Check for duplicated "struct tomoyo_unix_acl" entry.
  190. *
  191. * @a: Pointer to "struct tomoyo_acl_info".
  192. * @b: Pointer to "struct tomoyo_acl_info".
  193. *
  194. * Returns true if @a == @b except permission bits, false otherwise.
  195. */
  196. static bool tomoyo_same_unix_acl(const struct tomoyo_acl_info *a,
  197. const struct tomoyo_acl_info *b)
  198. {
  199. const struct tomoyo_unix_acl *p1 = container_of(a, typeof(*p1), head);
  200. const struct tomoyo_unix_acl *p2 = container_of(b, typeof(*p2), head);
  201. return p1->protocol == p2->protocol &&
  202. tomoyo_same_name_union(&p1->name, &p2->name);
  203. }
  204. /**
  205. * tomoyo_merge_inet_acl - Merge duplicated "struct tomoyo_inet_acl" entry.
  206. *
  207. * @a: Pointer to "struct tomoyo_acl_info".
  208. * @b: Pointer to "struct tomoyo_acl_info".
  209. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  210. *
  211. * Returns true if @a is empty, false otherwise.
  212. */
  213. static bool tomoyo_merge_inet_acl(struct tomoyo_acl_info *a,
  214. struct tomoyo_acl_info *b,
  215. const bool is_delete)
  216. {
  217. u8 * const a_perm =
  218. &container_of(a, struct tomoyo_inet_acl, head)->perm;
  219. u8 perm = *a_perm;
  220. const u8 b_perm = container_of(b, struct tomoyo_inet_acl, head)->perm;
  221. if (is_delete)
  222. perm &= ~b_perm;
  223. else
  224. perm |= b_perm;
  225. *a_perm = perm;
  226. return !perm;
  227. }
  228. /**
  229. * tomoyo_merge_unix_acl - Merge duplicated "struct tomoyo_unix_acl" entry.
  230. *
  231. * @a: Pointer to "struct tomoyo_acl_info".
  232. * @b: Pointer to "struct tomoyo_acl_info".
  233. * @is_delete: True for @a &= ~@b, false for @a |= @b.
  234. *
  235. * Returns true if @a is empty, false otherwise.
  236. */
  237. static bool tomoyo_merge_unix_acl(struct tomoyo_acl_info *a,
  238. struct tomoyo_acl_info *b,
  239. const bool is_delete)
  240. {
  241. u8 * const a_perm =
  242. &container_of(a, struct tomoyo_unix_acl, head)->perm;
  243. u8 perm = *a_perm;
  244. const u8 b_perm = container_of(b, struct tomoyo_unix_acl, head)->perm;
  245. if (is_delete)
  246. perm &= ~b_perm;
  247. else
  248. perm |= b_perm;
  249. *a_perm = perm;
  250. return !perm;
  251. }
  252. /**
  253. * tomoyo_write_inet_network - Write "struct tomoyo_inet_acl" list.
  254. *
  255. * @param: Pointer to "struct tomoyo_acl_param".
  256. *
  257. * Returns 0 on success, negative value otherwise.
  258. *
  259. * Caller holds tomoyo_read_lock().
  260. */
  261. int tomoyo_write_inet_network(struct tomoyo_acl_param *param)
  262. {
  263. struct tomoyo_inet_acl e = { .head.type = TOMOYO_TYPE_INET_ACL };
  264. int error = -EINVAL;
  265. u8 type;
  266. const char *protocol = tomoyo_read_token(param);
  267. const char *operation = tomoyo_read_token(param);
  268. for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
  269. if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
  270. break;
  271. for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
  272. if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
  273. e.perm |= 1 << type;
  274. if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
  275. return -EINVAL;
  276. if (param->data[0] == '@') {
  277. param->data++;
  278. e.address.group =
  279. tomoyo_get_group(param, TOMOYO_ADDRESS_GROUP);
  280. if (!e.address.group)
  281. return -ENOMEM;
  282. } else {
  283. if (!tomoyo_parse_ipaddr_union(param, &e.address))
  284. goto out;
  285. }
  286. if (!tomoyo_parse_number_union(param, &e.port) ||
  287. e.port.values[1] > 65535)
  288. goto out;
  289. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  290. tomoyo_same_inet_acl,
  291. tomoyo_merge_inet_acl);
  292. out:
  293. tomoyo_put_group(e.address.group);
  294. tomoyo_put_number_union(&e.port);
  295. return error;
  296. }
  297. /**
  298. * tomoyo_write_unix_network - Write "struct tomoyo_unix_acl" list.
  299. *
  300. * @param: Pointer to "struct tomoyo_acl_param".
  301. *
  302. * Returns 0 on success, negative value otherwise.
  303. */
  304. int tomoyo_write_unix_network(struct tomoyo_acl_param *param)
  305. {
  306. struct tomoyo_unix_acl e = { .head.type = TOMOYO_TYPE_UNIX_ACL };
  307. int error;
  308. u8 type;
  309. const char *protocol = tomoyo_read_token(param);
  310. const char *operation = tomoyo_read_token(param);
  311. for (e.protocol = 0; e.protocol < TOMOYO_SOCK_MAX; e.protocol++)
  312. if (!strcmp(protocol, tomoyo_proto_keyword[e.protocol]))
  313. break;
  314. for (type = 0; type < TOMOYO_MAX_NETWORK_OPERATION; type++)
  315. if (tomoyo_permstr(operation, tomoyo_socket_keyword[type]))
  316. e.perm |= 1 << type;
  317. if (e.protocol == TOMOYO_SOCK_MAX || !e.perm)
  318. return -EINVAL;
  319. if (!tomoyo_parse_name_union(param, &e.name))
  320. return -EINVAL;
  321. error = tomoyo_update_domain(&e.head, sizeof(e), param,
  322. tomoyo_same_unix_acl,
  323. tomoyo_merge_unix_acl);
  324. tomoyo_put_name_union(&e.name);
  325. return error;
  326. }
  327. /**
  328. * tomoyo_audit_net_log - Audit network log.
  329. *
  330. * @r: Pointer to "struct tomoyo_request_info".
  331. * @family: Name of socket family ("inet" or "unix").
  332. * @protocol: Name of protocol in @family.
  333. * @operation: Name of socket operation.
  334. * @address: Name of address.
  335. *
  336. * Returns 0 on success, negative value otherwise.
  337. */
  338. static int tomoyo_audit_net_log(struct tomoyo_request_info *r,
  339. const char *family, const u8 protocol,
  340. const u8 operation, const char *address)
  341. {
  342. return tomoyo_supervisor(r, "network %s %s %s %s\n", family,
  343. tomoyo_proto_keyword[protocol],
  344. tomoyo_socket_keyword[operation], address);
  345. }
  346. /**
  347. * tomoyo_audit_inet_log - Audit INET network log.
  348. *
  349. * @r: Pointer to "struct tomoyo_request_info".
  350. *
  351. * Returns 0 on success, negative value otherwise.
  352. */
  353. static int tomoyo_audit_inet_log(struct tomoyo_request_info *r)
  354. {
  355. char buf[128];
  356. int len;
  357. const __be32 *address = r->param.inet_network.address;
  358. if (r->param.inet_network.is_ipv6)
  359. tomoyo_print_ipv6(buf, sizeof(buf), (const struct in6_addr *)
  360. address, (const struct in6_addr *) address);
  361. else
  362. tomoyo_print_ipv4(buf, sizeof(buf), address, address);
  363. len = strlen(buf);
  364. snprintf(buf + len, sizeof(buf) - len, " %u",
  365. r->param.inet_network.port);
  366. return tomoyo_audit_net_log(r, "inet", r->param.inet_network.protocol,
  367. r->param.inet_network.operation, buf);
  368. }
  369. /**
  370. * tomoyo_audit_unix_log - Audit UNIX network log.
  371. *
  372. * @r: Pointer to "struct tomoyo_request_info".
  373. *
  374. * Returns 0 on success, negative value otherwise.
  375. */
  376. static int tomoyo_audit_unix_log(struct tomoyo_request_info *r)
  377. {
  378. return tomoyo_audit_net_log(r, "unix", r->param.unix_network.protocol,
  379. r->param.unix_network.operation,
  380. r->param.unix_network.address->name);
  381. }
  382. /**
  383. * tomoyo_check_inet_acl - Check permission for inet domain socket operation.
  384. *
  385. * @r: Pointer to "struct tomoyo_request_info".
  386. * @ptr: Pointer to "struct tomoyo_acl_info".
  387. *
  388. * Returns true if granted, false otherwise.
  389. */
  390. static bool tomoyo_check_inet_acl(struct tomoyo_request_info *r,
  391. const struct tomoyo_acl_info *ptr)
  392. {
  393. const struct tomoyo_inet_acl *acl =
  394. container_of(ptr, typeof(*acl), head);
  395. const u8 size = r->param.inet_network.is_ipv6 ? 16 : 4;
  396. if (!(acl->perm & (1 << r->param.inet_network.operation)) ||
  397. !tomoyo_compare_number_union(r->param.inet_network.port,
  398. &acl->port))
  399. return false;
  400. if (acl->address.group)
  401. return tomoyo_address_matches_group
  402. (r->param.inet_network.is_ipv6,
  403. r->param.inet_network.address, acl->address.group);
  404. return acl->address.is_ipv6 == r->param.inet_network.is_ipv6 &&
  405. memcmp(&acl->address.ip[0],
  406. r->param.inet_network.address, size) <= 0 &&
  407. memcmp(r->param.inet_network.address,
  408. &acl->address.ip[1], size) <= 0;
  409. }
  410. /**
  411. * tomoyo_check_unix_acl - Check permission for unix domain socket operation.
  412. *
  413. * @r: Pointer to "struct tomoyo_request_info".
  414. * @ptr: Pointer to "struct tomoyo_acl_info".
  415. *
  416. * Returns true if granted, false otherwise.
  417. */
  418. static bool tomoyo_check_unix_acl(struct tomoyo_request_info *r,
  419. const struct tomoyo_acl_info *ptr)
  420. {
  421. const struct tomoyo_unix_acl *acl =
  422. container_of(ptr, typeof(*acl), head);
  423. return (acl->perm & (1 << r->param.unix_network.operation)) &&
  424. tomoyo_compare_name_union(r->param.unix_network.address,
  425. &acl->name);
  426. }
  427. /**
  428. * tomoyo_inet_entry - Check permission for INET network operation.
  429. *
  430. * @address: Pointer to "struct tomoyo_addr_info".
  431. *
  432. * Returns 0 on success, negative value otherwise.
  433. */
  434. static int tomoyo_inet_entry(const struct tomoyo_addr_info *address)
  435. {
  436. const int idx = tomoyo_read_lock();
  437. struct tomoyo_request_info r;
  438. int error = 0;
  439. const u8 type = tomoyo_inet2mac[address->protocol][address->operation];
  440. if (type && tomoyo_init_request_info(&r, NULL, type)
  441. != TOMOYO_CONFIG_DISABLED) {
  442. r.param_type = TOMOYO_TYPE_INET_ACL;
  443. r.param.inet_network.protocol = address->protocol;
  444. r.param.inet_network.operation = address->operation;
  445. r.param.inet_network.is_ipv6 = address->inet.is_ipv6;
  446. r.param.inet_network.address = address->inet.address;
  447. r.param.inet_network.port = ntohs(address->inet.port);
  448. do {
  449. tomoyo_check_acl(&r, tomoyo_check_inet_acl);
  450. error = tomoyo_audit_inet_log(&r);
  451. } while (error == TOMOYO_RETRY_REQUEST);
  452. }
  453. tomoyo_read_unlock(idx);
  454. return error;
  455. }
  456. /**
  457. * tomoyo_check_inet_address - Check permission for inet domain socket's operation.
  458. *
  459. * @addr: Pointer to "struct sockaddr".
  460. * @addr_len: Size of @addr.
  461. * @port: Port number.
  462. * @address: Pointer to "struct tomoyo_addr_info".
  463. *
  464. * Returns 0 on success, negative value otherwise.
  465. */
  466. static int tomoyo_check_inet_address(const struct sockaddr *addr,
  467. const unsigned int addr_len,
  468. const u16 port,
  469. struct tomoyo_addr_info *address)
  470. {
  471. struct tomoyo_inet_addr_info *i = &address->inet;
  472. switch (addr->sa_family) {
  473. case AF_INET6:
  474. if (addr_len < SIN6_LEN_RFC2133)
  475. goto skip;
  476. i->is_ipv6 = true;
  477. i->address = (__be32 *)
  478. ((struct sockaddr_in6 *) addr)->sin6_addr.s6_addr;
  479. i->port = ((struct sockaddr_in6 *) addr)->sin6_port;
  480. break;
  481. case AF_INET:
  482. if (addr_len < sizeof(struct sockaddr_in))
  483. goto skip;
  484. i->is_ipv6 = false;
  485. i->address = (__be32 *)
  486. &((struct sockaddr_in *) addr)->sin_addr;
  487. i->port = ((struct sockaddr_in *) addr)->sin_port;
  488. break;
  489. default:
  490. goto skip;
  491. }
  492. if (address->protocol == SOCK_RAW)
  493. i->port = htons(port);
  494. return tomoyo_inet_entry(address);
  495. skip:
  496. return 0;
  497. }
  498. /**
  499. * tomoyo_unix_entry - Check permission for UNIX network operation.
  500. *
  501. * @address: Pointer to "struct tomoyo_addr_info".
  502. *
  503. * Returns 0 on success, negative value otherwise.
  504. */
  505. static int tomoyo_unix_entry(const struct tomoyo_addr_info *address)
  506. {
  507. const int idx = tomoyo_read_lock();
  508. struct tomoyo_request_info r;
  509. int error = 0;
  510. const u8 type = tomoyo_unix2mac[address->protocol][address->operation];
  511. if (type && tomoyo_init_request_info(&r, NULL, type)
  512. != TOMOYO_CONFIG_DISABLED) {
  513. char *buf = address->unix0.addr;
  514. int len = address->unix0.addr_len - sizeof(sa_family_t);
  515. if (len <= 0) {
  516. buf = "anonymous";
  517. len = 9;
  518. } else if (buf[0]) {
  519. len = strnlen(buf, len);
  520. }
  521. buf = tomoyo_encode2(buf, len);
  522. if (buf) {
  523. struct tomoyo_path_info addr;
  524. addr.name = buf;
  525. tomoyo_fill_path_info(&addr);
  526. r.param_type = TOMOYO_TYPE_UNIX_ACL;
  527. r.param.unix_network.protocol = address->protocol;
  528. r.param.unix_network.operation = address->operation;
  529. r.param.unix_network.address = &addr;
  530. do {
  531. tomoyo_check_acl(&r, tomoyo_check_unix_acl);
  532. error = tomoyo_audit_unix_log(&r);
  533. } while (error == TOMOYO_RETRY_REQUEST);
  534. kfree(buf);
  535. } else
  536. error = -ENOMEM;
  537. }
  538. tomoyo_read_unlock(idx);
  539. return error;
  540. }
  541. /**
  542. * tomoyo_check_unix_address - Check permission for unix domain socket's operation.
  543. *
  544. * @addr: Pointer to "struct sockaddr".
  545. * @addr_len: Size of @addr.
  546. * @address: Pointer to "struct tomoyo_addr_info".
  547. *
  548. * Returns 0 on success, negative value otherwise.
  549. */
  550. static int tomoyo_check_unix_address(struct sockaddr *addr,
  551. const unsigned int addr_len,
  552. struct tomoyo_addr_info *address)
  553. {
  554. struct tomoyo_unix_addr_info *u = &address->unix0;
  555. if (addr->sa_family != AF_UNIX)
  556. return 0;
  557. u->addr = ((struct sockaddr_un *) addr)->sun_path;
  558. u->addr_len = addr_len;
  559. return tomoyo_unix_entry(address);
  560. }
  561. /**
  562. * tomoyo_kernel_service - Check whether I'm kernel service or not.
  563. *
  564. * Returns true if I'm kernel service, false otherwise.
  565. */
  566. static bool tomoyo_kernel_service(void)
  567. {
  568. /* Nothing to do if I am a kernel service. */
  569. return uaccess_kernel();
  570. }
  571. /**
  572. * tomoyo_sock_family - Get socket's family.
  573. *
  574. * @sk: Pointer to "struct sock".
  575. *
  576. * Returns one of PF_INET, PF_INET6, PF_UNIX or 0.
  577. */
  578. static u8 tomoyo_sock_family(struct sock *sk)
  579. {
  580. u8 family;
  581. if (tomoyo_kernel_service())
  582. return 0;
  583. family = sk->sk_family;
  584. switch (family) {
  585. case PF_INET:
  586. case PF_INET6:
  587. case PF_UNIX:
  588. return family;
  589. default:
  590. return 0;
  591. }
  592. }
  593. /**
  594. * tomoyo_socket_listen_permission - Check permission for listening a socket.
  595. *
  596. * @sock: Pointer to "struct socket".
  597. *
  598. * Returns 0 on success, negative value otherwise.
  599. */
  600. int tomoyo_socket_listen_permission(struct socket *sock)
  601. {
  602. struct tomoyo_addr_info address;
  603. const u8 family = tomoyo_sock_family(sock->sk);
  604. const unsigned int type = sock->type;
  605. struct sockaddr_storage addr;
  606. int addr_len;
  607. if (!family || (type != SOCK_STREAM && type != SOCK_SEQPACKET))
  608. return 0;
  609. {
  610. const int error = sock->ops->getname(sock, (struct sockaddr *)
  611. &addr, &addr_len, 0);
  612. if (error)
  613. return error;
  614. }
  615. address.protocol = type;
  616. address.operation = TOMOYO_NETWORK_LISTEN;
  617. if (family == PF_UNIX)
  618. return tomoyo_check_unix_address((struct sockaddr *) &addr,
  619. addr_len, &address);
  620. return tomoyo_check_inet_address((struct sockaddr *) &addr, addr_len,
  621. 0, &address);
  622. }
  623. /**
  624. * tomoyo_socket_connect_permission - Check permission for setting the remote address of a socket.
  625. *
  626. * @sock: Pointer to "struct socket".
  627. * @addr: Pointer to "struct sockaddr".
  628. * @addr_len: Size of @addr.
  629. *
  630. * Returns 0 on success, negative value otherwise.
  631. */
  632. int tomoyo_socket_connect_permission(struct socket *sock,
  633. struct sockaddr *addr, int addr_len)
  634. {
  635. struct tomoyo_addr_info address;
  636. const u8 family = tomoyo_sock_family(sock->sk);
  637. const unsigned int type = sock->type;
  638. if (!family)
  639. return 0;
  640. address.protocol = type;
  641. switch (type) {
  642. case SOCK_DGRAM:
  643. case SOCK_RAW:
  644. address.operation = TOMOYO_NETWORK_SEND;
  645. break;
  646. case SOCK_STREAM:
  647. case SOCK_SEQPACKET:
  648. address.operation = TOMOYO_NETWORK_CONNECT;
  649. break;
  650. default:
  651. return 0;
  652. }
  653. if (family == PF_UNIX)
  654. return tomoyo_check_unix_address(addr, addr_len, &address);
  655. return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
  656. &address);
  657. }
  658. /**
  659. * tomoyo_socket_bind_permission - Check permission for setting the local address of a socket.
  660. *
  661. * @sock: Pointer to "struct socket".
  662. * @addr: Pointer to "struct sockaddr".
  663. * @addr_len: Size of @addr.
  664. *
  665. * Returns 0 on success, negative value otherwise.
  666. */
  667. int tomoyo_socket_bind_permission(struct socket *sock, struct sockaddr *addr,
  668. int addr_len)
  669. {
  670. struct tomoyo_addr_info address;
  671. const u8 family = tomoyo_sock_family(sock->sk);
  672. const unsigned int type = sock->type;
  673. if (!family)
  674. return 0;
  675. switch (type) {
  676. case SOCK_STREAM:
  677. case SOCK_DGRAM:
  678. case SOCK_RAW:
  679. case SOCK_SEQPACKET:
  680. address.protocol = type;
  681. address.operation = TOMOYO_NETWORK_BIND;
  682. break;
  683. default:
  684. return 0;
  685. }
  686. if (family == PF_UNIX)
  687. return tomoyo_check_unix_address(addr, addr_len, &address);
  688. return tomoyo_check_inet_address(addr, addr_len, sock->sk->sk_protocol,
  689. &address);
  690. }
  691. /**
  692. * tomoyo_socket_sendmsg_permission - Check permission for sending a datagram.
  693. *
  694. * @sock: Pointer to "struct socket".
  695. * @msg: Pointer to "struct msghdr".
  696. * @size: Unused.
  697. *
  698. * Returns 0 on success, negative value otherwise.
  699. */
  700. int tomoyo_socket_sendmsg_permission(struct socket *sock, struct msghdr *msg,
  701. int size)
  702. {
  703. struct tomoyo_addr_info address;
  704. const u8 family = tomoyo_sock_family(sock->sk);
  705. const unsigned int type = sock->type;
  706. if (!msg->msg_name || !family ||
  707. (type != SOCK_DGRAM && type != SOCK_RAW))
  708. return 0;
  709. address.protocol = type;
  710. address.operation = TOMOYO_NETWORK_SEND;
  711. if (family == PF_UNIX)
  712. return tomoyo_check_unix_address((struct sockaddr *)
  713. msg->msg_name,
  714. msg->msg_namelen, &address);
  715. return tomoyo_check_inet_address((struct sockaddr *) msg->msg_name,
  716. msg->msg_namelen,
  717. sock->sk->sk_protocol, &address);
  718. }