Skip to content

Commit 5e9faf2

Browse files
torvalds#267 Load Lua scripts with luaL_loadbufferx and handle user input correctly
1 parent ee97fe9 commit 5e9faf2

File tree

6 files changed

+99
-49
lines changed

6 files changed

+99
-49
lines changed

include/net/xdplua.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,21 @@
2222

2323
struct xdp_lua_work {
2424
char script[XDP_LUA_MAX_SCRIPT_LEN];
25+
size_t script_len;
2526
struct lua_State *L;
2627
struct sk_buff *skb;
2728
struct work_struct work;
2829
};
2930

3031
DECLARE_PER_CPU(struct xdp_lua_work, luaworks);
3132

33+
3234
#define XDP_LUA_BPF_FUNC(name) BPF_FUNC_lua_##name
3335

3436
#define xdp_lua_get_skb() (this_cpu_ptr(&luaworks)->skb)
3537
#define xdp_lua_set_skb(skb) (this_cpu_ptr(&luaworks)->skb = skb)
3638

37-
void generic_xdp_lua_install_prog(const char *script);
39+
int generic_xdp_lua_install_prog(const char *script, size_t script_len);
3840
void xdp_lua_init(void);
3941

4042
#define __BPF_LUA_MAP_0(l, m, v, ...) l

net/core/rtnetlink.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,14 +2663,14 @@ static int do_setlink(const struct sk_buff *skb,
26632663
#ifdef CONFIG_XDP_LUA
26642664
if (xdp[IFLA_XDP_LUA_PROG]) {
26652665
const char *script;
2666+
int script_len;
26662667

26672668
script = nla_data(xdp[IFLA_XDP_LUA_PROG]);
2668-
if (!script) {
2669-
err = -EINVAL;
2670-
goto errout;
2671-
}
2669+
script_len = nla_len(xdp[IFLA_XDP_LUA_PROG]);
26722670

2673-
generic_xdp_lua_install_prog(script);
2671+
err = generic_xdp_lua_install_prog(script, script_len);
2672+
if (err)
2673+
goto errout;
26742674
}
26752675
#endif /* CONFIG_XDP_LUA */
26762676
}

net/core/xdplua.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,23 +25,39 @@ static void per_cpu_xdp_lua_install(struct work_struct *w)
2525
lw = container_of(w, struct xdp_lua_work, work);
2626

