|
6 | 6 | #include <string.h> |
7 | 7 | #include <unistd.h> |
8 | 8 | #include <net/if.h> |
| 9 | +#ifdef USE_LIBCAP |
9 | 10 | #include <sys/capability.h> |
| 11 | +#endif |
10 | 12 | #include <sys/utsname.h> |
11 | 13 | #include <sys/vfs.h> |
12 | 14 |
|
@@ -37,7 +39,9 @@ static const char * const helper_name[] = { |
37 | 39 | #undef BPF_HELPER_MAKE_ENTRY |
38 | 40 |
|
39 | 41 | static bool full_mode; |
| 42 | +#ifdef USE_LIBCAP |
40 | 43 | static bool run_as_unprivileged; |
| 44 | +#endif |
41 | 45 |
|
42 | 46 | /* Miscellaneous utility functions */ |
43 | 47 |
|
@@ -475,11 +479,13 @@ probe_prog_type(enum bpf_prog_type prog_type, bool *supported_types, |
475 | 479 | } |
476 | 480 |
|
477 | 481 | res = bpf_probe_prog_type(prog_type, ifindex); |
| 482 | +#ifdef USE_LIBCAP |
478 | 483 | /* Probe may succeed even if program load fails, for unprivileged users |
479 | 484 | * check that we did not fail because of insufficient permissions |
480 | 485 | */ |
481 | 486 | if (run_as_unprivileged && errno == EPERM) |
482 | 487 | res = false; |
| 488 | +#endif |
483 | 489 |
|
484 | 490 | supported_types[prog_type] |= res; |
485 | 491 |
|
@@ -535,12 +541,14 @@ probe_helper_for_progtype(enum bpf_prog_type prog_type, bool supported_type, |
535 | 541 |
|
536 | 542 | if (supported_type) { |
537 | 543 | res = bpf_probe_helper(id, prog_type, ifindex); |
| 544 | +#ifdef USE_LIBCAP |
538 | 545 | /* Probe may succeed even if program load fails, for |
539 | 546 | * unprivileged users check that we did not fail because of |
540 | 547 | * insufficient permissions |
541 | 548 | */ |
542 | 549 | if (run_as_unprivileged && errno == EPERM) |
543 | 550 | res = false; |
| 551 | +#endif |
544 | 552 | } |
545 | 553 |
|
546 | 554 | if (json_output) { |
@@ -738,6 +746,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex) |
738 | 746 |
|
739 | 747 | static int handle_perms(void) |
740 | 748 | { |
| 749 | +#ifdef USE_LIBCAP |
741 | 750 | cap_value_t cap_list[1] = { CAP_SYS_ADMIN }; |
742 | 751 | bool has_sys_admin_cap = false; |
743 | 752 | cap_flag_value_t val; |
@@ -793,6 +802,18 @@ static int handle_perms(void) |
793 | 802 | } |
794 | 803 |
|
795 | 804 | return res; |
| 805 | +#else |
| 806 | + /* Detection assumes user has sufficient privileges (CAP_SYS_ADMIN). |
| 807 | + * We do not use libpcap so let's approximate, and restrict usage to |
| 808 | + * root user only. |
| 809 | + */ |
| 810 | + if (geteuid()) { |
| 811 | + p_err("full feature probing requires root privileges"); |
| 812 | + return -1; |
| 813 | + } |
| 814 | + |
| 815 | + return 0; |
| 816 | +#endif /* USE_LIBCAP */ |
796 | 817 | } |
797 | 818 |
|
798 | 819 | static int do_probe(int argc, char **argv) |
@@ -852,8 +873,13 @@ static int do_probe(int argc, char **argv) |
852 | 873 | return -1; |
853 | 874 | define_prefix = GET_ARG(); |
854 | 875 | } else if (is_prefix(*argv, "unprivileged")) { |
| 876 | +#ifdef USE_LIBCAP |
855 | 877 | run_as_unprivileged = true; |
856 | 878 | NEXT_ARG(); |
| 879 | +#else |
| 880 | + p_err("unprivileged run not supported, recompile bpftool with libcap"); |
| 881 | + return -1; |
| 882 | +#endif |
857 | 883 | } else { |
858 | 884 | p_err("expected no more arguments, 'kernel', 'dev', 'macros' or 'prefix', got: '%s'?", |
859 | 885 | *argv); |
|
0 commit comments