[PATCH] ipv6: Fix idev->addr_list corruption
From: Rabin Vincent <rab...@axis.com> addrconf_ifdown() removes elements from the idev->addr_list without holding the idev->lock. If this happens while the loop in __ipv6_dev_get_saddr() is handling the same element, that function ends up in an infinite loop: NMI watchdog: BUG: soft lockup - CPU#1 stuck for 23s! [test:1719] Call Trace: ipv6_get_saddr_eval+0x13c/0x3a0 __ipv6_dev_get_saddr+0xe4/0x1f0 ipv6_dev_get_saddr+0x1b4/0x204 ip6_dst_lookup_tail+0xcc/0x27c ip6_dst_lookup_flow+0x38/0x80 udpv6_sendmsg+0x708/0xba8 sock_sendmsg+0x18/0x30 SyS_sendto+0xb8/0xf8 syscall_common+0x34/0x58 Fixes: 6a923934c33 (Revert "ipv6: Revert optional address flusing on ifdown.") Signed-off-by: Rabin Vincent <rab...@axis.com> --- net/ipv6/addrconf.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 3631725..80ce478 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3626,14 +3626,19 @@ static int addrconf_ifdown(struct net_device *dev, int how) INIT_LIST_HEAD(_list); list_for_each_entry_safe(ifa, tmp, >addr_list, if_list) { struct rt6_info *rt = NULL; + bool keep; addrconf_del_dad_work(ifa); + keep = keep_addr && (ifa->flags & IFA_F_PERMANENT) && + !addr_is_local(>addr); + if (!keep) + list_move(>if_list, _list); + write_unlock_bh(>lock); spin_lock_bh(>lock); - if (keep_addr && (ifa->flags & IFA_F_PERMANENT) && - !addr_is_local(>addr)) { + if (keep) { /* set state to skip the notifier below */ state = INET6_IFADDR_STATE_DEAD; ifa->state = 0; @@ -3645,8 +3650,6 @@ static int addrconf_ifdown(struct net_device *dev, int how) } else { state = ifa->state; ifa->state = INET6_IFADDR_STATE_DEAD; - - list_move(>if_list, _list); } spin_unlock_bh(>lock); -- 2.7.0
Re: Synopsys Ethernet QoS Driver
On Fri, Nov 18, 2016 at 02:20:27PM +, Joao Pinto wrote: > For now we are interesting in improving the synopsys QoS driver under > /nect/ethernet/synopsys. For now the driver structure consists of a single > file > called dwc_eth_qos.c, containing synopsys ethernet qos common ops and platform > related stuff. > > Our strategy would be: > > a) Implement a platform glue driver (dwc_eth_qos_pltfm.c) > b) Implement a pci glue driver (dwc_eth_qos_pci.c) > c) Implement a "core driver" (dwc_eth_qos.c) that would only have Ethernet QoS > related stuff to be reused by the platform / pci drivers > d) Add a set of features to the "core driver" that we have available > internally Note that there are actually two drivers in mainline for this hardware: drivers/net/ethernet/synopsis/ drivers/net/ethernet/stmicro/stmmac/ (See http://lists.openwall.net/netdev/2016/02/29/127) The former only supports 4.x of the hardware. The later supports 4.x and 3.x and already has a platform glue driver with support for several platforms, a PCI glue driver, and a core driver with several features not present in the former (for example: TX/RX interrupt coalescing, EEE, PTP). Have you evaluated both drivers? Why have you decided to work on the former rather than the latter?
[PATCHv3] phy: fix crash in fixed_phy_add()
From: Rabin Vincent <rab...@axis.com> Since e7f4dc3536a ("mdio: Move allocation of interrupts into core"), platforms which call fixed_phy_add() before fixed_mdio_bus_init() is called (for example, because the platform code and the fixed_phy driver use the same initcall level) crash in fixed_phy_add() since the ->mii_bus is not allocated. Also since e7f4dc3536a, these interrupts are initalized to polling by default. The few (old) platforms which directly use fixed_phy_add() from their platform code all pass PHY_POLL for the irq argument, so we can keep these platforms not crashing by simply not attempting to set the irq if PHY_POLL is passed. Also, even if problems have not been reported on more modern platforms which used fixed_phy_register() from drivers' probe functions, we return -EPROBE_DEFER if the MDIO bus is not yet registered so that the probe is retried later. Fixes: e7f4dc3536a400 ("mdio: Move allocation of interrupts into core") Signed-off-by: Rabin Vincent <rab...@axis.com> --- v3: One more suggestion from Andrew: check mii bus state drivers/net/phy/fixed_phy.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index fc07a88..e7dcda6 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c @@ -255,7 +255,8 @@ int fixed_phy_add(unsigned int irq, int phy_addr, memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); - fmb->mii_bus->irq[phy_addr] = irq; + if (irq != PHY_POLL) + fmb->mii_bus->irq[phy_addr] = irq; fp->addr = phy_addr; fp->status = *status; @@ -314,6 +315,9 @@ struct phy_device *fixed_phy_register(unsigned int irq, int phy_addr; int ret; + if (!fmb->mii_bus || fmb->mii_bus->state != MDIOBUS_REGISTERED) + return ERR_PTR(-EPROBE_DEFER); + /* Get the next available PHY address, up to PHY_MAX_ADDR */ spin_lock(_fixed_addr_lock); if (phy_fixed_addr == PHY_MAX_ADDR) { -- 2.1.4
[PATCHv2] phy: fix crash in fixed_phy_add()
From: Rabin Vincent <rab...@axis.com> Since e7f4dc3536a ("mdio: Move allocation of interrupts into core"), platforms which call fixed_phy_add() before fixed_mdio_bus_init() is called (for example, because the platform code and the fixed_phy driver use the same initcall level) crash in fixed_phy_add() since the ->mii_bus is not allocated. Also since e7f4dc3536a, these interrupts are initalized to polling by default. The few (old) platforms which directly use fixed_phy_add() from their platform code all pass PHY_POLL for the irq argument, so we can keep these platforms not crashing by simply not attempting to set the irq if PHY_POLL is passed. Also, even if problems have not been reported on more modern platforms which used fixed_phy_register() from drivers' probe functions, we return -EPROBE_DEFER if the MDIO bus is not yet registered so that the probe is retried later. Fixes: e7f4dc3536a400 ("mdio: Move allocation of interrupts into core") Signed-off-by: Rabin Vincent <rab...@axis.com> --- v2: rewrite according to Andrew's suggestions drivers/net/phy/fixed_phy.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index fc07a88..d9dc1f5 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c @@ -255,7 +255,8 @@ int fixed_phy_add(unsigned int irq, int phy_addr, memset(fp->regs, 0xFF, sizeof(fp->regs[0]) * MII_REGS_NUM); - fmb->mii_bus->irq[phy_addr] = irq; + if (irq != PHY_POLL) + fmb->mii_bus->irq[phy_addr] = irq; fp->addr = phy_addr; fp->status = *status; @@ -314,6 +315,9 @@ struct phy_device *fixed_phy_register(unsigned int irq, int phy_addr; int ret; + if (!fmb->mii_bus) + return ERR_PTR(-EPROBE_DEFER); + /* Get the next available PHY address, up to PHY_MAX_ADDR */ spin_lock(_fixed_addr_lock); if (phy_fixed_addr == PHY_MAX_ADDR) { -- 2.1.4
Re: [PATCH] phy: remove irq param to fix crash in fixed_phy_add()
On Mon, May 16, 2016 at 02:29:03PM +0200, Andrew Lunn wrote: > What i think is better is to make fixed_phy_add() return -EPROBE_DEFER > if it is called before fixed_mdio_bus_init(). I don't see how this will work for platforms such as ar7 and bcm47xx which call fixed_phy_add() from platform code. There is no probe to retry there so while the EPROBE_DEFER will certainly fix the crash it will also leave the platforms without a phy.
[PATCH] phy: remove irq param to fix crash in fixed_phy_add()
From: Rabin Vincent <rab...@axis.com> Since e7f4dc3536a ("mdio: Move allocation of interrupts into core"), platforms which call fixed_phy_add() before fixed_mdio_bus_init() is called (for example, because the platform code and the fixed_phy driver use the same initcall level) crash in fixed_phy_add() since the ->mii_bus is not allocated. Also since e7f4dc3536a, these interrupts are initalized to polling by default. All callers of both fixed_phy_register() and fixed_phy_add() pass PHY_POLL for the irq argument, so we can fix these crashes by simply removing the irq parameter, since the default is correct for all users. Fixes: e7f4dc3536a400 ("mdio: Move allocation of interrupts into core") Signed-off-by: Rabin Vincent <rab...@axis.com> --- arch/m68k/coldfire/m5272.c | 2 +- arch/mips/ar7/platform.c | 5 ++--- arch/mips/bcm47xx/setup.c| 2 +- drivers/net/ethernet/broadcom/bgmac.c| 2 +- drivers/net/ethernet/broadcom/genet/bcmmii.c | 2 +- drivers/net/phy/fixed_phy.c | 10 +++--- drivers/of/of_mdio.c | 6 +++--- include/linux/phy_fixed.h| 16 ++-- 8 files changed, 18 insertions(+), 27 deletions(-) diff --git a/arch/m68k/coldfire/m5272.c b/arch/m68k/coldfire/m5272.c index c525e4c..217e2e0 100644 --- a/arch/m68k/coldfire/m5272.c +++ b/arch/m68k/coldfire/m5272.c @@ -126,7 +126,7 @@ static struct fixed_phy_status nettel_fixed_phy_status __initdata = { static int __init init_BSP(void) { m5272_uarts_init(); - fixed_phy_add(PHY_POLL, 0, _fixed_phy_status, -1); + fixed_phy_add(0, _fixed_phy_status, -1); return 0; } diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c index 58fca9a..0a024b0 100644 --- a/arch/mips/ar7/platform.c +++ b/arch/mips/ar7/platform.c @@ -678,8 +678,7 @@ static int __init ar7_register_devices(void) } if (ar7_has_high_cpmac()) { - res = fixed_phy_add(PHY_POLL, cpmac_high.id, - _phy_status, -1); + res = fixed_phy_add(cpmac_high.id, _phy_status, -1); if (!res) { cpmac_get_mac(1, cpmac_high_data.dev_addr); @@ -692,7 +691,7 @@ static int __init ar7_register_devices(void) } else cpmac_low_data.phy_mask = 0x; - res = fixed_phy_add(PHY_POLL, cpmac_low.id, _phy_status, -1); + res = fixed_phy_add(cpmac_low.id, _phy_status, -1); if (!res) { cpmac_get_mac(0, cpmac_low_data.dev_addr); res = platform_device_register(_low); diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index c807e32..ca3fbd1 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c @@ -243,7 +243,7 @@ static int __init bcm47xx_register_bus_complete(void) bcm47xx_leds_register(); bcm47xx_workarounds(); - fixed_phy_add(PHY_POLL, 0, _fixed_phy_status, -1); + fixed_phy_add(0, _fixed_phy_status, -1); return 0; } device_initcall(bcm47xx_register_bus_complete); diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 38db2e4..0c8f467 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1460,7 +1460,7 @@ static int bgmac_fixed_phy_register(struct bgmac *bgmac) struct phy_device *phy_dev; int err; - phy_dev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + phy_dev = fixed_phy_register(_status, -1, NULL); if (!phy_dev || IS_ERR(phy_dev)) { bgmac_err(bgmac, "Failed to register fixed PHY device\n"); return -ENODEV; diff --git a/drivers/net/ethernet/broadcom/genet/bcmmii.c b/drivers/net/ethernet/broadcom/genet/bcmmii.c index 457c3bc..f181fd1 100644 --- a/drivers/net/ethernet/broadcom/genet/bcmmii.c +++ b/drivers/net/ethernet/broadcom/genet/bcmmii.c @@ -595,7 +595,7 @@ static int bcmgenet_mii_pd_init(struct bcmgenet_priv *priv) .asym_pause = 0, }; - phydev = fixed_phy_register(PHY_POLL, _status, -1, NULL); + phydev = fixed_phy_register(_status, -1, NULL); if (!phydev || IS_ERR(phydev)) { dev_err(kdev, "failed to register fixed PHY device\n"); return -ENODEV; diff --git a/drivers/net/phy/fixed_phy.c b/drivers/net/phy/fixed_phy.c index fc07a88..295e6bd 100644 --- a/drivers/net/phy/fixed_phy.c +++ b/drivers/net/phy/fixed_phy.c @@ -241,8 +241,7 @@ int fixed_phy_update_state(struct phy_device *phydev, } EXPORT_SYMBOL(fixed_phy_update_state); -int fixed_phy_add(unsigned int irq, int phy_addr, - struct fixed_phy_status *status, +int fixed_phy_add(int phy_addr, struct fixed_phy_status *status, int
[PATCH] dwc_eth_qos: Reset hardware before PHY start
From: Rabin Vincent <rab...@axis.com> The hardware reset is currently done after phy_start() is called, leading to a race where we can lose the link status if the phy state machine calls dwceqos_adjust_link() before we reset the MAC registers. Acked-by: Lars Persson <lar...@axis.com> Signed-off-by: Rabin Vincent <rab...@axis.com> --- drivers/net/ethernet/synopsys/dwc_eth_qos.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/ethernet/synopsys/dwc_eth_qos.c b/drivers/net/ethernet/synopsys/dwc_eth_qos.c index 70814b7..fc8bbff 100644 --- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c +++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c @@ -1880,9 +1880,9 @@ static int dwceqos_open(struct net_device *ndev) } netdev_reset_queue(ndev); + dwceqos_init_hw(lp); napi_enable(>napi); phy_start(lp->phy_dev); - dwceqos_init_hw(lp); netif_start_queue(ndev); tasklet_enable(>tx_bdreclaim_tasklet); -- 2.7.0
Re: [PATCH] arm64: net: bpf: don't BUG() on large shifts
On Tue, Jan 05, 2016 at 09:55:58AM -0800, Alexei Starovoitov wrote: > this one is better to be addressed in verifier instead of eBPF JITs. > Please reject it in check_alu_op() instead. AFAICS the eBPF verifier is not called on the eBPF filters generated by the BPF->eBPF conversion in net/core/filter.c, so performing this check only in check_alu_op() will be insufficient. So I think we'd need to add this check to bpf_check_classic() too. Or am I missing something? -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] net: filter: make JITs zero A for SKF_AD_ALU_XOR_X
The SKF_AD_ALU_XOR_X ancillary is not like the other ancillary data instructions since it XORs A with X while all the others replace A with some loaded value. All the BPF JITs fail to clear A if this is used as the first instruction in a filter. This was found using american fuzzy lop. Add a helper to determine if A needs to be cleared given the first instruction in a filter, and use this in the JITs. Except for ARM, the rest have only been compile-tested. Fixes: 3480593131e0 ("net: filter: get rid of BPF_S_* enum") Signed-off-by: Rabin Vincent <ra...@rab.in> --- arch/arm/net/bpf_jit_32.c | 16 +--- arch/mips/net/bpf_jit.c | 16 +--- arch/powerpc/net/bpf_jit_comp.c | 13 ++--- arch/sparc/net/bpf_jit_comp.c | 17 ++--- include/linux/filter.h | 19 +++ 5 files changed, 25 insertions(+), 56 deletions(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index 591f9db3bf40..e153eb065fe4 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -187,19 +187,6 @@ static inline int mem_words_used(struct jit_ctx *ctx) return fls(ctx->seen & SEEN_MEM); } -static inline bool is_load_to_a(u16 inst) -{ - switch (inst) { - case BPF_LD | BPF_W | BPF_LEN: - case BPF_LD | BPF_W | BPF_ABS: - case BPF_LD | BPF_H | BPF_ABS: - case BPF_LD | BPF_B | BPF_ABS: - return true; - default: - return false; - } -} - static void jit_fill_hole(void *area, unsigned int size) { u32 *ptr; @@ -211,7 +198,6 @@ static void jit_fill_hole(void *area, unsigned int size) static void build_prologue(struct jit_ctx *ctx) { u16 reg_set = saved_regs(ctx); - u16 first_inst = ctx->skf->insns[0].code; u16 off; #ifdef CONFIG_FRAME_POINTER @@ -241,7 +227,7 @@ static void build_prologue(struct jit_ctx *ctx) emit(ARM_MOV_I(r_X, 0), ctx); /* do not leak kernel data to userspace */ - if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) + if (bpf_needs_clear_a(>skf->insns[0])) emit(ARM_MOV_I(r_A, 0), ctx); /* stack space for the BPF_MEM words */ diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c index 77cb27309db2..1a8c96035716 100644 --- a/arch/mips/net/bpf_jit.c +++ b/arch/mips/net/bpf_jit.c @@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num) return num; } -static bool is_load_to_a(u16 inst) -{ - switch (inst) { - case BPF_LD | BPF_W | BPF_LEN: - case BPF_LD | BPF_W | BPF_ABS: - case BPF_LD | BPF_H | BPF_ABS: - case BPF_LD | BPF_B | BPF_ABS: - return true; - default: - return false; - } -} - static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) { int i = 0, real_off = 0; @@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx) static void build_prologue(struct jit_ctx *ctx) { - u16 first_inst = ctx->skf->insns[0].code; int sp_off; /* Calculate the total offset for the stack pointer */ @@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx) emit_jit_reg_move(r_X, r_zero, ctx); /* Do not leak kernel data to userspace */ - if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) + if (bpf_needs_clear_a(>skf->insns[0])) emit_jit_reg_move(r_A, r_zero, ctx); } diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 04782164ee67..2d66a8446198 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c @@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image, PPC_LI(r_X, 0); } - switch (filter[0].code) { - case BPF_RET | BPF_K: - case BPF_LD | BPF_W | BPF_LEN: - case BPF_LD | BPF_W | BPF_ABS: - case BPF_LD | BPF_H | BPF_ABS: - case BPF_LD | BPF_B | BPF_ABS: - /* first instruction sets A register (or is RET 'constant') */ - break; - default: - /* make sure we dont leak kernel information to user */ + /* make sure we dont leak kernel information to user */ + if (bpf_needs_clear_a([0])) PPC_LI(r_A, 0); - } } static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c index 22564f5f2364..3e6e05a7c4c2 100644 --- a/arch/sparc/net/bpf_jit_comp.c +++ b/arch/sparc/net/bpf_jit_comp.c @@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp) } emit_reg_move(O7, r_saved_O7); - switch (filter[0].code) { - case BPF_RET | BPF_K: - case BPF_LD |
[PATCH] ARM: net: bpf: fix zero right shift
The LSR instruction cannot be used to perform a zero right shift since a 0 as the immediate value (imm5) in the LSR instruction encoding means that a shift of 32 is perfomed. See DecodeIMMShift() in the ARM ARM. Make the JIT skip generation of the LSR if a zero-shift is requested. This was found using american fuzzy lop. Signed-off-by: Rabin Vincent <ra...@rab.in> --- arch/arm/net/bpf_jit_32.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c index e153eb065fe4..93d0b6d0b63e 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -756,7 +756,8 @@ load_ind: case BPF_ALU | BPF_RSH | BPF_K: if (unlikely(k > 31)) return -1; - emit(ARM_LSR_I(r_A, r_A, k), ctx); + if (k) + emit(ARM_LSR_I(r_A, r_A, k), ctx); break; case BPF_ALU | BPF_RSH | BPF_X: update_on_xread(ctx); -- 2.6.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] arm64: net: bpf: don't BUG() on large shifts
Attempting to generate UBFM/SBFM instructions with shifts that can't be encoded in the immediate fields of the opcodes leads to a trigger of a BUG() in the instruction generation code. As the ARMv8 ARM says: "The shift amounts must be in the range 0 to one less than the register width of the instruction, inclusive." Make the JIT reject unencodable shifts instead of crashing. [ cut here ] kernel BUG at arch/arm64/kernel/insn.c:766! Internal error: Oops - BUG: 0 [#1] PREEMPT SMP CPU: 0 PID: 669 Comm: insmod Not tainted 4.4.0-rc8+ #4 PC is at aarch64_insn_gen_bitfield+0xcc/0xd4 LR is at build_body+0x1000/0x2914 .. Call trace: [] aarch64_insn_gen_bitfield+0xcc/0xd4 [] build_body+0x1000/0x2914 [] bpf_int_jit_compile+0x7c/0x1b4 [] bpf_prog_select_runtime+0x20/0xcc [] bpf_prepare_filter+0x3d8/0x3e8 [] bpf_prog_create+0x74/0xa4 [] test_bpf_init+0x1d4/0x748 [test_bpf] [] do_one_initcall+0x90/0x1a8 [] do_init_module+0x60/0x1c8 [] load_module+0x1554/0x1c98 [] SyS_init_module+0x11c/0x140 [] el0_svc_naked+0x24/0x28 Signed-off-by: Rabin Vincent <ra...@rab.in> --- arch/arm64/net/bpf_jit_comp.c | 7 +++ 1 file changed, 7 insertions(+) diff --git a/arch/arm64/net/bpf_jit_comp.c b/arch/arm64/net/bpf_jit_comp.c index b162ad70effc..3f4f089a85c0 100644 --- a/arch/arm64/net/bpf_jit_comp.c +++ b/arch/arm64/net/bpf_jit_comp.c @@ -255,6 +255,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx) const s32 imm = insn->imm; const int i = insn - ctx->prog->insnsi; const bool is64 = BPF_CLASS(code) == BPF_ALU64; + const int bits = is64 ? 64 : 32; u8 jmp_cond; s32 jmp_offset; @@ -444,14 +445,20 @@ emit_bswap_uxt: break; case BPF_ALU | BPF_LSH | BPF_K: case BPF_ALU64 | BPF_LSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_LSL(is64, dst, dst, imm), ctx); break; case BPF_ALU | BPF_RSH | BPF_K: case BPF_ALU64 | BPF_RSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_LSR(is64, dst, dst, imm), ctx); break; case BPF_ALU | BPF_ARSH | BPF_K: case BPF_ALU64 | BPF_ARSH | BPF_K: + if (imm < 0 || imm >= bits) + return -EINVAL; emit(A64_ASR(is64, dst, dst, imm), ctx); break; -- 2.6.4 -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: filter: make JITs zero A for SKF_AD_ALU_XOR_X
On Tue, Jan 05, 2016 at 08:00:45AM -0800, Eric Dumazet wrote: > On Tue, 2016-01-05 at 16:23 +0100, Rabin Vincent wrote: > > The SKF_AD_ALU_XOR_X ancillary is not like the other ancillary data > > instructions since it XORs A with X while all the others replace A with > > some loaded value. All the BPF JITs fail to clear A if this is used as > > the first instruction in a filter. > > Is x86_64 part of this 'All' subset ? ;) No, because it's an eBPF JIT. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html