Skip to content

Commit 1190b44

Browse files
committed
WIP: local sockets stack bypass
1 parent 9f3396a commit 1190b44

7 files changed

+184
-26
lines changed

Makefile

+48-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,35 @@
1-
BIN=bin
2-
KRNDIR=/home/rahul/rnd/linux-5.3
3-
CL=clang
4-
CC=gcc
5-
CFLAGS:=-Isrc -O2 -Wall
6-
KCFLAGS:=$(CFLAGS) -funroll-loops -I/usr/include/x86_64-linux-gnu -O2 -target bpf
7-
UCFLAGS:=$(CFLAGS) -I $(KRNDIR)/tools/lib -Wall
8-
ULDFLAGS:=$(KRNDIR)/tools/lib/bpf/libbpf.a -lelf
1+
ifeq (,$(KRNDIR))
2+
KRNDIR = /home/rahul/rnd/linux-5.3
3+
endif
4+
5+
BIN = bin
6+
CL = clang
7+
CC = gcc
8+
Q = @
9+
10+
ifeq ($(V),1)
11+
Q =
12+
endif
13+
14+
# This is shamelessly copied from kernel's samples/bpf/Makefile
15+
KF = -nostdinc -isystem /usr/lib/gcc/x86_64-linux-gnu/7/include \
16+
-I$(KRNDIR)/arch/x86/include -I$(KRNDIR)/arch/x86/include/generated \
17+
-I$(KRNDIR)/include -I$(KRNDIR)/arch/x86/include/uapi \
18+
-I$(KRNDIR)/arch/x86/include/generated/uapi -I$(KRNDIR)/include/uapi \
19+
-I$(KRNDIR)/include/generated/uapi \
20+
-include $(KRNDIR)/include/linux/kconfig.h \
21+
-include asm_goto_workaround.h \
22+
-I$(KRNDIR)/samples/bpf -I$(KRNDIR)/tools/testing/selftests/bpf/ -Isrc \
23+
-D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \
24+
-D__TARGET_ARCH_x86 -Wno-compare-distinct-pointer-types \
25+
-Wno-gnu-variable-sized-type-not-at-end \
26+
-Wno-address-of-packed-member -Wno-tautological-compare \
27+
-Wno-unknown-warning-option \
28+
-O2 -emit-llvm
29+
30+
UF = -Isrc -O2 -I $(KRNDIR)/tools/lib -Wall
31+
UDF = $(KRNDIR)/tools/lib/bpf/libbpf.a -lelf
32+
933
SRCDIR=src
1034