2727
local_bh_disable();
28-
if (luaL_dostring(lw->L, lw->script)) {
29-
pr_err(KERN_INFO "error: %s\nOn cpu: %d\n",
28+
if (luaL_loadbufferx(lw->L, lw->script, lw->script_len, NULL, "t")) {
29+
pr_err("error loading Lua script: %s\non cpu: %d\n",
3030
lua_tostring(lw->L, -1), this_cpu);
3131
lua_pop(lw->L, 1);
32+
goto enable;
3233
}
34+
35+
if (lua_pcall(lw->L, 0, LUA_MULTRET, 0)) {
36+
pr_err("error running Lua script: %s\non cpu: %d\n",
37+
lua_tostring(lw->L, -1), this_cpu);
38+
lua_pop(lw->L, 1);
39+
}
40+
41+
enable:
3342
local_bh_enable();
3443
}
3544

36-
void generic_xdp_lua_install_prog(const char *script)
45+
int generic_xdp_lua_install_prog(const char *script, size_t script_len)
3746
{
3847
int i;
3948

49+
if (!script || script_len == 0)
50+
return -EINVAL;
51+
52+
if (script_len > XDP_LUA_MAX_SCRIPT_LEN)
53+
return -ENAMETOOLONG;
54+
4055
for_each_possible_cpu(i) {
4156
struct xdp_lua_work *lw;
4257

4358
lw = per_cpu_ptr(&luaworks, i);
44-
strncpy(lw->script, script, XDP_LUA_MAX_SCRIPT_LEN);
59+
memcpy(lw->script, script, script_len);
60+
lw->script_len = script_len;
4561
schedule_work_on(i, &lw->work);
4662
}
4763

samples/bpf/xdplua_user.c

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,22 @@ static void usage(const char *prog) {
4141
prog);
4242
}
4343

44-
static char *extract_script(const char *path)
44+
static int try_strncpy(char *dest, const char *src, size_t n, const char *fmt) {
45+
int srclen = strnlen(src, n);
46+
47+
if (srclen == n) {
48+
int err = ENAMETOOLONG;
49+
fprintf(stderr, fmt, strerror(err));
50+
return -err;
51+
}
52+
53+
strncpy(dest, src, n);
54+
return srclen;
55+
}
56+
57+
static char *extract_script(const char *path, size_t *script_len)
4558
{
4659
FILE *f;
47-
long script_len;
4860
size_t read;
4961
char *script = NULL;
5062

@@ -55,25 +67,33 @@ static char *extract_script(const char *path)
5567
}
5668

5769
if (fseek(f, 0 , SEEK_END) < 0) {
58-
perror("unable to reach end of script file");
70+
perror("unable to reach end of file");
5971
goto out;
6072
}
61-
script_len = ftell(f);
62-
if (script_len < 0) {
63-
perror("error while attempting to get script length");
73+
74+
*script_len = (size_t) ftell(f);
75+
if (*script_len < 0) {
76+
perror("error while attempting to get file length");
6477
goto out;
6578
}
66-
rewind(f);
6779

68-
script = (char *) malloc(script_len + 1);
80+
fseek(f, 0, *script_len);
81+
82+
if (*script_len > XDP_LUA_MAX_SCRIPT_LEN)
83+
fprintf(stderr, "lua file can't have more than %d bytes\n",
84+
XDP_LUA_MAX_SCRIPT_LEN);
85+
86+
script = (char *) malloc(sizeof(char) * (*script_len));
6987
if (!script) {
7088
perror("failed to alloc lua script");
7189
goto out;
7290
}
73-
memset(script, 0, script_len + 1);
74-
read = fread(script, 1, script_len, f);
75-
if (read != script_len) {
76-
perror("unable to read lua file");
91+
92+
rewind(f);
93+
94+
read = fread(script, sizeof(char), *script_len, f);
95+
if (read != *script_len) {
96+
fprintf(stderr, "unable to read file %s\n", path);
7797
free(script);
7898
script = NULL;
7999
goto out;
@@ -95,11 +115,11 @@ static int do_attach_ebpf(int idx, int fd, const char *name)
95115
return err;
96116
}
97117

98-
static int do_attach_lua(const char *script)
118+
static int do_attach_lua(const char *script, size_t script_len)
99119
{
100120
int err;
101121

102-
err = bpf_set_link_xdp_lua_script(script);
122+
err = bpf_set_link_xdp_lua_script(script, script_len);
103123
if (err < 0)
104124
fprintf(stderr, "ERROR: failed to attach lua script %d\n", err);
105125

@@ -138,19 +158,23 @@ static void poll(int map_fd, int interval, int duration) {
138158
}
139159
}
140160

161+
#define strncpy_err(fmt, err) fprintf(stderr, fmt, strerr(-err))
162+
141163
int main(int argc, char *argv[])
142164
{
143165
struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
144166
char lua_filename[MAXFILENAMELEN];
145167
char filename[MAXFILENAMELEN];
146168
char script[XDP_LUA_MAX_SCRIPT_LEN];
169+
size_t script_len = 0;
147170
char ifname[IFNAMSIZ];
148171
struct bpf_object *obj;
149172
int opt, prog_fd;
150173
int rx_cnt_map_fd;
151174
int ifindex = 0;
152175
int detach = 0, attach_lua_file = 0, attach_ebpf = 0, monitor = 0,
153176
attach_lua_script = 0, interval = 1, duration = 1;
177+
int err = 0;
154178

155179
const char *optstr = "f:p:i:dms:I:D:";
156180
struct bpf_prog_load_attr prog_load_attr = {
@@ -163,28 +187,36 @@ int main(int argc, char *argv[])
163187
while ((opt = getopt(argc, argv, optstr)) != -1) {
164188
switch (opt) {
165189
case 'f':
166-
snprintf(lua_filename, sizeof(lua_filename), "%s", optarg);
190+
err = try_strncpy(lua_filename, optarg, MAXFILENAMELEN, "Invalid lua filename\nerr: %s\n");
191+
if (err < 0)
192+
return 1;
167193
attach_lua_file = 1;
168194
break;
169195
case 'p':
170-
snprintf(filename, sizeof(filename),
171-
"%s", optarg);
196+
err = try_strncpy(filename, optarg, MAXFILENAMELEN, "Invalid bpf prog filename\nerr: %s");
197+
if (err < 0)
198+
return 1;
172199
attach_ebpf = 1;
173200
break;
174201
case 'd':
175202
detach = 1;
176203
break;
177204
case 'i':
178-
snprintf(ifname, sizeof(ifname), "%s", optarg);
205+
script_len = try_strncpy(ifname, optarg, IFNAMSIZ, "Invalid interface name\nerr: %s");
206+
if (script_len < 0)
207+
return 1;
179208
ifindex = if_nametoindex(optarg);
180209
break;
181210
case 'm':
182211
monitor = 1;
183212
break;
184-
case 's':
185-
snprintf(script, sizeof(script), "%s", optarg);
213+
case 's': {
214+
err = try_strncpy(script, optarg, XDP_LUA_MAX_SCRIPT_LEN, "Invalid lua script\nerr: %s");
215+
if (err < 0)
216+
return 1;
186217
attach_lua_script = 1;
187218
break;
219+
}
188220
case 'I':
189221
interval = atoi(optarg);
190222
break;
@@ -197,7 +229,6 @@ int main(int argc, char *argv[])
197229
}
198230
}
199231

200-
201232
if (attach_ebpf || detach) {
202233
if (!ifindex) {
203234
printf("ERROR: invalid interface name");
@@ -234,20 +265,21 @@ int main(int argc, char *argv[])
234265
}
235266

236267
if (attach_lua_file) {
237-
char *extracted_script = extract_script(lua_filename);
268+
int ret = 0;
269+
size_t extracted_script_len;
270+
char *extracted_script = extract_script(lua_filename, &extracted_script_len);
238271
if (!extracted_script)
239272
return 1;
240273

241-
if (do_attach_lua(extracted_script) < 0) {
242-
free(extracted_script);
243-
return 1;
244-
}
274+
if (do_attach_lua(extracted_script, extracted_script_len) < 0)
275+
ret = 1;
245276

246277
free(extracted_script);
278+
return ret;
247279
}
248280

249281
if (attach_lua_script)
250-
if (do_attach_lua(script) < 0)
282+
if (do_attach_lua(script, script_len) < 0)
251283
return 1;
252284

253285
if (monitor) {

tools/lib/bpf/bpf.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -643,16 +643,16 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
643643
}
644644

645645
/* #ifdef CONFIG_XDPLUA */
646-
int bpf_set_link_xdp_lua_script(const char *script)
646+
int bpf_set_link_xdp_lua_script(const char *script, size_t script_len)
647647
{
648648
struct sockaddr_nl sa;
649649
int sock, seq = 0, len, ret = -1;
650650
char buf[4096];
651-
struct nlattr *nla, *nla_xdp;
651+
struct nlattr *nla, *nla_xdp_lua;
652652
struct {
653653
struct nlmsghdr nh;
654654
struct ifinfomsg ifinfo;
655-
char attrbuf[XDP_LUA_MAX_SCRIPT_LEN + 64];
655+
char attrbuf[XDP_LUA_MAX_SCRIPT_LEN];
656656
} req;
657657
struct nlmsghdr *nh;
658658
struct nlmsgerr *err;
@@ -703,24 +703,24 @@ int bpf_set_link_xdp_lua_script(const char *script)
703703
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
704704
nla->nla_len = NLA_HDRLEN;
705705

706-
/* add XDP LUA PROG */
707-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
708-
nla_xdp->nla_type = IFLA_XDP_LUA_PROG;
706+
/* add XDP LUA SCRIPT */
707+
nla_xdp_lua = (struct nlattr *)((char *)nla + nla->nla_len);
708+
nla_xdp_lua->nla_type = IFLA_XDP_LUA_PROG;
709709
if (script) {
710-
if (strlen(script) + 1 > XDP_LUA_MAX_SCRIPT_LEN) {
710+
if (script_len > XDP_LUA_MAX_SCRIPT_LEN) {
711711
fprintf(stderr, "script length cannot exceed %d bytes\n",
712712
XDP_LUA_MAX_SCRIPT_LEN);
713-
ret = -EINVAL;
713+
ret = -ENAMETOOLONG;
714714
goto cleanup;
715715
}
716716

717-
nla_xdp->nla_len = NLA_HDRLEN + strlen(script) + 1;
718-
memcpy((char *)nla_xdp + NLA_HDRLEN, script, strlen(script) + 1);
717+
nla_xdp_lua->nla_len = NLA_HDRLEN + script_len;
718+
memcpy((char *)nla_xdp_lua + NLA_HDRLEN, script, script_len);
719719
} else {
720720
ret = -EINVAL;
721721
goto cleanup;
722722
}
723-
nla->nla_len += nla_xdp->nla_len;
723+
nla->nla_len += nla_xdp_lua->nla_len;
724724

725725
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
726726

tools/lib/bpf/libbpf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type,
285285

286286
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
287287
/* #ifdef CONFIG_XDP_LUA */
288-
int bpf_set_link_xdp_lua_script(const char *script);
288+
int bpf_set_link_xdp_lua_script(const char *script, size_t script_len);
289289
/* #endif CONFIG_XDP_LUA */
290290

291291
enum bpf_perf_event_ret {

0 commit comments

Comments
 (0)