test_sock_addr.c 31 KB

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