1135
SRCS_KERN:=$(wildcard $(SRCDIR)/*-kern.c)
@@ -18,18 +42,29 @@ UBINS:=$(patsubst %.c,$(BIN)/%.bin,$(SRCN))
1842

1943
vpath %.c $(SRCDIR)
2044

45+
RED=\033[0;31m
46+
GREEN=\033[0;32m
47+
CYAN=\033[0;36m
48+
NC=\033[0m
49+
2150
.PHONY: all
22-
all: mkdir $(BOBJS) $(UBINS)
51+
all: chkdir $(BOBJS) $(UBINS)
2352

24-
.PHONY: mkdir
25-
mkdir:
53+
.PHONY: chkdir
54+
chkdir:
55+
ifeq (,$(wildcard $(KRNDIR)/Kconfig))
56+
@echo "Your kernel path[$(RED)$(KRNDIR)$(NC)] is incorrect. Use 'make KRNDIR=[KERNEL-SRC-PATH]'."
57+
Quitting abnormally
58+
endif
2659
@mkdir -p $(BIN) 2>/dev/null
2760

2861
$(BIN)/%.bin: %.c
29-
$(CC) $(UCFLAGS) $< -o $@ $(ULDFLAGS)
62+
@echo "Compiling user-space app: $(CYAN)$@$(NC) ..."
63+
$(Q)$(CC) $(UF) $< -o $@ $(UDF)
3064

3165
$(BIN)/%.bo: %.c
32-
$(CL) $(KCFLAGS) -c $< -o $@
66+
@echo "Compiling eBPF bytecode: $(GREEN)$@$(NC) ..."
67+
$(Q)$(CL) $(KF) -c $< -o -| llc -march=bpf -mcpu=probe -filetype=obj -o $@
3368

3469
.PHONY: clean
3570
clean:

Makefile.old

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
BIN=bin
2+
KRNDIR=/home/rahul/rnd/linux-5.3
3+
CL=clang
4+
CC=gcc
5+
CFLAGS:=-Isrc -O2 -Wall
6+
KCFLAGS:=$(CFLAGS) -funroll-loops -I$(KRNDIR)/tools/testing/selftests/bpf -O2 -target bpf
7+
UCFLAGS:=$(CFLAGS) -I $(KRNDIR)/tools/lib -Wall
8+
ULDFLAGS:=$(KRNDIR)/tools/lib/bpf/libbpf.a -lelf
9+
SRCDIR=src
10+
11+
SRCS_KERN:=$(wildcard $(SRCDIR)/*-kern.c)
12+
SRCN:=$(notdir $(SRCS_KERN))
13+
BOBJS:=$(patsubst %.c,$(BIN)/%.bo,$(SRCN))
14+
15+
SRCS_USER:=$(wildcard $(SRCDIR)/*-user.c)
16+
SRCN:=$(notdir $(SRCS_USER))
17+
UBINS:=$(patsubst %.c,$(BIN)/%.bin,$(SRCN))
18+
19+
vpath %.c $(SRCDIR)
20+
21+
.PHONY: all
22+
all: mkdir $(BOBJS) $(UBINS)
23+
24+
.PHONY: mkdir
25+
mkdir:
26+
@mkdir -p $(BIN) 2>/dev/null
27+
28+
$(BIN)/%.bin: %.c
29+
$(CC) $(UCFLAGS) $< -o $@ $(ULDFLAGS)
30+
31+
$(BIN)/%.bo: %.c
32+
$(CL) $(KCFLAGS) -c $< -o $@
33+
34+
.PHONY: clean
35+
clean:
36+
@rm -rf $(BIN)

load_tc.sh

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
IFACE=lo
44
[[ $UID -ne 0 ]] && echo "Need to be root" && exit 2
5+
[[ ! -f "bin/drop-spoofs-kern.bo" ]] && echo "do a make first" && exit 2
56

67
function unload()
78
{

run_as_cgroupv2.sh

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/bin/bash
2+
[[ $UID -ne 0 ]] && echo "need to be root" && exit 2
3+
[[ $(which curl) == "" ]] && echo "need util curl" && exit 2
4+
[[ $(which timeout) == "" ]] && echo "need util timeout" && exit 2
5+
6+
CGRP_MNT=/tmp/cgroupv2
7+
FOO=$CGRP_MNT/foo
8+
PINPT=/sys/fs/bpf/mytestprog
9+
BO=bin/local-socket-bypass-kern.bo
10+
BPF_MNT=/sys/fs/bpf
11+
12+
trap 'unload "$BASH_COMMAND"' EXIT
13+
14+
unload()
15+
{
16+
[[ $? -ne 0 ]] && echo "Failed: [$1]"
17+
echo "unloading..."
18+
set +e
19+
bpftool cgroup detach $FOO sock_ops pinned $PINPT 2>/dev/null
20+
umount $CGRP_MNT
21+
[[ -d "$CGRP_MNT" ]] && rm -rf $CGRP_MNT
22+
umount $BPF_MNT
23+
}
24+
25+
# Inspired by: https://github.com/torvalds/linux/blob/master/samples/bpf/tcp_bpf.readme
26+
load()
27+
{
28+
mountpoint $BPF_MNT >/dev/null
29+
[[ $? -ne 0 ]] && mount -t bpf none $BPF_MNT
30+
31+
mkdir -p $CGRP_MNT
32+
mountpoint $CGRP_MNT >/dev/null
33+
[[ $? -ne 0 ]] && mount -t cgroup2 none $CGRP_MNT
34+
35+
set -eE -o functrace
36+
mkdir -p $FOO
37+
echo $$ >> $FOO/cgroup.procs
38+
bpftool prog load $BO $PINPT
39+
bpftool cgroup attach $FOO sock_ops pinned $PINPT
40+
}
41+
42+
load
43+
44+
### Start of Action
45+
46+
curl http://www.baidu.com
47+
48+
### End of Action
49+
50+
timeout --preserve-status 1s bpftool prog tracelog

src/drop-spoofs-kern.c

+5-6
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
* Do not allow a container to generate spoofed packet
33
*/
44

5-
#include <stdint.h>
6-
#include <linux/bpf.h>
7-
#include <linux/ip.h>
8-
#include <linux/in.h>
9-
#include <linux/pkt_cls.h>
10-
#include <linux/if_ether.h>
5+
#include <uapi/linux/bpf.h>
6+
#include <uapi/linux/ip.h>
7+
#include <uapi/linux/in.h>
8+
#include <uapi/linux/pkt_cls.h>
9+
#include <uapi/linux/if_ether.h>
1110
#include "drop-spoofs.h"
1211

1312
#ifndef SEC

src/local-socket-bypass-kern.c

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Completely bypass kernel TCP/IP stack for local socket.
3+
* Note:
4+
* 1. sockmap can be used only for TCP sockets
5+
* 2. since tcp/ip stack is bypassed, underneath tooling such as tcpdump and
6+
* other OAM/stats collection will not work for these bypassed sockets.
7+
* 3.
8+
*/
9+
10+
#include <uapi/linux/bpf.h>
11+
#include <linux/version.h>
12+
13+
#include "bpf_helpers.h"
14+
15+
struct bpf_map_def SEC("maps") sock_ops = {
16+
.type = BPF_MAP_TYPE_SOCKMAP,
17+
.key_size = sizeof(int),
18+
.value_size = sizeof(unsigned int),
19+
.max_entries = 2,
20+
};
21+
22+
SEC("sockops")
23+
int sock_map_update(struct bpf_sock_ops *ops)
24+
{
25+
int op;
26+
op = (int) ops->op;
27+
28+
bpf_printk("XYZ BPF command: %d\n", op);
29+
if (op == BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB || op == BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB) {
30+
uint32_t idx = 0;
31+
bpf_printk("Calling UPDATE: %d %d\n", op, BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB);
32+
bpf_sock_map_update(ops, &sock_ops, &idx, BPF_ANY);
33+
}
34+
35+
return 0;
36+
}
37+
38+
char _license[] SEC("license") = "GPL";
39+
int _version SEC("version") = LINUX_VERSION_CODE;

src/xdp-drop-kern.c

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44
* Check: block-tcp-8080.rst for details
55
*/
66

7-
#include <linux/bpf.h>
8-
#include <linux/in.h>
9-
#include <linux/if_ether.h>
10-
#include <linux/ip.h>
11-
#include <linux/tcp.h>
12-
13-
#define htons(x) ((__be16)___constant_swab16((x)))
7+
#include <uapi/linux/bpf.h>
8+
#include <uapi/linux/in.h>
9+
#include <uapi/linux/if_ether.h>
10+
#include <uapi/linux/ip.h>
11+
#include <uapi/linux/tcp.h>
1412

1513
// Sizeof all headers till TCP
1614
#define TOTSZ (sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct tcphdr))

0 commit comments

Comments
 (0)