network.c 21 KB

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