summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicolas Douma <nicolas@serveur.io>2020-04-28 16:40:15 +0200
committerNicolas Douma <nicolas@serveur.io>2020-04-28 16:40:15 +0200
commita6880abb439e0fa48ea8c1cbd90f51919cba33da (patch)
treec1b0749772911491508892347726ffe88f31467b
parentPad struct bpf_load_program_attr with zeroes in case new fields are added (diff)
downloadnetifexec-a6880abb439e0fa48ea8c1cbd90f51919cba33da.tar.xz
netifexec-a6880abb439e0fa48ea8c1cbd90f51919cba33da.zip
Make SO_BINDTODEVICE return -EPERM instead of nothing
-rw-r--r--netifexec.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/netifexec.c b/netifexec.c
index c2f014d..f488678 100644
--- a/netifexec.c
+++ b/netifexec.c
@@ -1,4 +1,3 @@
-#include <linux/version.h>
#include <sys/eventfd.h>
#include <sys/prctl.h>
#include <sys/types.h>
@@ -12,9 +11,7 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
-#include <limits.h>
#include <fcntl.h>
-#include <stdio.h>
#include <time.h>
#include <mntent.h>
#include <errno.h>
@@ -237,11 +234,11 @@ static int ifindex(const char *ifname)
* @param bpf_name The expect name of the eBPF program
* @return A boolean that tells whether the eBPF program is effective.
*/
-static bool bpf_already_effective(int cgroupfd, const char *bpf_name)
+static bool bpf_already_effective(int cgroupfd, int attach_type, const char *bpf_name)
{
uint32_t bpf_prog_ids[1024];
uint32_t attach_flags, prog_cnt = sizeof(bpf_prog_ids) / sizeof(*bpf_prog_ids);
- CHK(bpf_prog_query(cgroupfd, BPF_CGROUP_INET_SOCK_CREATE, BPF_F_QUERY_EFFECTIVE,
+ CHK(bpf_prog_query(cgroupfd, attach_type, BPF_F_QUERY_EFFECTIVE,
&attach_flags, bpf_prog_ids, &prog_cnt), "Unable to query bpf programs on cgroup");
bool has_bpf = false;
if (prog_cnt > 0) {
@@ -383,7 +380,7 @@ static void hook_sock_create(int cgroupfd, char *iface)
if (snprintf(bpf_name, sizeof(bpf_name), "netifexec_%s", iface) >= sizeof(bpf_name))
errx(1, "Interface name too long");
- if (bpf_already_effective(cgroupfd, bpf_name))
+ if (bpf_already_effective(cgroupfd, BPF_CGROUP_INET_SOCK_CREATE, bpf_name))
return;
int index = ifindex(iface);
@@ -436,28 +433,26 @@ static void hook_setsockopt(int cgroupfd, char *iface)
if (snprintf(bpf_name, sizeof(bpf_name), "sopt_%s", iface) >= sizeof(bpf_name))
errx(1, "Interface name too long");
- if (bpf_already_effective(cgroupfd, bpf_name))
+ if (bpf_already_effective(cgroupfd, BPF_CGROUP_SETSOCKOPT, bpf_name))
return;
/*
- * 0: (61) r2 = *(u32 *)(r1 +24)
- * 1: (55) if r2 != 0x1 goto pc+5
- * 2: (61) r2 = *(u32 *)(r1 +28)
- * 3: (55) if r2 != 0x19 goto pc+3
- * 4: (18) r2 = 0xffffffff
- * 6: (63) *(u32 *)(r1 +32) = r2
- * 7: (b7) r0 = 1
- * 8: (95) exit
+ * 0: (b7) r0 = 1
+ * 1: (61) r2 = *(u32 *)(r1 +24)
+ * 2: (55) if r2 != 0x1 goto pc+3
+ * 3: (61) r2 = *(u32 *)(r1 +28)
+ * 4: (55) if r2 != 0x19 goto pc+1
+ * 5: (b7) r0 = 0
+ * 6: (95) exit
*/
struct bpf_insn bpf_program[] = {
+ BPF_MOV64_IMM(BPF_REG_0, SK_PASS),
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct bpf_sockopt, level)),
- BPF_JMP_IMM(BPF_AND, BPF_REG_2, SOL_SOCKET, 5),
+ BPF_JMP_IMM(BPF_AND, BPF_REG_2, SOL_SOCKET, 3),
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, offsetof(struct bpf_sockopt, optname)),
- BPF_JMP_IMM(BPF_AND, BPF_REG_2, SO_BINDTODEVICE, 3),
- BPF_LD_IMM64(BPF_REG_2, 0xFFFFFFFFUL),
- BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_2, offsetof(struct bpf_sockopt, optlen)),
- BPF_MOV64_IMM(BPF_REG_0, 1),
+ BPF_JMP_IMM(BPF_AND, BPF_REG_2, SO_BINDTODEVICE, 1),
+ BPF_MOV64_IMM(BPF_REG_0, SK_DROP),
BPF_EXIT_INSN()
};