3.17-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Takashi Iwai <ti...@suse.de>

[ Upstream commit 5748eb8f8e989a9da1ac7c96dc73d68cbdedf7df ]

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: Stefan Seyfried <stefan.seyfr...@googlemail.com>
Signed-off-by: Takashi Iwai <ti...@suse.de>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 drivers/net/ppp/ppp_generic.c |   40 ++++++++++++++++++++--------------------
 1 file changed, 20 insertions(+), 20 deletions(-)

--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -755,23 +755,23 @@ static long ppp_ioctl(struct file *file,
 
                err = get_filter(argp, &code);
                if (err >= 0) {
+                       struct bpf_prog *pass_filter = NULL;
                        struct sock_fprog_kern fprog = {
                                .len = err,
                                .filter = code,
                        };
 
-                       ppp_lock(ppp);
-                       if (ppp->pass_filter) {
-                               bpf_prog_destroy(ppp->pass_filter);
-                               ppp->pass_filter = NULL;
+                       err = 0;
+                       if (fprog.filter)
+                               err = bpf_prog_create(&pass_filter, &fprog);
+                       if (!err) {
+                               ppp_lock(ppp);
+                               if (ppp->pass_filter)
+                                       bpf_prog_destroy(ppp->pass_filter);
+                               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);
-                       ppp_unlock(ppp);
                }
                break;
        }
@@ -781,23 +781,23 @@ static long ppp_ioctl(struct file *file,
 
                err = get_filter(argp, &code);
                if (err >= 0) {
+                       struct bpf_prog *active_filter = NULL;
                        struct sock_fprog_kern fprog = {
                                .len = err,
                                .filter = code,
                        };
 
-                       ppp_lock(ppp);
-                       if (ppp->active_filter) {
-                               bpf_prog_destroy(ppp->active_filter);
-                               ppp->active_filter = NULL;
+                       err = 0;
+                       if (fprog.filter)
+                               err = bpf_prog_create(&active_filter, &fprog);
+                       if (!err) {
+                               ppp_lock(ppp);
+                               if (ppp->active_filter)
+                                       bpf_prog_destroy(ppp->active_filter);
+                               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);
-                       ppp_unlock(ppp);
                }
                break;
        }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to