]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 May 2019 06:58:30 +0000 (08:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 28 May 2019 06:58:30 +0000 (08:58 +0200)
added patches:
bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch
brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch
brcmfmac-assure-ssid-length-from-firmware-is-limited.patch

queue-4.19/bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch [new file with mode: 0644]
queue-4.19/brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch [new file with mode: 0644]
queue-4.19/brcmfmac-assure-ssid-length-from-firmware-is-limited.patch [new file with mode: 0644]
queue-4.19/series

diff --git a/queue-4.19/bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch b/queue-4.19/bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch
new file mode 100644 (file)
index 0000000..f3266e0
--- /dev/null
@@ -0,0 +1,200 @@
+From ede95a63b5e84ddeea6b0c473b36ab8bfd8c6ce3 Mon Sep 17 00:00:00 2001
+From: Daniel Borkmann <daniel@iogearbox.net>
+Date: Tue, 23 Oct 2018 01:11:04 +0200
+Subject: bpf: add bpf_jit_limit knob to restrict unpriv allocations
+
+From: Daniel Borkmann <daniel@iogearbox.net>
+
+commit ede95a63b5e84ddeea6b0c473b36ab8bfd8c6ce3 upstream.
+
+Rick reported that the BPF JIT could potentially fill the entire module
+space with BPF programs from unprivileged users which would prevent later
+attempts to load normal kernel modules or privileged BPF programs, for
+example. If JIT was enabled but unsuccessful to generate the image, then
+before commit 290af86629b2 ("bpf: introduce BPF_JIT_ALWAYS_ON config")
+we would always fall back to the BPF interpreter. Nowadays in the case
+where the CONFIG_BPF_JIT_ALWAYS_ON could be set, then the load will abort
+with a failure since the BPF interpreter was compiled out.
+
+Add a global limit and enforce it for unprivileged users such that in case
+of BPF interpreter compiled out we fail once the limit has been reached
+or we fall back to BPF interpreter earlier w/o using module mem if latter
+was compiled in. In a next step, fair share among unprivileged users can
+be resolved in particular for the case where we would fail hard once limit
+is reached.
+
+Fixes: 290af86629b2 ("bpf: introduce BPF_JIT_ALWAYS_ON config")
+Fixes: 0a14842f5a3c ("net: filter: Just In Time compiler for x86-64")
+Co-Developed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
+Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
+Acked-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Cc: Jann Horn <jannh@google.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: LKML <linux-kernel@vger.kernel.org>
+Signed-off-by: Alexei Starovoitov <ast@kernel.org>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ Documentation/sysctl/net.txt |    8 +++++++
+ include/linux/filter.h       |    1 
+ kernel/bpf/core.c            |   49 ++++++++++++++++++++++++++++++++++++++++---
+ net/core/sysctl_net_core.c   |   10 +++++++-
+ 4 files changed, 63 insertions(+), 5 deletions(-)
+
+--- a/Documentation/sysctl/net.txt
++++ b/Documentation/sysctl/net.txt
+@@ -92,6 +92,14 @@ Values :
+       0 - disable JIT kallsyms export (default value)
+       1 - enable JIT kallsyms export for privileged users only
++bpf_jit_limit
++-------------
++
++This enforces a global limit for memory allocations to the BPF JIT
++compiler in order to reject unprivileged JIT requests once it has
++been surpassed. bpf_jit_limit contains the value of the global limit
++in bytes.
++
+ dev_weight
+ --------------
+--- a/include/linux/filter.h
++++ b/include/linux/filter.h
+@@ -836,6 +836,7 @@ bpf_run_sk_reuseport(struct sock_reusepo
+ extern int bpf_jit_enable;
+ extern int bpf_jit_harden;
+ extern int bpf_jit_kallsyms;
++extern int bpf_jit_limit;
+ typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
+--- a/kernel/bpf/core.c
++++ b/kernel/bpf/core.c
+@@ -366,10 +366,13 @@ void bpf_prog_kallsyms_del_all(struct bp
+ }
+ #ifdef CONFIG_BPF_JIT
++# define BPF_JIT_LIMIT_DEFAULT        (PAGE_SIZE * 40000)
++
+ /* All BPF JIT sysctl knobs here. */
+ int bpf_jit_enable   __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_ALWAYS_ON);
+ int bpf_jit_harden   __read_mostly;
+ int bpf_jit_kallsyms __read_mostly;
++int bpf_jit_limit    __read_mostly = BPF_JIT_LIMIT_DEFAULT;
+ static __always_inline void
+ bpf_get_prog_addr_region(const struct bpf_prog *prog,
+@@ -578,27 +581,64 @@ int bpf_get_kallsym(unsigned int symnum,
+       return ret;
+ }
++static atomic_long_t bpf_jit_current;
++
++#if defined(MODULES_VADDR)
++static int __init bpf_jit_charge_init(void)
++{
++      /* Only used as heuristic here to derive limit. */
++      bpf_jit_limit = min_t(u64, round_up((MODULES_END - MODULES_VADDR) >> 2,
++                                          PAGE_SIZE), INT_MAX);
++      return 0;
++}
++pure_initcall(bpf_jit_charge_init);
++#endif
++
++static int bpf_jit_charge_modmem(u32 pages)
++{
++      if (atomic_long_add_return(pages, &bpf_jit_current) >
++          (bpf_jit_limit >> PAGE_SHIFT)) {
++              if (!capable(CAP_SYS_ADMIN)) {
++                      atomic_long_sub(pages, &bpf_jit_current);
++                      return -EPERM;
++              }
++      }
++
++      return 0;
++}
++
++static void bpf_jit_uncharge_modmem(u32 pages)
++{
++      atomic_long_sub(pages, &bpf_jit_current);
++}
++
+ struct bpf_binary_header *
+ bpf_jit_binary_alloc(unsigned int proglen, u8 **image_ptr,
+                    unsigned int alignment,
+                    bpf_jit_fill_hole_t bpf_fill_ill_insns)
+ {
+       struct bpf_binary_header *hdr;
+-      unsigned int size, hole, start;
++      u32 size, hole, start, pages;
+       /* Most of BPF filters are really small, but if some of them
+        * fill a page, allow at least 128 extra bytes to insert a
+        * random section of illegal instructions.
+        */
+       size = round_up(proglen + sizeof(*hdr) + 128, PAGE_SIZE);
++      pages = size / PAGE_SIZE;
++
++      if (bpf_jit_charge_modmem(pages))
++              return NULL;
+       hdr = module_alloc(size);
+-      if (hdr == NULL)
++      if (!hdr) {
++              bpf_jit_uncharge_modmem(pages);
+               return NULL;
++      }
+       /* Fill space with illegal/arch-dep instructions. */
+       bpf_fill_ill_insns(hdr, size);
+-      hdr->pages = size / PAGE_SIZE;
++      hdr->pages = pages;
+       hole = min_t(unsigned int, size - (proglen + sizeof(*hdr)),
+                    PAGE_SIZE - sizeof(*hdr));
+       start = (get_random_int() % hole) & ~(alignment - 1);
+@@ -611,7 +651,10 @@ bpf_jit_binary_alloc(unsigned int progle
+ void bpf_jit_binary_free(struct bpf_binary_header *hdr)
+ {
++      u32 pages = hdr->pages;
++
+       module_memfree(hdr);
++      bpf_jit_uncharge_modmem(pages);
+ }
+ /* This symbol is only overridden by archs that have different
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -279,7 +279,6 @@ static int proc_dointvec_minmax_bpf_enab
+       return ret;
+ }
+-# ifdef CONFIG_HAVE_EBPF_JIT
+ static int
+ proc_dointvec_minmax_bpf_restricted(struct ctl_table *table, int write,
+                                   void __user *buffer, size_t *lenp,
+@@ -290,7 +289,6 @@ proc_dointvec_minmax_bpf_restricted(stru
+       return proc_dointvec_minmax(table, write, buffer, lenp, ppos);
+ }
+-# endif
+ #endif
+ static struct ctl_table net_core_table[] = {
+@@ -397,6 +395,14 @@ static struct ctl_table net_core_table[]
+               .extra2         = &one,
+       },
+ # endif
++      {
++              .procname       = "bpf_jit_limit",
++              .data           = &bpf_jit_limit,
++              .maxlen         = sizeof(int),
++              .mode           = 0600,
++              .proc_handler   = proc_dointvec_minmax_bpf_restricted,
++              .extra1         = &one,
++      },
+ #endif
+       {
+               .procname       = "netdev_tstamp_prequeue",
diff --git a/queue-4.19/brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch b/queue-4.19/brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch
new file mode 100644 (file)
index 0000000..98adb48
--- /dev/null
@@ -0,0 +1,103 @@
+From a4176ec356c73a46c07c181c6d04039fafa34a9f Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 14 Feb 2019 13:43:48 +0100
+Subject: brcmfmac: add subtype check for event handling in data path
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+commit a4176ec356c73a46c07c181c6d04039fafa34a9f upstream.
+
+For USB there is no separate channel being used to pass events
+from firmware to the host driver and as such are passed over the
+data path. In order to detect mock event messages an additional
+check is needed on event subtype. This check is added conditionally
+using unlikely() keyword.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c   |    5 ++--
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h   |   16 ++++++++++----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c |    2 -
+ 3 files changed, 16 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -464,7 +464,8 @@ void brcmf_rx_frame(struct device *dev,
+       } else {
+               /* Process special event packets */
+               if (handle_event)
+-                      brcmf_fweh_process_skb(ifp->drvr, skb);
++                      brcmf_fweh_process_skb(ifp->drvr, skb,
++                                             BCMILCP_SUBTYPE_VENDOR_LONG);
+               brcmf_netif_rx(ifp, skb);
+       }
+@@ -481,7 +482,7 @@ void brcmf_rx_event(struct device *dev,
+       if (brcmf_rx_hdrpull(drvr, skb, &ifp))
+               return;
+-      brcmf_fweh_process_skb(ifp->drvr, skb);
++      brcmf_fweh_process_skb(ifp->drvr, skb, 0);
+       brcmu_pkt_buf_free_skb(skb);
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h
+@@ -211,7 +211,7 @@ enum brcmf_fweh_event_code {
+  */
+ #define BRCM_OUI                              "\x00\x10\x18"
+ #define BCMILCP_BCM_SUBTYPE_EVENT             1
+-
++#define BCMILCP_SUBTYPE_VENDOR_LONG           32769
+ /**
+  * struct brcm_ethhdr - broadcom specific ether header.
+@@ -334,10 +334,10 @@ void brcmf_fweh_process_event(struct brc
+ void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
+ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
+-                                        struct sk_buff *skb)
++                                        struct sk_buff *skb, u16 stype)
+ {
+       struct brcmf_event *event_packet;
+-      u16 usr_stype;
++      u16 subtype, usr_stype;
+       /* only process events when protocol matches */
+       if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL))
+@@ -346,8 +346,16 @@ static inline void brcmf_fweh_process_sk
+       if ((skb->len + ETH_HLEN) < sizeof(*event_packet))
+               return;
+-      /* check for BRCM oui match */
+       event_packet = (struct brcmf_event *)skb_mac_header(skb);
++
++      /* check subtype if needed */
++      if (unlikely(stype)) {
++              subtype = get_unaligned_be16(&event_packet->hdr.subtype);
++              if (subtype != stype)
++                      return;
++      }
++
++      /* check for BRCM oui match */
+       if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0],
+                  sizeof(event_packet->hdr.oui)))
+               return;
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+@@ -1116,7 +1116,7 @@ static void brcmf_msgbuf_process_event(s
+       skb->protocol = eth_type_trans(skb, ifp->ndev);
+-      brcmf_fweh_process_skb(ifp->drvr, skb);
++      brcmf_fweh_process_skb(ifp->drvr, skb, 0);
+ exit:
+       brcmu_pkt_buf_free_skb(skb);
diff --git a/queue-4.19/brcmfmac-assure-ssid-length-from-firmware-is-limited.patch b/queue-4.19/brcmfmac-assure-ssid-length-from-firmware-is-limited.patch
new file mode 100644 (file)
index 0000000..7825847
--- /dev/null
@@ -0,0 +1,35 @@
+From 1b5e2423164b3670e8bc9174e4762d297990deff Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Thu, 14 Feb 2019 13:43:47 +0100
+Subject: brcmfmac: assure SSID length from firmware is limited
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+commit 1b5e2423164b3670e8bc9174e4762d297990deff upstream.
+
+The SSID length as received from firmware should not exceed
+IEEE80211_MAX_SSID_LEN as that would result in heap overflow.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Cc: Ben Hutchings <ben.hutchings@codethink.co.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3466,6 +3466,8 @@ brcmf_wowl_nd_results(struct brcmf_if *i
+       }
+       netinfo = brcmf_get_netinfo_array(pfn_result);
++      if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
++              netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
+       memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
+       cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
+       cfg->wowl.nd->n_channels = 1;
index 277b42398a2d014ee22a5d777254ca3848226bea..8ddb91089eabd5fe5532057759f230c92422db57 100644 (file)
@@ -24,3 +24,6 @@ udlfb-fix-some-inconsistent-null-checking.patch
 fbdev-fix-divide-error-in-fb_var_to_videomode.patch
 nfsv4.2-fix-unnecessary-retry-in-nfs4_copy_file_range.patch
 nfsv4.1-fix-incorrect-return-value-in-copy_file_range.patch
+bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch
+brcmfmac-assure-ssid-length-from-firmware-is-limited.patch
+brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch