feature.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344
  1. // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
  2. /* Copyright (c) 2019 Netronome Systems, Inc. */
  3. #include <ctype.h>
  4. #include <errno.h>
  5. #include <fcntl.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <net/if.h>
  9. #ifdef USE_LIBCAP
  10. #include <sys/capability.h>
  11. #endif
  12. #include <sys/utsname.h>
  13. #include <sys/vfs.h>
  14. #include <linux/filter.h>
  15. #include <linux/limits.h>
  16. #include <bpf/bpf.h>
  17. #include <bpf/libbpf.h>
  18. #include <zlib.h>
  19. #include "main.h"
  20. #ifndef PROC_SUPER_MAGIC
  21. # define PROC_SUPER_MAGIC 0x9fa0
  22. #endif
  23. enum probe_component {
  24. COMPONENT_UNSPEC,
  25. COMPONENT_KERNEL,
  26. COMPONENT_DEVICE,
  27. };
  28. #define BPF_HELPER_MAKE_ENTRY(name) [BPF_FUNC_ ## name] = "bpf_" # name
  29. static const char * const helper_name[] = {
  30. __BPF_FUNC_MAPPER(BPF_HELPER_MAKE_ENTRY)
  31. };
  32. #undef BPF_HELPER_MAKE_ENTRY
  33. static bool full_mode;
  34. #ifdef USE_LIBCAP
  35. static bool run_as_unprivileged;
  36. #endif
  37. /* Miscellaneous utility functions */
  38. static bool grep(const char *buffer, const char *pattern)
  39. {
  40. return !!strstr(buffer, pattern);
  41. }
  42. static bool check_procfs(void)
  43. {
  44. struct statfs st_fs;
  45. if (statfs("/proc", &st_fs) < 0)
  46. return false;
  47. if ((unsigned long)st_fs.f_type != PROC_SUPER_MAGIC)
  48. return false;
  49. return true;
  50. }
  51. static void uppercase(char *str, size_t len)
  52. {
  53. size_t i;
  54. for (i = 0; i < len && str[i] != '\0'; i++)
  55. str[i] = toupper(str[i]);
  56. }
  57. /* Printing utility functions */
  58. static void
  59. print_bool_feature(const char *feat_name, const char *plain_name,
  60. const char *define_name, bool res, const char *define_prefix)
  61. {
  62. if (json_output)
  63. jsonw_bool_field(json_wtr, feat_name, res);
  64. else if (define_prefix)
  65. printf("#define %s%sHAVE_%s\n", define_prefix,
  66. res ? "" : "NO_", define_name);
  67. else
  68. printf("%s is %savailable\n", plain_name, res ? "" : "NOT ");
  69. }
  70. static void print_kernel_option(const char *name, const char *value,
  71. const char *define_prefix)
  72. {
  73. char *endptr;
  74. int res;
  75. if (json_output) {
  76. if (!value) {
  77. jsonw_null_field(json_wtr, name);
  78. return;
  79. }
  80. errno = 0;
  81. res = strtol(value, &endptr, 0);
  82. if (!errno && *endptr == '\n')
  83. jsonw_int_field(json_wtr, name, res);
  84. else
  85. jsonw_string_field(json_wtr, name, value);
  86. } else if (define_prefix) {
  87. if (value)
  88. printf("#define %s%s %s\n", define_prefix,
  89. name, value);
  90. else
  91. printf("/* %s%s is not set */\n", define_prefix, name);
  92. } else {
  93. if (value)
  94. printf("%s is set to %s\n", name, value);
  95. else
  96. printf("%s is not set\n", name);
  97. }
  98. }
  99. static void
  100. print_start_section(const char *json_title, const char *plain_title,
  101. const char *define_comment, const char *define_prefix)
  102. {
  103. if (json_output) {
  104. jsonw_name(json_wtr, json_title);
  105. jsonw_start_object(json_wtr);
  106. } else if (define_prefix) {
  107. printf("%s\n", define_comment);
  108. } else {
  109. printf("%s\n", plain_title);
  110. }
  111. }
  112. static void print_end_section(void)
  113. {
  114. if (json_output)
  115. jsonw_end_object(json_wtr);
  116. else
  117. printf("\n");
  118. }
  119. /* Probing functions */
  120. static int get_vendor_id(int ifindex)
  121. {
  122. char ifname[IF_NAMESIZE], path[64], buf[8];
  123. ssize_t len;
  124. int fd;
  125. if (!if_indextoname(ifindex, ifname))
  126. return -1;
  127. snprintf(path, sizeof(path), "/sys/class/net/%s/device/vendor", ifname);
  128. fd = open(path, O_RDONLY | O_CLOEXEC);
  129. if (fd < 0)
  130. return -1;
  131. len = read(fd, buf, sizeof(buf));
  132. close(fd);
  133. if (len < 0)
  134. return -1;
  135. if (len >= (ssize_t)sizeof(buf))
  136. return -1;
  137. buf[len] = '\0';
  138. return strtol(buf, NULL, 0);
  139. }
  140. static long read_procfs(const char *path)
  141. {
  142. char *endptr, *line = NULL;
  143. size_t len = 0;
  144. FILE *fd;
  145. long res;
  146. fd = fopen(path, "r");
  147. if (!fd)
  148. return -1;
  149. res = getline(&line, &len, fd);
  150. fclose(fd);
  151. if (res < 0)
  152. return -1;
  153. errno = 0;
  154. res = strtol(line, &endptr, 10);
  155. if (errno || *line == '\0' || *endptr != '\n')
  156. res = -1;
  157. free(line);
  158. return res;
  159. }
  160. static void probe_unprivileged_disabled(void)
  161. {
  162. long res;
  163. /* No support for C-style ouptut */
  164. res = read_procfs("/proc/sys/kernel/unprivileged_bpf_disabled");
  165. if (json_output) {
  166. jsonw_int_field(json_wtr, "unprivileged_bpf_disabled", res);
  167. } else {
  168. switch (res) {
  169. case 0:
  170. printf("bpf() syscall for unprivileged users is enabled\n");
  171. break;
  172. case 1:
  173. printf("bpf() syscall restricted to privileged users (without recovery)\n");
  174. break;
  175. case 2:
  176. printf("bpf() syscall restricted to privileged users (admin can change)\n");
  177. break;
  178. case -1:
  179. printf("Unable to retrieve required privileges for bpf() syscall\n");
  180. break;
  181. default:
  182. printf("bpf() syscall restriction has unknown value %ld\n", res);
  183. }
  184. }
  185. }
  186. static void probe_jit_enable(void)
  187. {
  188. long res;
  189. /* No support for C-style ouptut */
  190. res = read_procfs("/proc/sys/net/core/bpf_jit_enable");
  191. if (json_output) {
  192. jsonw_int_field(json_wtr, "bpf_jit_enable", res);
  193. } else {
  194. switch (res) {
  195. case 0:
  196. printf("JIT compiler is disabled\n");
  197. break;
  198. case 1:
  199. printf("JIT compiler is enabled\n");
  200. break;
  201. case 2:
  202. printf("JIT compiler is enabled with debugging traces in kernel logs\n");
  203. break;
  204. case -1:
  205. printf("Unable to retrieve JIT-compiler status\n");
  206. break;
  207. default:
  208. printf("JIT-compiler status has unknown value %ld\n",
  209. res);
  210. }
  211. }
  212. }
  213. static void probe_jit_harden(void)
  214. {
  215. long res;
  216. /* No support for C-style ouptut */
  217. res = read_procfs("/proc/sys/net/core/bpf_jit_harden");
  218. if (json_output) {
  219. jsonw_int_field(json_wtr, "bpf_jit_harden", res);
  220. } else {
  221. switch (res) {
  222. case 0:
  223. printf("JIT compiler hardening is disabled\n");
  224. break;
  225. case 1:
  226. printf("JIT compiler hardening is enabled for unprivileged users\n");
  227. break;
  228. case 2:
  229. printf("JIT compiler hardening is enabled for all users\n");
  230. break;
  231. case -1:
  232. printf("Unable to retrieve JIT hardening status\n");
  233. break;
  234. default:
  235. printf("JIT hardening status has unknown value %ld\n",
  236. res);
  237. }
  238. }
  239. }
  240. static void probe_jit_kallsyms(void)
  241. {
  242. long res;
  243. /* No support for C-style ouptut */
  244. res = read_procfs("/proc/sys/net/core/bpf_jit_kallsyms");
  245. if (json_output) {
  246. jsonw_int_field(json_wtr, "bpf_jit_kallsyms", res);
  247. } else {
  248. switch (res) {
  249. case 0:
  250. printf("JIT compiler kallsyms exports are disabled\n");
  251. break;
  252. case 1:
  253. printf("JIT compiler kallsyms exports are enabled for root\n");
  254. break;
  255. case -1:
  256. printf("Unable to retrieve JIT kallsyms export status\n");
  257. break;
  258. default:
  259. printf("JIT kallsyms exports status has unknown value %ld\n", res);
  260. }
  261. }
  262. }
  263. static void probe_jit_limit(void)
  264. {
  265. long res;
  266. /* No support for C-style ouptut */
  267. res = read_procfs("/proc/sys/net/core/bpf_jit_limit");
  268. if (json_output) {
  269. jsonw_int_field(json_wtr, "bpf_jit_limit", res);
  270. } else {
  271. switch (res) {
  272. case -1:
  273. printf("Unable to retrieve global memory limit for JIT compiler for unprivileged users\n");
  274. break;
  275. default:
  276. printf("Global memory limit for JIT compiler for unprivileged users is %ld bytes\n", res);
  277. }
  278. }
  279. }
  280. static bool read_next_kernel_config_option(gzFile file, char *buf, size_t n,
  281. char **value)
  282. {
  283. char *sep;
  284. while (gzgets(file, buf, n)) {
  285. if (strncmp(buf, "CONFIG_", 7))
  286. continue;
  287. sep = strchr(buf, '=');
  288. if (!sep)
  289. continue;
  290. /* Trim ending '\n' */
  291. buf[strlen(buf) - 1] = '\0';
  292. /* Split on '=' and ensure that a value is present. */
  293. *sep = '\0';
  294. if (!sep[1])
  295. continue;
  296. *value = sep + 1;
  297. return true;
  298. }
  299. return false;
  300. }
  301. static void probe_kernel_image_config(const char *define_prefix)
  302. {
  303. static const struct {
  304. const char * const name;
  305. bool macro_dump;
  306. } options[] = {
  307. /* Enable BPF */
  308. { "CONFIG_BPF", },
  309. /* Enable bpf() syscall */
  310. { "CONFIG_BPF_SYSCALL", },
  311. /* Does selected architecture support eBPF JIT compiler */
  312. { "CONFIG_HAVE_EBPF_JIT", },
  313. /* Compile eBPF JIT compiler */
  314. { "CONFIG_BPF_JIT", },
  315. /* Avoid compiling eBPF interpreter (use JIT only) */
  316. { "CONFIG_BPF_JIT_ALWAYS_ON", },
  317. /* Kernel BTF debug information available */
  318. { "CONFIG_DEBUG_INFO_BTF", },
  319. /* Kernel module BTF debug information available */
  320. { "CONFIG_DEBUG_INFO_BTF_MODULES", },
  321. /* cgroups */
  322. { "CONFIG_CGROUPS", },
  323. /* BPF programs attached to cgroups */
  324. { "CONFIG_CGROUP_BPF", },
  325. /* bpf_get_cgroup_classid() helper */
  326. { "CONFIG_CGROUP_NET_CLASSID", },
  327. /* bpf_skb_{,ancestor_}cgroup_id() helpers */
  328. { "CONFIG_SOCK_CGROUP_DATA", },
  329. /* Tracing: attach BPF to kprobes, tracepoints, etc. */
  330. { "CONFIG_BPF_EVENTS", },
  331. /* Kprobes */
  332. { "CONFIG_KPROBE_EVENTS", },
  333. /* Uprobes */
  334. { "CONFIG_UPROBE_EVENTS", },
  335. /* Tracepoints */
  336. { "CONFIG_TRACING", },
  337. /* Syscall tracepoints */
  338. { "CONFIG_FTRACE_SYSCALLS", },
  339. /* bpf_override_return() helper support for selected arch */
  340. { "CONFIG_FUNCTION_ERROR_INJECTION", },
  341. /* bpf_override_return() helper */
  342. { "CONFIG_BPF_KPROBE_OVERRIDE", },
  343. /* Network */
  344. { "CONFIG_NET", },
  345. /* AF_XDP sockets */
  346. { "CONFIG_XDP_SOCKETS", },
  347. /* BPF_PROG_TYPE_LWT_* and related helpers */
  348. { "CONFIG_LWTUNNEL_BPF", },
  349. /* BPF_PROG_TYPE_SCHED_ACT, TC (traffic control) actions */
  350. { "CONFIG_NET_ACT_BPF", },
  351. /* BPF_PROG_TYPE_SCHED_CLS, TC filters */
  352. { "CONFIG_NET_CLS_BPF", },
  353. /* TC clsact qdisc */
  354. { "CONFIG_NET_CLS_ACT", },
  355. /* Ingress filtering with TC */
  356. { "CONFIG_NET_SCH_INGRESS", },
  357. /* bpf_skb_get_xfrm_state() helper */
  358. { "CONFIG_XFRM", },
  359. /* bpf_get_route_realm() helper */
  360. { "CONFIG_IP_ROUTE_CLASSID", },
  361. /* BPF_PROG_TYPE_LWT_SEG6_LOCAL and related helpers */
  362. { "CONFIG_IPV6_SEG6_BPF", },
  363. /* BPF_PROG_TYPE_LIRC_MODE2 and related helpers */
  364. { "CONFIG_BPF_LIRC_MODE2", },
  365. /* BPF stream parser and BPF socket maps */
  366. { "CONFIG_BPF_STREAM_PARSER", },
  367. /* xt_bpf module for passing BPF programs to netfilter */
  368. { "CONFIG_NETFILTER_XT_MATCH_BPF", },
  369. /* bpfilter back-end for iptables */
  370. { "CONFIG_BPFILTER", },
  371. /* bpftilter module with "user mode helper" */
  372. { "CONFIG_BPFILTER_UMH", },
  373. /* test_bpf module for BPF tests */
  374. { "CONFIG_TEST_BPF", },
  375. /* Misc configs useful in BPF C programs */
  376. /* jiffies <-> sec conversion for bpf_jiffies64() helper */
  377. { "CONFIG_HZ", true, }
  378. };
  379. char *values[ARRAY_SIZE(options)] = { };
  380. struct utsname utsn;
  381. char path[PATH_MAX];
  382. gzFile file = NULL;
  383. char buf[4096];
  384. char *value;
  385. size_t i;
  386. if (!uname(&utsn)) {
  387. snprintf(path, sizeof(path), "/boot/config-%s", utsn.release);
  388. /* gzopen also accepts uncompressed files. */
  389. file = gzopen(path, "r");
  390. }
  391. if (!file) {
  392. /* Some distributions build with CONFIG_IKCONFIG=y and put the
  393. * config file at /proc/config.gz.
  394. */
  395. file = gzopen("/proc/config.gz", "r");
  396. }
  397. if (!file) {
  398. p_info("skipping kernel config, can't open file: %s",
  399. strerror(errno));
  400. goto end_parse;
  401. }
  402. /* Sanity checks */
  403. if (!gzgets(file, buf, sizeof(buf)) ||
  404. !gzgets(file, buf, sizeof(buf))) {
  405. p_info("skipping kernel config, can't read from file: %s",
  406. strerror(errno));
  407. goto end_parse;
  408. }
  409. if (strcmp(buf, "# Automatically generated file; DO NOT EDIT.\n")) {
  410. p_info("skipping kernel config, can't find correct file");
  411. goto end_parse;
  412. }
  413. while (read_next_kernel_config_option(file, buf, sizeof(buf), &value)) {
  414. for (i = 0; i < ARRAY_SIZE(options); i++) {
  415. if ((define_prefix && !options[i].macro_dump) ||
  416. values[i] || strcmp(buf, options[i].name))
  417. continue;
  418. values[i] = strdup(value);
  419. }
  420. }
  421. end_parse:
  422. if (file)
  423. gzclose(file);
  424. for (i = 0; i < ARRAY_SIZE(options); i++) {
  425. if (define_prefix && !options[i].macro_dump)
  426. continue;
  427. print_kernel_option(options[i].name, values[i], define_prefix);
  428. free(values[i]);
  429. }
  430. }
  431. static bool probe_bpf_syscall(const char *define_prefix)
  432. {
  433. bool res;
  434. bpf_prog_load(BPF_PROG_TYPE_UNSPEC, NULL, NULL, NULL, 0, NULL);
  435. res = (errno != ENOSYS);
  436. print_bool_feature("have_bpf_syscall",
  437. "bpf() syscall",
  438. "BPF_SYSCALL",
  439. res, define_prefix);
  440. return res;
  441. }
  442. static bool
  443. probe_prog_load_ifindex(enum bpf_prog_type prog_type,
  444. const struct bpf_insn *insns, size_t insns_cnt,
  445. char *log_buf, size_t log_buf_sz,
  446. __u32 ifindex)
  447. {
  448. LIBBPF_OPTS(bpf_prog_load_opts, opts,
  449. .log_buf = log_buf,
  450. .log_size = log_buf_sz,
  451. .log_level = log_buf ? 1 : 0,
  452. .prog_ifindex = ifindex,
  453. );
  454. int fd;
  455. errno = 0;
  456. fd = bpf_prog_load(prog_type, NULL, "GPL", insns, insns_cnt, &opts);
  457. if (fd >= 0)
  458. close(fd);
  459. return fd >= 0 && errno != EINVAL && errno != EOPNOTSUPP;
  460. }
  461. static bool probe_prog_type_ifindex(enum bpf_prog_type prog_type, __u32 ifindex)
  462. {
  463. /* nfp returns -EINVAL on exit(0) with TC offload */
  464. struct bpf_insn insns[2] = {
  465. BPF_MOV64_IMM(BPF_REG_0, 2),
  466. BPF_EXIT_INSN()
  467. };
  468. return probe_prog_load_ifindex(prog_type, insns, ARRAY_SIZE(insns),
  469. NULL, 0, ifindex);
  470. }
  471. static void
  472. probe_prog_type(enum bpf_prog_type prog_type, const char *prog_type_str,
  473. bool *supported_types, const char *define_prefix, __u32 ifindex)
  474. {
  475. char feat_name[128], plain_desc[128], define_name[128];
  476. const char *plain_comment = "eBPF program_type ";
  477. size_t maxlen;
  478. bool res;
  479. if (ifindex) {
  480. switch (prog_type) {
  481. case BPF_PROG_TYPE_SCHED_CLS:
  482. case BPF_PROG_TYPE_XDP:
  483. break;
  484. default:
  485. return;
  486. }
  487. res = probe_prog_type_ifindex(prog_type, ifindex);
  488. } else {
  489. res = libbpf_probe_bpf_prog_type(prog_type, NULL) > 0;
  490. }
  491. #ifdef USE_LIBCAP
  492. /* Probe may succeed even if program load fails, for unprivileged users
  493. * check that we did not fail because of insufficient permissions
  494. */
  495. if (run_as_unprivileged && errno == EPERM)
  496. res = false;
  497. #endif
  498. supported_types[prog_type] |= res;
  499. maxlen = sizeof(plain_desc) - strlen(plain_comment) - 1;
  500. if (strlen(prog_type_str) > maxlen) {
  501. p_info("program type name too long");
  502. return;
  503. }
  504. sprintf(feat_name, "have_%s_prog_type", prog_type_str);
  505. sprintf(define_name, "%s_prog_type", prog_type_str);
  506. uppercase(define_name, sizeof(define_name));
  507. sprintf(plain_desc, "%s%s", plain_comment, prog_type_str);
  508. print_bool_feature(feat_name, plain_desc, define_name, res,
  509. define_prefix);
  510. }
  511. static bool probe_map_type_ifindex(enum bpf_map_type map_type, __u32 ifindex)
  512. {
  513. LIBBPF_OPTS(bpf_map_create_opts, opts);
  514. int key_size, value_size, max_entries;
  515. int fd;
  516. opts.map_ifindex = ifindex;
  517. key_size = sizeof(__u32);
  518. value_size = sizeof(__u32);
  519. max_entries = 1;
  520. fd = bpf_map_create(map_type, NULL, key_size, value_size, max_entries,
  521. &opts);
  522. if (fd >= 0)
  523. close(fd);
  524. return fd >= 0;
  525. }
  526. static void
  527. probe_map_type(enum bpf_map_type map_type, char const *map_type_str,
  528. const char *define_prefix, __u32 ifindex)
  529. {
  530. char feat_name[128], plain_desc[128], define_name[128];
  531. const char *plain_comment = "eBPF map_type ";
  532. size_t maxlen;
  533. bool res;
  534. if (ifindex) {
  535. switch (map_type) {
  536. case BPF_MAP_TYPE_HASH:
  537. case BPF_MAP_TYPE_ARRAY:
  538. break;
  539. default:
  540. return;
  541. }
  542. res = probe_map_type_ifindex(map_type, ifindex);
  543. } else {
  544. res = libbpf_probe_bpf_map_type(map_type, NULL) > 0;
  545. }
  546. /* Probe result depends on the success of map creation, no additional
  547. * check required for unprivileged users
  548. */
  549. maxlen = sizeof(plain_desc) - strlen(plain_comment) - 1;
  550. if (strlen(map_type_str) > maxlen) {
  551. p_info("map type name too long");
  552. return;
  553. }
  554. sprintf(feat_name, "have_%s_map_type", map_type_str);
  555. sprintf(define_name, "%s_map_type", map_type_str);
  556. uppercase(define_name, sizeof(define_name));
  557. sprintf(plain_desc, "%s%s", plain_comment, map_type_str);
  558. print_bool_feature(feat_name, plain_desc, define_name, res,
  559. define_prefix);
  560. }
  561. static bool
  562. probe_helper_ifindex(enum bpf_func_id id, enum bpf_prog_type prog_type,
  563. __u32 ifindex)
  564. {
  565. struct bpf_insn insns[2] = {
  566. BPF_EMIT_CALL(id),
  567. BPF_EXIT_INSN()
  568. };
  569. char buf[4096] = {};
  570. bool res;
  571. probe_prog_load_ifindex(prog_type, insns, ARRAY_SIZE(insns), buf,
  572. sizeof(buf), ifindex);
  573. res = !grep(buf, "invalid func ") && !grep(buf, "unknown func ");
  574. switch (get_vendor_id(ifindex)) {
  575. case 0x19ee: /* Netronome specific */
  576. res = res && !grep(buf, "not supported by FW") &&
  577. !grep(buf, "unsupported function id");
  578. break;
  579. default:
  580. break;
  581. }
  582. return res;
  583. }
  584. static bool
  585. probe_helper_for_progtype(enum bpf_prog_type prog_type, bool supported_type,
  586. const char *define_prefix, unsigned int id,
  587. const char *ptype_name, __u32 ifindex)
  588. {
  589. bool res = false;
  590. if (supported_type) {
  591. if (ifindex)
  592. res = probe_helper_ifindex(id, prog_type, ifindex);
  593. else
  594. res = libbpf_probe_bpf_helper(prog_type, id, NULL) > 0;
  595. #ifdef USE_LIBCAP
  596. /* Probe may succeed even if program load fails, for
  597. * unprivileged users check that we did not fail because of
  598. * insufficient permissions
  599. */
  600. if (run_as_unprivileged && errno == EPERM)
  601. res = false;
  602. #endif
  603. }
  604. if (json_output) {
  605. if (res)
  606. jsonw_string(json_wtr, helper_name[id]);
  607. } else if (define_prefix) {
  608. printf("#define %sBPF__PROG_TYPE_%s__HELPER_%s %s\n",
  609. define_prefix, ptype_name, helper_name[id],
  610. res ? "1" : "0");
  611. } else {
  612. if (res)
  613. printf("\n\t- %s", helper_name[id]);
  614. }
  615. return res;
  616. }
  617. static void
  618. probe_helpers_for_progtype(enum bpf_prog_type prog_type,
  619. const char *prog_type_str, bool supported_type,
  620. const char *define_prefix, __u32 ifindex)
  621. {
  622. char feat_name[128];
  623. unsigned int id;
  624. bool probe_res = false;
  625. if (ifindex)
  626. /* Only test helpers for offload-able program types */
  627. switch (prog_type) {
  628. case BPF_PROG_TYPE_SCHED_CLS:
  629. case BPF_PROG_TYPE_XDP:
  630. break;
  631. default:
  632. return;
  633. }
  634. if (json_output) {
  635. sprintf(feat_name, "%s_available_helpers", prog_type_str);
  636. jsonw_name(json_wtr, feat_name);
  637. jsonw_start_array(json_wtr);
  638. } else if (!define_prefix) {
  639. printf("eBPF helpers supported for program type %s:",
  640. prog_type_str);
  641. }
  642. for (id = 1; id < ARRAY_SIZE(helper_name); id++) {
  643. /* Skip helper functions which emit dmesg messages when not in
  644. * the full mode.
  645. */
  646. switch (id) {
  647. case BPF_FUNC_trace_printk:
  648. case BPF_FUNC_trace_vprintk:
  649. case BPF_FUNC_probe_write_user:
  650. if (!full_mode)
  651. continue;
  652. /* fallthrough */
  653. default:
  654. probe_res |= probe_helper_for_progtype(prog_type, supported_type,
  655. define_prefix, id, prog_type_str,
  656. ifindex);
  657. }
  658. }
  659. if (json_output)
  660. jsonw_end_array(json_wtr);
  661. else if (!define_prefix) {
  662. printf("\n");
  663. if (!probe_res) {
  664. if (!supported_type)
  665. printf("\tProgram type not supported\n");
  666. else
  667. printf("\tCould not determine which helpers are available\n");
  668. }
  669. }
  670. }
  671. static void
  672. probe_misc_feature(struct bpf_insn *insns, size_t len,
  673. const char *define_prefix, __u32 ifindex,
  674. const char *feat_name, const char *plain_name,
  675. const char *define_name)
  676. {
  677. LIBBPF_OPTS(bpf_prog_load_opts, opts,
  678. .prog_ifindex = ifindex,
  679. );
  680. bool res;
  681. int fd;
  682. errno = 0;
  683. fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL",
  684. insns, len, &opts);
  685. res = fd >= 0 || !errno;
  686. if (fd >= 0)
  687. close(fd);
  688. print_bool_feature(feat_name, plain_name, define_name, res,
  689. define_prefix);
  690. }
  691. /*
  692. * Probe for availability of kernel commit (5.3):
  693. *
  694. * c04c0d2b968a ("bpf: increase complexity limit and maximum program size")
  695. */
  696. static void probe_large_insn_limit(const char *define_prefix, __u32 ifindex)
  697. {
  698. struct bpf_insn insns[BPF_MAXINSNS + 1];
  699. int i;
  700. for (i = 0; i < BPF_MAXINSNS; i++)
  701. insns[i] = BPF_MOV64_IMM(BPF_REG_0, 1);
  702. insns[BPF_MAXINSNS] = BPF_EXIT_INSN();
  703. probe_misc_feature(insns, ARRAY_SIZE(insns),
  704. define_prefix, ifindex,
  705. "have_large_insn_limit",
  706. "Large program size limit",
  707. "LARGE_INSN_LIMIT");
  708. }
  709. /*
  710. * Probe for bounded loop support introduced in commit 2589726d12a1
  711. * ("bpf: introduce bounded loops").
  712. */
  713. static void
  714. probe_bounded_loops(const char *define_prefix, __u32 ifindex)
  715. {
  716. struct bpf_insn insns[4] = {
  717. BPF_MOV64_IMM(BPF_REG_0, 10),
  718. BPF_ALU64_IMM(BPF_SUB, BPF_REG_0, 1),
  719. BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, -2),
  720. BPF_EXIT_INSN()
  721. };
  722. probe_misc_feature(insns, ARRAY_SIZE(insns),
  723. define_prefix, ifindex,
  724. "have_bounded_loops",
  725. "Bounded loop support",
  726. "BOUNDED_LOOPS");
  727. }
  728. /*
  729. * Probe for the v2 instruction set extension introduced in commit 92b31a9af73b
  730. * ("bpf: add BPF_J{LT,LE,SLT,SLE} instructions").
  731. */
  732. static void
  733. probe_v2_isa_extension(const char *define_prefix, __u32 ifindex)
  734. {
  735. struct bpf_insn insns[4] = {
  736. BPF_MOV64_IMM(BPF_REG_0, 0),
  737. BPF_JMP_IMM(BPF_JLT, BPF_REG_0, 0, 1),
  738. BPF_MOV64_IMM(BPF_REG_0, 1),
  739. BPF_EXIT_INSN()
  740. };
  741. probe_misc_feature(insns, ARRAY_SIZE(insns),
  742. define_prefix, ifindex,
  743. "have_v2_isa_extension",
  744. "ISA extension v2",
  745. "V2_ISA_EXTENSION");
  746. }
  747. /*
  748. * Probe for the v3 instruction set extension introduced in commit 092ed0968bb6
  749. * ("bpf: verifier support JMP32").
  750. */
  751. static void
  752. probe_v3_isa_extension(const char *define_prefix, __u32 ifindex)
  753. {
  754. struct bpf_insn insns[4] = {
  755. BPF_MOV64_IMM(BPF_REG_0, 0),
  756. BPF_JMP32_IMM(BPF_JLT, BPF_REG_0, 0, 1),
  757. BPF_MOV64_IMM(BPF_REG_0, 1),
  758. BPF_EXIT_INSN()
  759. };
  760. probe_misc_feature(insns, ARRAY_SIZE(insns),
  761. define_prefix, ifindex,
  762. "have_v3_isa_extension",
  763. "ISA extension v3",
  764. "V3_ISA_EXTENSION");
  765. }
  766. static void
  767. section_system_config(enum probe_component target, const char *define_prefix)
  768. {
  769. switch (target) {
  770. case COMPONENT_KERNEL:
  771. case COMPONENT_UNSPEC:
  772. print_start_section("system_config",
  773. "Scanning system configuration...",
  774. "/*** Misc kernel config items ***/",
  775. define_prefix);
  776. if (!define_prefix) {
  777. if (check_procfs()) {
  778. probe_unprivileged_disabled();
  779. probe_jit_enable();
  780. probe_jit_harden();
  781. probe_jit_kallsyms();
  782. probe_jit_limit();
  783. } else {
  784. p_info("/* procfs not mounted, skipping related probes */");
  785. }
  786. }
  787. probe_kernel_image_config(define_prefix);
  788. print_end_section();
  789. break;
  790. default:
  791. break;
  792. }
  793. }
  794. static bool section_syscall_config(const char *define_prefix)
  795. {
  796. bool res;
  797. print_start_section("syscall_config",
  798. "Scanning system call availability...",
  799. "/*** System call availability ***/",
  800. define_prefix);
  801. res = probe_bpf_syscall(define_prefix);
  802. print_end_section();
  803. return res;
  804. }
  805. static void
  806. section_program_types(bool *supported_types, const char *define_prefix,
  807. __u32 ifindex)
  808. {
  809. unsigned int prog_type = BPF_PROG_TYPE_UNSPEC;
  810. const char *prog_type_str;
  811. print_start_section("program_types",
  812. "Scanning eBPF program types...",
  813. "/*** eBPF program types ***/",
  814. define_prefix);
  815. while (true) {
  816. prog_type++;
  817. prog_type_str = libbpf_bpf_prog_type_str(prog_type);
  818. /* libbpf will return NULL for variants unknown to it. */
  819. if (!prog_type_str)
  820. break;
  821. probe_prog_type(prog_type, prog_type_str, supported_types, define_prefix,
  822. ifindex);
  823. }
  824. print_end_section();
  825. }
  826. static void section_map_types(const char *define_prefix, __u32 ifindex)
  827. {
  828. unsigned int map_type = BPF_MAP_TYPE_UNSPEC;
  829. const char *map_type_str;
  830. print_start_section("map_types",
  831. "Scanning eBPF map types...",
  832. "/*** eBPF map types ***/",
  833. define_prefix);
  834. while (true) {
  835. map_type++;
  836. map_type_str = libbpf_bpf_map_type_str(map_type);
  837. /* libbpf will return NULL for variants unknown to it. */
  838. if (!map_type_str)
  839. break;
  840. probe_map_type(map_type, map_type_str, define_prefix, ifindex);
  841. }
  842. print_end_section();
  843. }
  844. static void
  845. section_helpers(bool *supported_types, const char *define_prefix, __u32 ifindex)
  846. {
  847. unsigned int prog_type = BPF_PROG_TYPE_UNSPEC;
  848. const char *prog_type_str;
  849. print_start_section("helpers",
  850. "Scanning eBPF helper functions...",
  851. "/*** eBPF helper functions ***/",
  852. define_prefix);
  853. if (define_prefix)
  854. printf("/*\n"
  855. " * Use %sHAVE_PROG_TYPE_HELPER(prog_type_name, helper_name)\n"
  856. " * to determine if <helper_name> is available for <prog_type_name>,\n"
  857. " * e.g.\n"
  858. " * #if %sHAVE_PROG_TYPE_HELPER(xdp, bpf_redirect)\n"
  859. " * // do stuff with this helper\n"
  860. " * #elif\n"
  861. " * // use a workaround\n"
  862. " * #endif\n"
  863. " */\n"
  864. "#define %sHAVE_PROG_TYPE_HELPER(prog_type, helper) \\\n"
  865. " %sBPF__PROG_TYPE_ ## prog_type ## __HELPER_ ## helper\n",
  866. define_prefix, define_prefix, define_prefix,
  867. define_prefix);
  868. while (true) {
  869. prog_type++;
  870. prog_type_str = libbpf_bpf_prog_type_str(prog_type);
  871. /* libbpf will return NULL for variants unknown to it. */
  872. if (!prog_type_str)
  873. break;
  874. probe_helpers_for_progtype(prog_type, prog_type_str,
  875. supported_types[prog_type],
  876. define_prefix,
  877. ifindex);
  878. }
  879. print_end_section();
  880. }
  881. static void section_misc(const char *define_prefix, __u32 ifindex)
  882. {
  883. print_start_section("misc",
  884. "Scanning miscellaneous eBPF features...",
  885. "/*** eBPF misc features ***/",
  886. define_prefix);
  887. probe_large_insn_limit(define_prefix, ifindex);
  888. probe_bounded_loops(define_prefix, ifindex);
  889. probe_v2_isa_extension(define_prefix, ifindex);
  890. probe_v3_isa_extension(define_prefix, ifindex);
  891. print_end_section();
  892. }
  893. #ifdef USE_LIBCAP
  894. #define capability(c) { c, false, #c }
  895. #define capability_msg(a, i) a[i].set ? "" : a[i].name, a[i].set ? "" : ", "
  896. #endif
  897. static int handle_perms(void)
  898. {
  899. #ifdef USE_LIBCAP
  900. struct {
  901. cap_value_t cap;
  902. bool set;
  903. char name[14]; /* strlen("CAP_SYS_ADMIN") */
  904. } bpf_caps[] = {
  905. capability(CAP_SYS_ADMIN),
  906. #ifdef CAP_BPF
  907. capability(CAP_BPF),
  908. capability(CAP_NET_ADMIN),
  909. capability(CAP_PERFMON),
  910. #endif
  911. };
  912. cap_value_t cap_list[ARRAY_SIZE(bpf_caps)];
  913. unsigned int i, nb_bpf_caps = 0;
  914. bool cap_sys_admin_only = true;
  915. cap_flag_value_t val;
  916. int res = -1;
  917. cap_t caps;
  918. caps = cap_get_proc();
  919. if (!caps) {
  920. p_err("failed to get capabilities for process: %s",
  921. strerror(errno));
  922. return -1;
  923. }
  924. #ifdef CAP_BPF
  925. if (CAP_IS_SUPPORTED(CAP_BPF))
  926. cap_sys_admin_only = false;
  927. #endif
  928. for (i = 0; i < ARRAY_SIZE(bpf_caps); i++) {
  929. const char *cap_name = bpf_caps[i].name;
  930. cap_value_t cap = bpf_caps[i].cap;
  931. if (cap_get_flag(caps, cap, CAP_EFFECTIVE, &val)) {
  932. p_err("bug: failed to retrieve %s status: %s", cap_name,
  933. strerror(errno));
  934. goto exit_free;
  935. }
  936. if (val == CAP_SET) {
  937. bpf_caps[i].set = true;
  938. cap_list[nb_bpf_caps++] = cap;
  939. }
  940. if (cap_sys_admin_only)
  941. /* System does not know about CAP_BPF, meaning that
  942. * CAP_SYS_ADMIN is the only capability required. We
  943. * just checked it, break.
  944. */
  945. break;
  946. }
  947. if ((run_as_unprivileged && !nb_bpf_caps) ||
  948. (!run_as_unprivileged && nb_bpf_caps == ARRAY_SIZE(bpf_caps)) ||
  949. (!run_as_unprivileged && cap_sys_admin_only && nb_bpf_caps)) {
  950. /* We are all good, exit now */
  951. res = 0;
  952. goto exit_free;
  953. }
  954. if (!run_as_unprivileged) {
  955. if (cap_sys_admin_only)
  956. p_err("missing %s, required for full feature probing; run as root or use 'unprivileged'",
  957. bpf_caps[0].name);
  958. else
  959. p_err("missing %s%s%s%s%s%s%s%srequired for full feature probing; run as root or use 'unprivileged'",
  960. capability_msg(bpf_caps, 0),
  961. #ifdef CAP_BPF
  962. capability_msg(bpf_caps, 1),
  963. capability_msg(bpf_caps, 2),
  964. capability_msg(bpf_caps, 3)
  965. #else
  966. "", "", "", "", "", ""
  967. #endif /* CAP_BPF */
  968. );
  969. goto exit_free;
  970. }
  971. /* if (run_as_unprivileged && nb_bpf_caps > 0), drop capabilities. */
  972. if (cap_set_flag(caps, CAP_EFFECTIVE, nb_bpf_caps, cap_list,
  973. CAP_CLEAR)) {
  974. p_err("bug: failed to clear capabilities: %s", strerror(errno));
  975. goto exit_free;
  976. }
  977. if (cap_set_proc(caps)) {
  978. p_err("failed to drop capabilities: %s", strerror(errno));
  979. goto exit_free;
  980. }
  981. res = 0;
  982. exit_free:
  983. if (cap_free(caps) && !res) {
  984. p_err("failed to clear storage object for capabilities: %s",
  985. strerror(errno));
  986. res = -1;
  987. }
  988. return res;
  989. #else
  990. /* Detection assumes user has specific privileges.
  991. * We do not use libcap so let's approximate, and restrict usage to
  992. * root user only.
  993. */
  994. if (geteuid()) {
  995. p_err("full feature probing requires root privileges");
  996. return -1;
  997. }
  998. return 0;
  999. #endif /* USE_LIBCAP */
  1000. }
  1001. static int do_probe(int argc, char **argv)
  1002. {
  1003. enum probe_component target = COMPONENT_UNSPEC;
  1004. const char *define_prefix = NULL;
  1005. bool supported_types[128] = {};
  1006. __u32 ifindex = 0;
  1007. char *ifname;
  1008. set_max_rlimit();
  1009. while (argc) {
  1010. if (is_prefix(*argv, "kernel")) {
  1011. if (target != COMPONENT_UNSPEC) {
  1012. p_err("component to probe already specified");
  1013. return -1;
  1014. }
  1015. target = COMPONENT_KERNEL;
  1016. NEXT_ARG();
  1017. } else if (is_prefix(*argv, "dev")) {
  1018. NEXT_ARG();
  1019. if (target != COMPONENT_UNSPEC || ifindex) {
  1020. p_err("component to probe already specified");
  1021. return -1;
  1022. }
  1023. if (!REQ_ARGS(1))
  1024. return -1;
  1025. target = COMPONENT_DEVICE;
  1026. ifname = GET_ARG();
  1027. ifindex = if_nametoindex(ifname);
  1028. if (!ifindex) {
  1029. p_err("unrecognized netdevice '%s': %s", ifname,
  1030. strerror(errno));
  1031. return -1;
  1032. }
  1033. } else if (is_prefix(*argv, "full")) {
  1034. full_mode = true;
  1035. NEXT_ARG();
  1036. } else if (is_prefix(*argv, "macros") && !define_prefix) {
  1037. define_prefix = "";
  1038. NEXT_ARG();
  1039. } else if (is_prefix(*argv, "prefix")) {
  1040. if (!define_prefix) {
  1041. p_err("'prefix' argument can only be use after 'macros'");
  1042. return -1;
  1043. }
  1044. if (strcmp(define_prefix, "")) {
  1045. p_err("'prefix' already defined");
  1046. return -1;
  1047. }
  1048. NEXT_ARG();
  1049. if (!REQ_ARGS(1))
  1050. return -1;
  1051. define_prefix = GET_ARG();
  1052. } else if (is_prefix(*argv, "unprivileged")) {
  1053. #ifdef USE_LIBCAP
  1054. run_as_unprivileged = true;
  1055. NEXT_ARG();
  1056. #else
  1057. p_err("unprivileged run not supported, recompile bpftool with libcap");
  1058. return -1;
  1059. #endif
  1060. } else {
  1061. p_err("expected no more arguments, 'kernel', 'dev', 'macros' or 'prefix', got: '%s'?",
  1062. *argv);
  1063. return -1;
  1064. }
  1065. }
  1066. /* Full feature detection requires specific privileges.
  1067. * Let's approximate, and warn if user is not root.
  1068. */
  1069. if (handle_perms())
  1070. return -1;
  1071. if (json_output) {
  1072. define_prefix = NULL;
  1073. jsonw_start_object(json_wtr);
  1074. }
  1075. section_system_config(target, define_prefix);
  1076. if (!section_syscall_config(define_prefix))
  1077. /* bpf() syscall unavailable, don't probe other BPF features */
  1078. goto exit_close_json;
  1079. section_program_types(supported_types, define_prefix, ifindex);
  1080. section_map_types(define_prefix, ifindex);
  1081. section_helpers(supported_types, define_prefix, ifindex);
  1082. section_misc(define_prefix, ifindex);
  1083. exit_close_json:
  1084. if (json_output)
  1085. /* End root object */
  1086. jsonw_end_object(json_wtr);
  1087. return 0;
  1088. }
  1089. static const char *get_helper_name(unsigned int id)
  1090. {
  1091. if (id >= ARRAY_SIZE(helper_name))
  1092. return NULL;
  1093. return helper_name[id];
  1094. }
  1095. static int do_list_builtins(int argc, char **argv)
  1096. {
  1097. const char *(*get_name)(unsigned int id);
  1098. unsigned int id = 0;
  1099. if (argc < 1)
  1100. usage();
  1101. if (is_prefix(*argv, "prog_types")) {
  1102. get_name = (const char *(*)(unsigned int))libbpf_bpf_prog_type_str;
  1103. } else if (is_prefix(*argv, "map_types")) {
  1104. get_name = (const char *(*)(unsigned int))libbpf_bpf_map_type_str;
  1105. } else if (is_prefix(*argv, "attach_types")) {
  1106. get_name = (const char *(*)(unsigned int))libbpf_bpf_attach_type_str;
  1107. } else if (is_prefix(*argv, "link_types")) {
  1108. get_name = (const char *(*)(unsigned int))libbpf_bpf_link_type_str;
  1109. } else if (is_prefix(*argv, "helpers")) {
  1110. get_name = get_helper_name;
  1111. } else {
  1112. p_err("expected 'prog_types', 'map_types', 'attach_types', 'link_types' or 'helpers', got: %s", *argv);
  1113. return -1;
  1114. }
  1115. if (json_output)
  1116. jsonw_start_array(json_wtr); /* root array */
  1117. while (true) {
  1118. const char *name;
  1119. name = get_name(id++);
  1120. if (!name)
  1121. break;
  1122. if (json_output)
  1123. jsonw_string(json_wtr, name);
  1124. else
  1125. printf("%s\n", name);
  1126. }
  1127. if (json_output)
  1128. jsonw_end_array(json_wtr); /* root array */
  1129. return 0;
  1130. }
  1131. static int do_help(int argc, char **argv)
  1132. {
  1133. if (json_output) {
  1134. jsonw_null(json_wtr);
  1135. return 0;
  1136. }
  1137. fprintf(stderr,
  1138. "Usage: %1$s %2$s probe [COMPONENT] [full] [unprivileged] [macros [prefix PREFIX]]\n"
  1139. " %1$s %2$s list_builtins GROUP\n"
  1140. " %1$s %2$s help\n"
  1141. "\n"
  1142. " COMPONENT := { kernel | dev NAME }\n"
  1143. " GROUP := { prog_types | map_types | attach_types | link_types | helpers }\n"
  1144. " " HELP_SPEC_OPTIONS " }\n"
  1145. "",
  1146. bin_name, argv[-2]);
  1147. return 0;
  1148. }
  1149. static const struct cmd cmds[] = {
  1150. { "probe", do_probe },
  1151. { "list_builtins", do_list_builtins },
  1152. { "help", do_help },
  1153. { 0 }
  1154. };
  1155. int do_feature(int argc, char **argv)
  1156. {
  1157. return cmd_select(cmds, argc, argv, do_help);
  1158. }