test_sock_addr.c 33 KB

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