From: Greg Kroah-Hartman Date: Tue, 28 May 2019 06:58:30 +0000 (+0200) Subject: 4.19-stable patches X-Git-Tag: v5.1.6~29 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=750b2d01350162cf90d1de99bec72bf9406c4b8c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.19-stable patches 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 --- 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 index 00000000000..f3266e02be0 --- /dev/null +++ b/queue-4.19/bpf-add-bpf_jit_limit-knob-to-restrict-unpriv-allocations.patch @@ -0,0 +1,200 @@ +From ede95a63b5e84ddeea6b0c473b36ab8bfd8c6ce3 Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Tue, 23 Oct 2018 01:11:04 +0200 +Subject: bpf: add bpf_jit_limit knob to restrict unpriv allocations + +From: Daniel Borkmann + +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 +Signed-off-by: Daniel Borkmann +Acked-by: Alexei Starovoitov +Cc: Eric Dumazet +Cc: Jann Horn +Cc: Kees Cook +Cc: LKML +Signed-off-by: Alexei Starovoitov +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..98adb4830f6 --- /dev/null +++ b/queue-4.19/brcmfmac-add-subtype-check-for-event-handling-in-data-path.patch @@ -0,0 +1,103 @@ +From a4176ec356c73a46c07c181c6d04039fafa34a9f Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:48 +0100 +Subject: brcmfmac: add subtype check for event handling in data path + +From: Arend van Spriel + +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + 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 index 00000000000..78258476cc4 --- /dev/null +++ b/queue-4.19/brcmfmac-assure-ssid-length-from-firmware-is-limited.patch @@ -0,0 +1,35 @@ +From 1b5e2423164b3670e8bc9174e4762d297990deff Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:47 +0100 +Subject: brcmfmac: assure SSID length from firmware is limited + +From: Arend van Spriel + +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 +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Cc: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman + +--- + 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; diff --git a/queue-4.19/series b/queue-4.19/series index 277b42398a2..8ddb91089ea 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -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