Commit 5748eb8f authored by Takashi Iwai's avatar Takashi Iwai Committed by David S. Miller

net: ppp: Don't call bpf_prog_create() in ppp_lock

In ppp_ioctl(), bpf_prog_create() is called inside ppp_lock, which
eventually calls vmalloc() and hits BUG_ON() in vmalloc.c.  This patch
works around the problem by moving the allocation outside the lock.

The bug was revealed by the recent change in net/core/filter.c, as it
allocates via vmalloc() instead of kmalloc() now.
Reported-and-tested-by: default avatarStefan Seyfried <stefan.seyfried@googlemail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f4a1edd5
...@@ -755,23 +755,23 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -755,23 +755,23 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
err = get_filter(argp, &code); err = get_filter(argp, &code);
if (err >= 0) { if (err >= 0) {
struct bpf_prog *pass_filter = NULL;
struct sock_fprog_kern fprog = { struct sock_fprog_kern fprog = {
.len = err, .len = err,
.filter = code, .filter = code,
}; };
err = 0;
if (fprog.filter)
err = bpf_prog_create(&pass_filter, &fprog);
if (!err) {
ppp_lock(ppp); ppp_lock(ppp);
if (ppp->pass_filter) { if (ppp->pass_filter)
bpf_prog_destroy(ppp->pass_filter); bpf_prog_destroy(ppp->pass_filter);
ppp->pass_filter = NULL; ppp->pass_filter = pass_filter;
ppp_unlock(ppp);
} }
if (fprog.filter != NULL)
err = bpf_prog_create(&ppp->pass_filter,
&fprog);
else
err = 0;
kfree(code); kfree(code);
ppp_unlock(ppp);
} }
break; break;
} }
...@@ -781,23 +781,23 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ...@@ -781,23 +781,23 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
err = get_filter(argp, &code); err = get_filter(argp, &code);
if (err >= 0) { if (err >= 0) {
struct bpf_prog *active_filter = NULL;
struct sock_fprog_kern fprog = { struct sock_fprog_kern fprog = {
.len = err, .len = err,
.filter = code, .filter = code,
}; };
err = 0;
if (fprog.filter)
err = bpf_prog_create(&active_filter, &fprog);
if (!err) {
ppp_lock(ppp); ppp_lock(ppp);
if (ppp->active_filter) { if (ppp->active_filter)
bpf_prog_destroy(ppp->active_filter); bpf_prog_destroy(ppp->active_filter);
ppp->active_filter = NULL; ppp->active_filter = active_filter;
ppp_unlock(ppp);
} }
if (fprog.filter != NULL)
err = bpf_prog_create(&ppp->active_filter,
&fprog);
else
err = 0;
kfree(code); kfree(code);
ppp_unlock(ppp);
} }
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment