test_sock_addr.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (c) 2018 Facebook
  3. #define _GNU_SOURCE
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <arpa/inet.h>
  8. #include <netinet/in.h>
  9. #include <sys/types.h>
  10. #include <sys/select.h>
  11. #include <sys/socket.h>
  12. #include <linux/filter.h>
  13. #include <bpf/bpf.h>
  14. #include <bpf/libbpf.h>
  15. #include "cgroup_helpers.h"
  16. #include "bpf_rlimit.h"
  17. #ifndef ENOTSUPP
  18. # define ENOTSUPP 524
  19. #endif
  20. #ifndef ARRAY_SIZE
  21. # define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
  22. #endif
  23. #define CG_PATH "/foo"
  24. #define CONNECT4_PROG_PATH "./connect4_prog.o"
  25. #define CONNECT6_PROG_PATH "./connect6_prog.o"
  26. #define SENDMSG4_PROG_PATH "./sendmsg4_prog.o"
  27. #define SENDMSG6_PROG_PATH "./sendmsg6_prog.o"
  28. #define SERV4_IP "192.168.1.254"
  29. #define SERV4_REWRITE_IP "127.0.0.1"
  30. #define SRC4_IP "172.16.0.1"
  31. #define SRC4_REWRITE_IP "127.0.0.4"
  32. #define SERV4_PORT 4040
  33. #define SERV4_REWRITE_PORT 4444
  34. #define SERV6_IP "face:b00c:1234:5678::abcd"
  35. #define SERV6_REWRITE_IP "::1"
  36. #define SERV6_V4MAPPED_IP "::ffff:192.168.0.4"
  37. #define SRC6_IP "::1"
  38. #define SRC6_REWRITE_IP "::6"
  39. #define SERV6_PORT 6060
  40. #define SERV6_REWRITE_PORT 6666
  41. #define INET_NTOP_BUF 40
  42. struct sock_addr_test;
  43. typedef int (*load_fn)(const struct sock_addr_test *test);
  44. typedef int (*info_fn)(int, struct sockaddr *, socklen_t *);
  45. char bpf_log_buf[BPF_LOG_BUF_SIZE];
  46. struct sock_addr_test {
  47. const char *descr;
  48. /* BPF prog properties */
  49. load_fn loadfn;
  50. enum bpf_attach_type expected_attach_type;
  51. enum bpf_attach_type attach_type;
  52. /* Socket properties */
  53. int domain;
  54. int type;
  55. /* IP:port pairs for BPF prog to override */
  56. const char *requested_ip;
  57. unsigned short requested_port;
  58. const char *expected_ip;
  59. unsigned short expected_port;
  60. const char *expected_src_ip;
  61. /* Expected test result */
  62. enum {
  63. LOAD_REJECT,
  64. ATTACH_REJECT,
  65. SYSCALL_EPERM,
  66. SYSCALL_ENOTSUPP,
  67. SUCCESS,
  68. } expected_result;
  69. };
  70. static int bind4_prog_load(const struct sock_addr_test *test);
  71. static int bind6_prog_load(const struct sock_addr_test *test);
  72. static int connect4_prog_load(const struct sock_addr_test *test);
  73. static int connect6_prog_load(const struct sock_addr_test *test);
  74. static int sendmsg_deny_prog_load(const struct sock_addr_test *test);
  75. static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test);
  76. static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test);
  77. static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test);
  78. static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test);
  79. static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test);
  80. static struct sock_addr_test tests[] = {
  81. /* bind */
  82. {
  83. "bind4: load prog with wrong expected attach type",
  84. bind4_prog_load,
  85. BPF_CGROUP_INET6_BIND,
  86. BPF_CGROUP_INET4_BIND,
  87. AF_INET,
  88. SOCK_STREAM,
  89. NULL,
  90. 0,
  91. NULL,
  92. 0,
  93. NULL,
  94. LOAD_REJECT,
  95. },
  96. {
  97. "bind4: attach prog with wrong attach type",
  98. bind4_prog_load,
  99. BPF_CGROUP_INET4_BIND,
  100. BPF_CGROUP_INET6_BIND,
  101. AF_INET,
  102. SOCK_STREAM,
  103. NULL,
  104. 0,
  105. NULL,
  106. 0,
  107. NULL,
  108. ATTACH_REJECT,
  109. },
  110. {
  111. "bind4: rewrite IP & TCP port in",
  112. bind4_prog_load,
  113. BPF_CGROUP_INET4_BIND,
  114. BPF_CGROUP_INET4_BIND,
  115. AF_INET,
  116. SOCK_STREAM,
  117. SERV4_IP,
  118. SERV4_PORT,
  119. SERV4_REWRITE_IP,
  120. SERV4_REWRITE_PORT,
  121. NULL,
  122. SUCCESS,
  123. },
  124. {
  125. "bind4: rewrite IP & UDP port in",
  126. bind4_prog_load,
  127. BPF_CGROUP_INET4_BIND,
  128. BPF_CGROUP_INET4_BIND,
  129. AF_INET,
  130. SOCK_DGRAM,
  131. SERV4_IP,
  132. SERV4_PORT,
  133. SERV4_REWRITE_IP,
  134. SERV4_REWRITE_PORT,
  135. NULL,
  136. SUCCESS,
  137. },
  138. {
  139. "bind6: load prog with wrong expected attach type",
  140. bind6_prog_load,
  141. BPF_CGROUP_INET4_BIND,
  142. BPF_CGROUP_INET6_BIND,
  143. AF_INET6,
  144. SOCK_STREAM,
  145. NULL,
  146. 0,
  147. NULL,
  148. 0,
  149. NULL,
  150. LOAD_REJECT,
  151. },
  152. {
  153. "bind6: attach prog with wrong attach type",
  154. bind6_prog_load,
  155. BPF_CGROUP_INET6_BIND,
  156. BPF_CGROUP_INET4_BIND,
  157. AF_INET,
  158. SOCK_STREAM,
  159. NULL,
  160. 0,
  161. NULL,
  162. 0,
  163. NULL,
  164. ATTACH_REJECT,
  165. },
  166. {
  167. "bind6: rewrite IP & TCP port in",
  168. bind6_prog_load,
  169. BPF_CGROUP_INET6_BIND,
  170. BPF_CGROUP_INET6_BIND,
  171. AF_INET6,
  172. SOCK_STREAM,
  173. SERV6_IP,
  174. SERV6_PORT,
  175. SERV6_REWRITE_IP,
  176. SERV6_REWRITE_PORT,
  177. NULL,
  178. SUCCESS,
  179. },
  180. {
  181. "bind6: rewrite IP & UDP port in",
  182. bind6_prog_load,
  183. BPF_CGROUP_INET6_BIND,
  184. BPF_CGROUP_INET6_BIND,
  185. AF_INET6,
  186. SOCK_DGRAM,
  187. SERV6_IP,
  188. SERV6_PORT,
  189. SERV6_REWRITE_IP,
  190. SERV6_REWRITE_PORT,
  191. NULL,
  192. SUCCESS,
  193. },
  194. /* connect */
  195. {
  196. "connect4: load prog with wrong expected attach type",
  197. connect4_prog_load,
  198. BPF_CGROUP_INET6_CONNECT,
  199. BPF_CGROUP_INET4_CONNECT,
  200. AF_INET,
  201. SOCK_STREAM,
  202. NULL,
  203. 0,
  204. NULL,
  205. 0,
  206. NULL,
  207. LOAD_REJECT,
  208. },
  209. {
  210. "connect4: attach prog with wrong attach type",
  211. connect4_prog_load,
  212. BPF_CGROUP_INET4_CONNECT,
  213. BPF_CGROUP_INET6_CONNECT,
  214. AF_INET,
  215. SOCK_STREAM,
  216. NULL,
  217. 0,
  218. NULL,
  219. 0,
  220. NULL,
  221. ATTACH_REJECT,
  222. },
  223. {
  224. "connect4: rewrite IP & TCP port",
  225. connect4_prog_load,
  226. BPF_CGROUP_INET4_CONNECT,
  227. BPF_CGROUP_INET4_CONNECT,
  228. AF_INET,
  229. SOCK_STREAM,
  230. SERV4_IP,
  231. SERV4_PORT,
  232. SERV4_REWRITE_IP,
  233. SERV4_REWRITE_PORT,
  234. SRC4_REWRITE_IP,
  235. SUCCESS,
  236. },
  237. {
  238. "connect4: rewrite IP & UDP port",
  239. connect4_prog_load,
  240. BPF_CGROUP_INET4_CONNECT,
  241. BPF_CGROUP_INET4_CONNECT,
  242. AF_INET,
  243. SOCK_DGRAM,
  244. SERV4_IP,
  245. SERV4_PORT,
  246. SERV4_REWRITE_IP,
  247. SERV4_REWRITE_PORT,
  248. SRC4_REWRITE_IP,
  249. SUCCESS,
  250. },
  251. {
  252. "connect6: load prog with wrong expected attach type",
  253. connect6_prog_load,
  254. BPF_CGROUP_INET4_CONNECT,
  255. BPF_CGROUP_INET6_CONNECT,
  256. AF_INET6,
  257. SOCK_STREAM,
  258. NULL,
  259. 0,
  260. NULL,
  261. 0,
  262. NULL,
  263. LOAD_REJECT,
  264. },
  265. {
  266. "connect6: attach prog with wrong attach type",
  267. connect6_prog_load,
  268. BPF_CGROUP_INET6_CONNECT,
  269. BPF_CGROUP_INET4_CONNECT,
  270. AF_INET,
  271. SOCK_STREAM,
  272. NULL,
  273. 0,
  274. NULL,
  275. 0,
  276. NULL,
  277. ATTACH_REJECT,
  278. },
  279. {
  280. "connect6: rewrite IP & TCP port",
  281. connect6_prog_load,
  282. BPF_CGROUP_INET6_CONNECT,
  283. BPF_CGROUP_INET6_CONNECT,
  284. AF_INET6,
  285. SOCK_STREAM,
  286. SERV6_IP,
  287. SERV6_PORT,
  288. SERV6_REWRITE_IP,
  289. SERV6_REWRITE_PORT,
  290. SRC6_REWRITE_IP,
  291. SUCCESS,
  292. },
  293. {
  294. "connect6: rewrite IP & UDP port",
  295. connect6_prog_load,
  296. BPF_CGROUP_INET6_CONNECT,
  297. BPF_CGROUP_INET6_CONNECT,
  298. AF_INET6,
  299. SOCK_DGRAM,
  300. SERV6_IP,
  301. SERV6_PORT,
  302. SERV6_REWRITE_IP,
  303. SERV6_REWRITE_PORT,
  304. SRC6_REWRITE_IP,
  305. SUCCESS,
  306. },
  307. /* sendmsg */
  308. {
  309. "sendmsg4: load prog with wrong expected attach type",
  310. sendmsg4_rw_asm_prog_load,
  311. BPF_CGROUP_UDP6_SENDMSG,
  312. BPF_CGROUP_UDP4_SENDMSG,
  313. AF_INET,
  314. SOCK_DGRAM,
  315. NULL,
  316. 0,
  317. NULL,
  318. 0,
  319. NULL,
  320. LOAD_REJECT,
  321. },
  322. {
  323. "sendmsg4: attach prog with wrong attach type",
  324. sendmsg4_rw_asm_prog_load,
  325. BPF_CGROUP_UDP4_SENDMSG,
  326. BPF_CGROUP_UDP6_SENDMSG,
  327. AF_INET,
  328. SOCK_DGRAM,
  329. NULL,
  330. 0,
  331. NULL,
  332. 0,
  333. NULL,
  334. ATTACH_REJECT,
  335. },
  336. {
  337. "sendmsg4: rewrite IP & port (asm)",
  338. sendmsg4_rw_asm_prog_load,
  339. BPF_CGROUP_UDP4_SENDMSG,
  340. BPF_CGROUP_UDP4_SENDMSG,
  341. AF_INET,
  342. SOCK_DGRAM,
  343. SERV4_IP,
  344. SERV4_PORT,
  345. SERV4_REWRITE_IP,
  346. SERV4_REWRITE_PORT,
  347. SRC4_REWRITE_IP,
  348. SUCCESS,
  349. },
  350. {
  351. "sendmsg4: rewrite IP & port (C)",
  352. sendmsg4_rw_c_prog_load,
  353. BPF_CGROUP_UDP4_SENDMSG,
  354. BPF_CGROUP_UDP4_SENDMSG,
  355. AF_INET,
  356. SOCK_DGRAM,
  357. SERV4_IP,
  358. SERV4_PORT,
  359. SERV4_REWRITE_IP,
  360. SERV4_REWRITE_PORT,
  361. SRC4_REWRITE_IP,
  362. SUCCESS,
  363. },
  364. {
  365. "sendmsg4: deny call",
  366. sendmsg_deny_prog_load,
  367. BPF_CGROUP_UDP4_SENDMSG,
  368. BPF_CGROUP_UDP4_SENDMSG,
  369. AF_INET,
  370. SOCK_DGRAM,
  371. SERV4_IP,
  372. SERV4_PORT,
  373. SERV4_REWRITE_IP,
  374. SERV4_REWRITE_PORT,
  375. SRC4_REWRITE_IP,
  376. SYSCALL_EPERM,
  377. },
  378. {
  379. "sendmsg6: load prog with wrong expected attach type",
  380. sendmsg6_rw_asm_prog_load,
  381. BPF_CGROUP_UDP4_SENDMSG,
  382. BPF_CGROUP_UDP6_SENDMSG,
  383. AF_INET6,
  384. SOCK_DGRAM,
  385. NULL,
  386. 0,
  387. NULL,
  388. 0,
  389. NULL,
  390. LOAD_REJECT,
  391. },
  392. {
  393. "sendmsg6: attach prog with wrong attach type",
  394. sendmsg6_rw_asm_prog_load,
  395. BPF_CGROUP_UDP6_SENDMSG,
  396. BPF_CGROUP_UDP4_SENDMSG,
  397. AF_INET6,
  398. SOCK_DGRAM,
  399. NULL,
  400. 0,
  401. NULL,
  402. 0,
  403. NULL,
  404. ATTACH_REJECT,
  405. },
  406. {
  407. "sendmsg6: rewrite IP & port (asm)",
  408. sendmsg6_rw_asm_prog_load,
  409. BPF_CGROUP_UDP6_SENDMSG,
  410. BPF_CGROUP_UDP6_SENDMSG,
  411. AF_INET6,
  412. SOCK_DGRAM,
  413. SERV6_IP,
  414. SERV6_PORT,
  415. SERV6_REWRITE_IP,
  416. SERV6_REWRITE_PORT,
  417. SRC6_REWRITE_IP,
  418. SUCCESS,
  419. },
  420. {
  421. "sendmsg6: rewrite IP & port (C)",
  422. sendmsg6_rw_c_prog_load,
  423. BPF_CGROUP_UDP6_SENDMSG,
  424. BPF_CGROUP_UDP6_SENDMSG,
  425. AF_INET6,
  426. SOCK_DGRAM,
  427. SERV6_IP,
  428. SERV6_PORT,
  429. SERV6_REWRITE_IP,
  430. SERV6_REWRITE_PORT,
  431. SRC6_REWRITE_IP,
  432. SUCCESS,
  433. },
  434. {
  435. "sendmsg6: IPv4-mapped IPv6",
  436. sendmsg6_rw_v4mapped_prog_load,
  437. BPF_CGROUP_UDP6_SENDMSG,
  438. BPF_CGROUP_UDP6_SENDMSG,
  439. AF_INET6,
  440. SOCK_DGRAM,
  441. SERV6_IP,
  442. SERV6_PORT,
  443. SERV6_REWRITE_IP,
  444. SERV6_REWRITE_PORT,
  445. SRC6_REWRITE_IP,
  446. SYSCALL_ENOTSUPP,
  447. },
  448. {
  449. "sendmsg6: deny call",
  450. sendmsg_deny_prog_load,
  451. BPF_CGROUP_UDP6_SENDMSG,
  452. BPF_CGROUP_UDP6_SENDMSG,
  453. AF_INET6,
  454. SOCK_DGRAM,
  455. SERV6_IP,
  456. SERV6_PORT,
  457. SERV6_REWRITE_IP,
  458. SERV6_REWRITE_PORT,
  459. SRC6_REWRITE_IP,
  460. SYSCALL_EPERM,
  461. },
  462. };
  463. static int mk_sockaddr(int domain, const char *ip, unsigned short port,
  464. struct sockaddr *addr, socklen_t addr_len)
  465. {
  466. struct sockaddr_in6 *addr6;
  467. struct sockaddr_in *addr4;
  468. if (domain != AF_INET && domain != AF_INET6) {
  469. log_err("Unsupported address family");
  470. return -1;
  471. }
  472. memset(addr, 0, addr_len);
  473. if (domain == AF_INET) {
  474. if (addr_len < sizeof(struct sockaddr_in))
  475. return -1;
  476. addr4 = (struct sockaddr_in *)addr;
  477. addr4->sin_family = domain;
  478. addr4->sin_port = htons(port);
  479. if (inet_pton(domain, ip, (void *)&addr4->sin_addr) != 1) {
  480. log_err("Invalid IPv4: %s", ip);
  481. return -1;
  482. }
  483. } else if (domain == AF_INET6) {
  484. if (addr_len < sizeof(struct sockaddr_in6))
  485. return -1;
  486. addr6 = (struct sockaddr_in6 *)addr;
  487. addr6->sin6_family = domain;
  488. addr6->sin6_port = htons(port);
  489. if (inet_pton(domain, ip, (void *)&addr6->sin6_addr) != 1) {
  490. log_err("Invalid IPv6: %s", ip);
  491. return -1;
  492. }
  493. }
  494. return 0;
  495. }
  496. static int load_insns(const struct sock_addr_test *test,
  497. const struct bpf_insn *insns, size_t insns_cnt)
  498. {
  499. struct bpf_load_program_attr load_attr;
  500. int ret;
  501. memset(&load_attr, 0, sizeof(struct bpf_load_program_attr));
  502. load_attr.prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
  503. load_attr.expected_attach_type = test->expected_attach_type;
  504. load_attr.insns = insns;
  505. load_attr.insns_cnt = insns_cnt;
  506. load_attr.license = "GPL";
  507. ret = bpf_load_program_xattr(&load_attr, bpf_log_buf, BPF_LOG_BUF_SIZE);
  508. if (ret < 0 && test->expected_result != LOAD_REJECT) {
  509. log_err(">>> Loading program error.\n"
  510. ">>> Verifier output:\n%s\n-------\n", bpf_log_buf);
  511. }
  512. return ret;
  513. }
  514. /* [1] These testing programs try to read different context fields, including
  515. * narrow loads of different sizes from user_ip4 and user_ip6, and write to
  516. * those allowed to be overridden.
  517. *
  518. * [2] BPF_LD_IMM64 & BPF_JMP_REG are used below whenever there is a need to
  519. * compare a register with unsigned 32bit integer. BPF_JMP_IMM can't be used
  520. * in such cases since it accepts only _signed_ 32bit integer as IMM
  521. * argument. Also note that BPF_LD_IMM64 contains 2 instructions what matters
  522. * to count jumps properly.
  523. */
  524. static int bind4_prog_load(const struct sock_addr_test *test)
  525. {
  526. union {
  527. uint8_t u4_addr8[4];
  528. uint16_t u4_addr16[2];
  529. uint32_t u4_addr32;
  530. } ip4;
  531. struct sockaddr_in addr4_rw;
  532. if (inet_pton(AF_INET, SERV4_IP, (void *)&ip4) != 1) {
  533. log_err("Invalid IPv4: %s", SERV4_IP);
  534. return -1;
  535. }
  536. if (mk_sockaddr(AF_INET, SERV4_REWRITE_IP, SERV4_REWRITE_PORT,
  537. (struct sockaddr *)&addr4_rw, sizeof(addr4_rw)) == -1)
  538. return -1;
  539. /* See [1]. */
  540. struct bpf_insn insns[] = {
  541. BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
  542. /* if (sk.family == AF_INET && */
  543. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  544. offsetof(struct bpf_sock_addr, family)),
  545. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET, 16),
  546. /* (sk.type == SOCK_DGRAM || sk.type == SOCK_STREAM) && */
  547. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  548. offsetof(struct bpf_sock_addr, type)),
  549. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_DGRAM, 1),
  550. BPF_JMP_A(1),
  551. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_STREAM, 12),
  552. /* 1st_byte_of_user_ip4 == expected && */
  553. BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
  554. offsetof(struct bpf_sock_addr, user_ip4)),
  555. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr8[0], 10),
  556. /* 1st_half_of_user_ip4 == expected && */
  557. BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_6,
  558. offsetof(struct bpf_sock_addr, user_ip4)),
  559. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip4.u4_addr16[0], 8),
  560. /* whole_user_ip4 == expected) { */
  561. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  562. offsetof(struct bpf_sock_addr, user_ip4)),
  563. BPF_LD_IMM64(BPF_REG_8, ip4.u4_addr32), /* See [2]. */
  564. BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_8, 4),
  565. /* user_ip4 = addr4_rw.sin_addr */
  566. BPF_MOV32_IMM(BPF_REG_7, addr4_rw.sin_addr.s_addr),
  567. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  568. offsetof(struct bpf_sock_addr, user_ip4)),
  569. /* user_port = addr4_rw.sin_port */
  570. BPF_MOV32_IMM(BPF_REG_7, addr4_rw.sin_port),
  571. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  572. offsetof(struct bpf_sock_addr, user_port)),
  573. /* } */
  574. /* return 1 */
  575. BPF_MOV64_IMM(BPF_REG_0, 1),
  576. BPF_EXIT_INSN(),
  577. };
  578. return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
  579. }
  580. static int bind6_prog_load(const struct sock_addr_test *test)
  581. {
  582. struct sockaddr_in6 addr6_rw;
  583. struct in6_addr ip6;
  584. if (inet_pton(AF_INET6, SERV6_IP, (void *)&ip6) != 1) {
  585. log_err("Invalid IPv6: %s", SERV6_IP);
  586. return -1;
  587. }
  588. if (mk_sockaddr(AF_INET6, SERV6_REWRITE_IP, SERV6_REWRITE_PORT,
  589. (struct sockaddr *)&addr6_rw, sizeof(addr6_rw)) == -1)
  590. return -1;
  591. /* See [1]. */
  592. struct bpf_insn insns[] = {
  593. BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
  594. /* if (sk.family == AF_INET6 && */
  595. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  596. offsetof(struct bpf_sock_addr, family)),
  597. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET6, 18),
  598. /* 5th_byte_of_user_ip6 == expected && */
  599. BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_6,
  600. offsetof(struct bpf_sock_addr, user_ip6[1])),
  601. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip6.s6_addr[4], 16),
  602. /* 3rd_half_of_user_ip6 == expected && */
  603. BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_6,
  604. offsetof(struct bpf_sock_addr, user_ip6[1])),
  605. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, ip6.s6_addr16[2], 14),
  606. /* last_word_of_user_ip6 == expected) { */
  607. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  608. offsetof(struct bpf_sock_addr, user_ip6[3])),
  609. BPF_LD_IMM64(BPF_REG_8, ip6.s6_addr32[3]), /* See [2]. */
  610. BPF_JMP_REG(BPF_JNE, BPF_REG_7, BPF_REG_8, 10),
  611. #define STORE_IPV6_WORD(N) \
  612. BPF_MOV32_IMM(BPF_REG_7, addr6_rw.sin6_addr.s6_addr32[N]), \
  613. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7, \
  614. offsetof(struct bpf_sock_addr, user_ip6[N]))
  615. /* user_ip6 = addr6_rw.sin6_addr */
  616. STORE_IPV6_WORD(0),
  617. STORE_IPV6_WORD(1),
  618. STORE_IPV6_WORD(2),
  619. STORE_IPV6_WORD(3),
  620. /* user_port = addr6_rw.sin6_port */
  621. BPF_MOV32_IMM(BPF_REG_7, addr6_rw.sin6_port),
  622. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  623. offsetof(struct bpf_sock_addr, user_port)),
  624. /* } */
  625. /* return 1 */
  626. BPF_MOV64_IMM(BPF_REG_0, 1),
  627. BPF_EXIT_INSN(),
  628. };
  629. return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
  630. }
  631. static int load_path(const struct sock_addr_test *test, const char *path)
  632. {
  633. struct bpf_prog_load_attr attr;
  634. struct bpf_object *obj;
  635. int prog_fd;
  636. memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
  637. attr.file = path;
  638. attr.prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR;
  639. attr.expected_attach_type = test->expected_attach_type;
  640. if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) {
  641. if (test->expected_result != LOAD_REJECT)
  642. log_err(">>> Loading program (%s) error.\n", path);
  643. return -1;
  644. }
  645. return prog_fd;
  646. }
  647. static int connect4_prog_load(const struct sock_addr_test *test)
  648. {
  649. return load_path(test, CONNECT4_PROG_PATH);
  650. }
  651. static int connect6_prog_load(const struct sock_addr_test *test)
  652. {
  653. return load_path(test, CONNECT6_PROG_PATH);
  654. }
  655. static int sendmsg_deny_prog_load(const struct sock_addr_test *test)
  656. {
  657. struct bpf_insn insns[] = {
  658. /* return 0 */
  659. BPF_MOV64_IMM(BPF_REG_0, 0),
  660. BPF_EXIT_INSN(),
  661. };
  662. return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
  663. }
  664. static int sendmsg4_rw_asm_prog_load(const struct sock_addr_test *test)
  665. {
  666. struct sockaddr_in dst4_rw_addr;
  667. struct in_addr src4_rw_ip;
  668. if (inet_pton(AF_INET, SRC4_REWRITE_IP, (void *)&src4_rw_ip) != 1) {
  669. log_err("Invalid IPv4: %s", SRC4_REWRITE_IP);
  670. return -1;
  671. }
  672. if (mk_sockaddr(AF_INET, SERV4_REWRITE_IP, SERV4_REWRITE_PORT,
  673. (struct sockaddr *)&dst4_rw_addr,
  674. sizeof(dst4_rw_addr)) == -1)
  675. return -1;
  676. struct bpf_insn insns[] = {
  677. BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
  678. /* if (sk.family == AF_INET && */
  679. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  680. offsetof(struct bpf_sock_addr, family)),
  681. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET, 8),
  682. /* sk.type == SOCK_DGRAM) { */
  683. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  684. offsetof(struct bpf_sock_addr, type)),
  685. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, SOCK_DGRAM, 6),
  686. /* msg_src_ip4 = src4_rw_ip */
  687. BPF_MOV32_IMM(BPF_REG_7, src4_rw_ip.s_addr),
  688. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  689. offsetof(struct bpf_sock_addr, msg_src_ip4)),
  690. /* user_ip4 = dst4_rw_addr.sin_addr */
  691. BPF_MOV32_IMM(BPF_REG_7, dst4_rw_addr.sin_addr.s_addr),
  692. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  693. offsetof(struct bpf_sock_addr, user_ip4)),
  694. /* user_port = dst4_rw_addr.sin_port */
  695. BPF_MOV32_IMM(BPF_REG_7, dst4_rw_addr.sin_port),
  696. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  697. offsetof(struct bpf_sock_addr, user_port)),
  698. /* } */
  699. /* return 1 */
  700. BPF_MOV64_IMM(BPF_REG_0, 1),
  701. BPF_EXIT_INSN(),
  702. };
  703. return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
  704. }
  705. static int sendmsg4_rw_c_prog_load(const struct sock_addr_test *test)
  706. {
  707. return load_path(test, SENDMSG4_PROG_PATH);
  708. }
  709. static int sendmsg6_rw_dst_asm_prog_load(const struct sock_addr_test *test,
  710. const char *rw_dst_ip)
  711. {
  712. struct sockaddr_in6 dst6_rw_addr;
  713. struct in6_addr src6_rw_ip;
  714. if (inet_pton(AF_INET6, SRC6_REWRITE_IP, (void *)&src6_rw_ip) != 1) {
  715. log_err("Invalid IPv6: %s", SRC6_REWRITE_IP);
  716. return -1;
  717. }
  718. if (mk_sockaddr(AF_INET6, rw_dst_ip, SERV6_REWRITE_PORT,
  719. (struct sockaddr *)&dst6_rw_addr,
  720. sizeof(dst6_rw_addr)) == -1)
  721. return -1;
  722. struct bpf_insn insns[] = {
  723. BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
  724. /* if (sk.family == AF_INET6) { */
  725. BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_6,
  726. offsetof(struct bpf_sock_addr, family)),
  727. BPF_JMP_IMM(BPF_JNE, BPF_REG_7, AF_INET6, 18),
  728. #define STORE_IPV6_WORD_N(DST, SRC, N) \
  729. BPF_MOV32_IMM(BPF_REG_7, SRC[N]), \
  730. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7, \
  731. offsetof(struct bpf_sock_addr, DST[N]))
  732. #define STORE_IPV6(DST, SRC) \
  733. STORE_IPV6_WORD_N(DST, SRC, 0), \
  734. STORE_IPV6_WORD_N(DST, SRC, 1), \
  735. STORE_IPV6_WORD_N(DST, SRC, 2), \
  736. STORE_IPV6_WORD_N(DST, SRC, 3)
  737. STORE_IPV6(msg_src_ip6, src6_rw_ip.s6_addr32),
  738. STORE_IPV6(user_ip6, dst6_rw_addr.sin6_addr.s6_addr32),
  739. /* user_port = dst6_rw_addr.sin6_port */
  740. BPF_MOV32_IMM(BPF_REG_7, dst6_rw_addr.sin6_port),
  741. BPF_STX_MEM(BPF_W, BPF_REG_6, BPF_REG_7,
  742. offsetof(struct bpf_sock_addr, user_port)),
  743. /* } */
  744. /* return 1 */
  745. BPF_MOV64_IMM(BPF_REG_0, 1),
  746. BPF_EXIT_INSN(),
  747. };
  748. return load_insns(test, insns, sizeof(insns) / sizeof(struct bpf_insn));
  749. }
  750. static int sendmsg6_rw_asm_prog_load(const struct sock_addr_test *test)
  751. {
  752. return sendmsg6_rw_dst_asm_prog_load(test, SERV6_REWRITE_IP);
  753. }
  754. static int sendmsg6_rw_v4mapped_prog_load(const struct sock_addr_test *test)
  755. {
  756. return sendmsg6_rw_dst_asm_prog_load(test, SERV6_V4MAPPED_IP);
  757. }
  758. static int sendmsg6_rw_c_prog_load(const struct sock_addr_test *test)
  759. {
  760. return load_path(test, SENDMSG6_PROG_PATH);
  761. }
  762. static int cmp_addr(const struct sockaddr_storage *addr1,
  763. const struct sockaddr_storage *addr2, int cmp_port)
  764. {
  765. const struct sockaddr_in *four1, *four2;
  766. const struct sockaddr_in6 *six1, *six2;
  767. if (addr1->ss_family != addr2->ss_family)
  768. return -1;
  769. if (addr1->ss_family == AF_INET) {
  770. four1 = (const struct sockaddr_in *)addr1;
  771. four2 = (const struct sockaddr_in *)addr2;
  772. return !((four1->sin_port == four2->sin_port || !cmp_port) &&
  773. four1->sin_addr.s_addr == four2->sin_addr.s_addr);
  774. } else if (addr1->ss_family == AF_INET6) {
  775. six1 = (const struct sockaddr_in6 *)addr1;
  776. six2 = (const struct sockaddr_in6 *)addr2;
  777. return !((six1->sin6_port == six2->sin6_port || !cmp_port) &&
  778. !memcmp(&six1->sin6_addr, &six2->sin6_addr,
  779. sizeof(struct in6_addr)));
  780. }
  781. return -1;
  782. }
  783. static int cmp_sock_addr(info_fn fn, int sock1,
  784. const struct sockaddr_storage *addr2, int cmp_port)
  785. {
  786. struct sockaddr_storage addr1;
  787. socklen_t len1 = sizeof(addr1);
  788. memset(&addr1, 0, len1);
  789. if (fn(sock1, (struct sockaddr *)&addr1, (socklen_t *)&len1) != 0)
  790. return -1;
  791. return cmp_addr(&addr1, addr2, cmp_port);
  792. }
  793. static int cmp_local_ip(int sock1, const struct sockaddr_storage *addr2)
  794. {
  795. return cmp_sock_addr(getsockname, sock1, addr2, /*cmp_port*/ 0);
  796. }
  797. static int cmp_local_addr(int sock1, const struct sockaddr_storage *addr2)
  798. {
  799. return cmp_sock_addr(getsockname, sock1, addr2, /*cmp_port*/ 1);
  800. }
  801. static int cmp_peer_addr(int sock1, const struct sockaddr_storage *addr2)
  802. {
  803. return cmp_sock_addr(getpeername, sock1, addr2, /*cmp_port*/ 1);
  804. }
  805. static int start_server(int type, const struct sockaddr_storage *addr,
  806. socklen_t addr_len)
  807. {
  808. int fd;
  809. fd = socket(addr->ss_family, type, 0);
  810. if (fd == -1) {
  811. log_err("Failed to create server socket");
  812. goto out;
  813. }
  814. if (bind(fd, (const struct sockaddr *)addr, addr_len) == -1) {
  815. log_err("Failed to bind server socket");
  816. goto close_out;
  817. }
  818. if (type == SOCK_STREAM) {
  819. if (listen(fd, 128) == -1) {
  820. log_err("Failed to listen on server socket");
  821. goto close_out;
  822. }
  823. }
  824. goto out;
  825. close_out:
  826. close(fd);
  827. fd = -1;
  828. out:
  829. return fd;
  830. }
  831. static int connect_to_server(int type, const struct sockaddr_storage *addr,
  832. socklen_t addr_len)
  833. {
  834. int domain;
  835. int fd = -1;
  836. domain = addr->ss_family;
  837. if (domain != AF_INET && domain != AF_INET6) {
  838. log_err("Unsupported address family");
  839. goto err;
  840. }
  841. fd = socket(domain, type, 0);
  842. if (fd == -1) {
  843. log_err("Failed to create client socket");
  844. goto err;
  845. }
  846. if (connect(fd, (const struct sockaddr *)addr, addr_len) == -1) {
  847. log_err("Fail to connect to server");
  848. goto err;
  849. }
  850. goto out;
  851. err:
  852. close(fd);
  853. fd = -1;
  854. out:
  855. return fd;
  856. }
  857. int init_pktinfo(int domain, struct cmsghdr *cmsg)
  858. {
  859. struct in6_pktinfo *pktinfo6;
  860. struct in_pktinfo *pktinfo4;
  861. if (domain == AF_INET) {
  862. cmsg->cmsg_level = SOL_IP;
  863. cmsg->cmsg_type = IP_PKTINFO;
  864. cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));
  865. pktinfo4 = (struct in_pktinfo *)CMSG_DATA(cmsg);
  866. memset(pktinfo4, 0, sizeof(struct in_pktinfo));
  867. if (inet_pton(domain, SRC4_IP,
  868. (void *)&pktinfo4->ipi_spec_dst) != 1)
  869. return -1;
  870. } else if (domain == AF_INET6) {
  871. cmsg->cmsg_level = SOL_IPV6;
  872. cmsg->cmsg_type = IPV6_PKTINFO;
  873. cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
  874. pktinfo6 = (struct in6_pktinfo *)CMSG_DATA(cmsg);
  875. memset(pktinfo6, 0, sizeof(struct in6_pktinfo));
  876. if (inet_pton(domain, SRC6_IP,
  877. (void *)&pktinfo6->ipi6_addr) != 1)
  878. return -1;
  879. } else {
  880. return -1;
  881. }
  882. return 0;
  883. }
  884. static int sendmsg_to_server(const struct sockaddr_storage *addr,
  885. socklen_t addr_len, int set_cmsg, int *syscall_err)
  886. {
  887. union {
  888. char buf[CMSG_SPACE(sizeof(struct in6_pktinfo))];
  889. struct cmsghdr align;
  890. } control6;
  891. union {
  892. char buf[CMSG_SPACE(sizeof(struct in_pktinfo))];
  893. struct cmsghdr align;
  894. } control4;
  895. struct msghdr hdr;
  896. struct iovec iov;
  897. char data = 'a';
  898. int domain;
  899. int fd = -1;
  900. domain = addr->ss_family;
  901. if (domain != AF_INET && domain != AF_INET6) {
  902. log_err("Unsupported address family");
  903. goto err;
  904. }
  905. fd = socket(domain, SOCK_DGRAM, 0);
  906. if (fd == -1) {
  907. log_err("Failed to create client socket");
  908. goto err;
  909. }
  910. memset(&iov, 0, sizeof(iov));
  911. iov.iov_base = &data;
  912. iov.iov_len = sizeof(data);
  913. memset(&hdr, 0, sizeof(hdr));
  914. hdr.msg_name = (void *)addr;
  915. hdr.msg_namelen = addr_len;
  916. hdr.msg_iov = &iov;
  917. hdr.msg_iovlen = 1;
  918. if (set_cmsg) {
  919. if (domain == AF_INET) {
  920. hdr.msg_control = &control4;
  921. hdr.msg_controllen = sizeof(control4.buf);
  922. } else if (domain == AF_INET6) {
  923. hdr.msg_control = &control6;
  924. hdr.msg_controllen = sizeof(control6.buf);
  925. }
  926. if (init_pktinfo(domain, CMSG_FIRSTHDR(&hdr))) {
  927. log_err("Fail to init pktinfo");
  928. goto err;
  929. }
  930. }
  931. if (sendmsg(fd, &hdr, 0) != sizeof(data)) {
  932. log_err("Fail to send message to server");
  933. *syscall_err = errno;
  934. goto err;
  935. }
  936. goto out;
  937. err:
  938. close(fd);
  939. fd = -1;
  940. out:
  941. return fd;
  942. }
  943. static int recvmsg_from_client(int sockfd, struct sockaddr_storage *src_addr)
  944. {
  945. struct timeval tv;
  946. struct msghdr hdr;
  947. struct iovec iov;
  948. char data[64];
  949. fd_set rfds;
  950. FD_ZERO(&rfds);
  951. FD_SET(sockfd, &rfds);
  952. tv.tv_sec = 2;
  953. tv.tv_usec = 0;
  954. if (select(sockfd + 1, &rfds, NULL, NULL, &tv) <= 0 ||
  955. !FD_ISSET(sockfd, &rfds))
  956. return -1;
  957. memset(&iov, 0, sizeof(iov));
  958. iov.iov_base = data;
  959. iov.iov_len = sizeof(data);
  960. memset(&hdr, 0, sizeof(hdr));
  961. hdr.msg_name = src_addr;
  962. hdr.msg_namelen = sizeof(struct sockaddr_storage);
  963. hdr.msg_iov = &iov;
  964. hdr.msg_iovlen = 1;
  965. return recvmsg(sockfd, &hdr, 0);
  966. }
  967. static int init_addrs(const struct sock_addr_test *test,
  968. struct sockaddr_storage *requested_addr,
  969. struct sockaddr_storage *expected_addr,
  970. struct sockaddr_storage *expected_src_addr)
  971. {
  972. socklen_t addr_len = sizeof(struct sockaddr_storage);
  973. if (mk_sockaddr(test->domain, test->expected_ip, test->expected_port,
  974. (struct sockaddr *)expected_addr, addr_len) == -1)
  975. goto err;
  976. if (mk_sockaddr(test->domain, test->requested_ip, test->requested_port,
  977. (struct sockaddr *)requested_addr, addr_len) == -1)
  978. goto err;
  979. if (test->expected_src_ip &&
  980. mk_sockaddr(test->domain, test->expected_src_ip, 0,
  981. (struct sockaddr *)expected_src_addr, addr_len) == -1)
  982. goto err;
  983. return 0;
  984. err:
  985. return -1;
  986. }
  987. static int run_bind_test_case(const struct sock_addr_test *test)
  988. {
  989. socklen_t addr_len = sizeof(struct sockaddr_storage);
  990. struct sockaddr_storage requested_addr;
  991. struct sockaddr_storage expected_addr;
  992. int clientfd = -1;
  993. int servfd = -1;
  994. int err = 0;
  995. if (init_addrs(test, &requested_addr, &expected_addr, NULL))
  996. goto err;
  997. servfd = start_server(test->type, &requested_addr, addr_len);
  998. if (servfd == -1)
  999. goto err;
  1000. if (cmp_local_addr(servfd, &expected_addr))
  1001. goto err;
  1002. /* Try to connect to server just in case */
  1003. clientfd = connect_to_server(test->type, &expected_addr, addr_len);
  1004. if (clientfd == -1)
  1005. goto err;
  1006. goto out;
  1007. err:
  1008. err = -1;
  1009. out:
  1010. close(clientfd);
  1011. close(servfd);
  1012. return err;
  1013. }
  1014. static int run_connect_test_case(const struct sock_addr_test *test)
  1015. {
  1016. socklen_t addr_len = sizeof(struct sockaddr_storage);
  1017. struct sockaddr_storage expected_src_addr;
  1018. struct sockaddr_storage requested_addr;
  1019. struct sockaddr_storage expected_addr;
  1020. int clientfd = -1;
  1021. int servfd = -1;
  1022. int err = 0;
  1023. if (init_addrs(test, &requested_addr, &expected_addr,
  1024. &expected_src_addr))
  1025. goto err;
  1026. /* Prepare server to connect to */
  1027. servfd = start_server(test->type, &expected_addr, addr_len);
  1028. if (servfd == -1)
  1029. goto err;
  1030. clientfd = connect_to_server(test->type, &requested_addr, addr_len);
  1031. if (clientfd == -1)
  1032. goto err;
  1033. /* Make sure src and dst addrs were overridden properly */
  1034. if (cmp_peer_addr(clientfd, &expected_addr))
  1035. goto err;
  1036. if (cmp_local_ip(clientfd, &expected_src_addr))
  1037. goto err;
  1038. goto out;
  1039. err:
  1040. err = -1;
  1041. out:
  1042. close(clientfd);
  1043. close(servfd);
  1044. return err;
  1045. }
  1046. static int run_sendmsg_test_case(const struct sock_addr_test *test)
  1047. {
  1048. socklen_t addr_len = sizeof(struct sockaddr_storage);
  1049. struct sockaddr_storage expected_src_addr;
  1050. struct sockaddr_storage requested_addr;
  1051. struct sockaddr_storage expected_addr;
  1052. struct sockaddr_storage real_src_addr;
  1053. int clientfd = -1;
  1054. int servfd = -1;
  1055. int set_cmsg;
  1056. int err = 0;
  1057. if (test->type != SOCK_DGRAM)
  1058. goto err;
  1059. if (init_addrs(test, &requested_addr, &expected_addr,
  1060. &expected_src_addr))
  1061. goto err;
  1062. /* Prepare server to sendmsg to */
  1063. servfd = start_server(test->type, &expected_addr, addr_len);
  1064. if (servfd == -1)
  1065. goto err;
  1066. for (set_cmsg = 0; set_cmsg <= 1; ++set_cmsg) {
  1067. if (clientfd >= 0)
  1068. close(clientfd);
  1069. clientfd = sendmsg_to_server(&requested_addr, addr_len,
  1070. set_cmsg, &err);
  1071. if (err)
  1072. goto out;
  1073. else if (clientfd == -1)
  1074. goto err;
  1075. /* Try to receive message on server instead of using
  1076. * getpeername(2) on client socket, to check that client's
  1077. * destination address was rewritten properly, since
  1078. * getpeername(2) doesn't work with unconnected datagram
  1079. * sockets.
  1080. *
  1081. * Get source address from recvmsg(2) as well to make sure
  1082. * source was rewritten properly: getsockname(2) can't be used
  1083. * since socket is unconnected and source defined for one
  1084. * specific packet may differ from the one used by default and
  1085. * returned by getsockname(2).
  1086. */
  1087. if (recvmsg_from_client(servfd, &real_src_addr) == -1)
  1088. goto err;
  1089. if (cmp_addr(&real_src_addr, &expected_src_addr, /*cmp_port*/0))
  1090. goto err;
  1091. }
  1092. goto out;
  1093. err:
  1094. err = -1;
  1095. out:
  1096. close(clientfd);
  1097. close(servfd);
  1098. return err;
  1099. }
  1100. static int run_test_case(int cgfd, const struct sock_addr_test *test)
  1101. {
  1102. int progfd = -1;
  1103. int err = 0;
  1104. printf("Test case: %s .. ", test->descr);
  1105. progfd = test->loadfn(test);
  1106. if (test->expected_result == LOAD_REJECT && progfd < 0)
  1107. goto out;
  1108. else if (test->expected_result == LOAD_REJECT || progfd < 0)
  1109. goto err;
  1110. err = bpf_prog_attach(progfd, cgfd, test->attach_type,
  1111. BPF_F_ALLOW_OVERRIDE);
  1112. if (test->expected_result == ATTACH_REJECT && err) {
  1113. err = 0; /* error was expected, reset it */
  1114. goto out;
  1115. } else if (test->expected_result == ATTACH_REJECT || err) {
  1116. goto err;
  1117. }
  1118. switch (test->attach_type) {
  1119. case BPF_CGROUP_INET4_BIND:
  1120. case BPF_CGROUP_INET6_BIND:
  1121. err = run_bind_test_case(test);
  1122. break;
  1123. case BPF_CGROUP_INET4_CONNECT:
  1124. case BPF_CGROUP_INET6_CONNECT:
  1125. err = run_connect_test_case(test);
  1126. break;
  1127. case BPF_CGROUP_UDP4_SENDMSG:
  1128. case BPF_CGROUP_UDP6_SENDMSG:
  1129. err = run_sendmsg_test_case(test);
  1130. break;
  1131. default:
  1132. goto err;
  1133. }
  1134. if (test->expected_result == SYSCALL_EPERM && err == EPERM) {
  1135. err = 0; /* error was expected, reset it */
  1136. goto out;
  1137. }
  1138. if (test->expected_result == SYSCALL_ENOTSUPP && err == ENOTSUPP) {
  1139. err = 0; /* error was expected, reset it */
  1140. goto out;
  1141. }
  1142. if (err || test->expected_result != SUCCESS)
  1143. goto err;
  1144. goto out;
  1145. err:
  1146. err = -1;
  1147. out:
  1148. /* Detaching w/o checking return code: best effort attempt. */
  1149. if (progfd != -1)
  1150. bpf_prog_detach(cgfd, test->attach_type);
  1151. close(progfd);
  1152. printf("[%s]\n", err ? "FAIL" : "PASS");
  1153. return err;
  1154. }
  1155. static int run_tests(int cgfd)
  1156. {
  1157. int passes = 0;
  1158. int fails = 0;
  1159. int i;
  1160. for (i = 0; i < ARRAY_SIZE(tests); ++i) {
  1161. if (run_test_case(cgfd, &tests[i]))
  1162. ++fails;
  1163. else
  1164. ++passes;
  1165. }
  1166. printf("Summary: %d PASSED, %d FAILED\n", passes, fails);
  1167. return fails ? -1 : 0;
  1168. }
  1169. int main(int argc, char **argv)
  1170. {
  1171. int cgfd = -1;
  1172. int err = 0;
  1173. if (argc < 2) {
  1174. fprintf(stderr,
  1175. "%s has to be run via %s.sh. Skip direct run.\n",
  1176. argv[0], argv[0]);
  1177. exit(err);
  1178. }
  1179. if (setup_cgroup_environment())
  1180. goto err;
  1181. cgfd = create_and_get_cgroup(CG_PATH);
  1182. if (!cgfd)
  1183. goto err;
  1184. if (join_cgroup(CG_PATH))
  1185. goto err;
  1186. if (run_tests(cgfd))
  1187. goto err;
  1188. goto out;
  1189. err:
  1190. err = -1;
  1191. out:
  1192. close(cgfd);
  1193. cleanup_cgroup_environment();
  1194. return err;
  1195. }