From: Greg Kroah-Hartman Date: Sun, 25 Mar 2018 10:03:15 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v4.15.14~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2db92d756c4165b99ba8325726ffd3ed447382f1;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: brcmfmac-fix-p2p_device-ethernet-address-generation.patch can-cc770-fix-queue-stall-dropped-rtr-reply.patch can-cc770-fix-stalls-on-rt-linux-remove-redundant-irq-ack.patch can-cc770-fix-use-after-free-in-cc770_tx_interrupt.patch drm-udl-properly-check-framebuffer-mmap-offsets.patch staging-ncpfs-memory-corruption-in-ncp_read_kernel.patch tracing-probeevent-fix-to-support-minus-offset-from-symbol.patch --- diff --git a/queue-3.18/brcmfmac-fix-p2p_device-ethernet-address-generation.patch b/queue-3.18/brcmfmac-fix-p2p_device-ethernet-address-generation.patch new file mode 100644 index 00000000000..403c0704380 --- /dev/null +++ b/queue-3.18/brcmfmac-fix-p2p_device-ethernet-address-generation.patch @@ -0,0 +1,70 @@ +From 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b Mon Sep 17 00:00:00 2001 +From: Arend Van Spriel +Date: Wed, 28 Feb 2018 21:15:20 +0100 +Subject: brcmfmac: fix P2P_DEVICE ethernet address generation + +From: Arend Van Spriel + +commit 455f3e76cfc0d893585a5f358b9ddbe9c1e1e53b upstream. + +The firmware has a requirement that the P2P_DEVICE address should +be different from the address of the primary interface. When not +specified by user-space, the driver generates the MAC address for +the P2P_DEVICE interface using the MAC address of the primary +interface and setting the locally administered bit. However, the MAC +address of the primary interface may already have that bit set causing +the creation of the P2P_DEVICE interface to fail with -EBUSY. Fix this +by using a random address instead to determine the P2P_DEVICE address. + +Cc: stable@vger.kernel.org # 3.10.y +Reported-by: Hans de Goede +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 24 +++++++++++------------- + 1 file changed, 11 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -460,25 +460,23 @@ static int brcmf_p2p_set_firmware(struct + * @dev_addr: optional device address. + * + * P2P needs mac addresses for P2P device and interface. If no device +- * address it specified, these are derived from the primary net device, ie. +- * the permanent ethernet address of the device. ++ * address it specified, these are derived from a random ethernet ++ * address. + */ + static void brcmf_p2p_generate_bss_mac(struct brcmf_p2p_info *p2p, u8 *dev_addr) + { +- struct brcmf_if *pri_ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; +- bool local_admin = false; ++ bool random_addr = false; + +- if (!dev_addr || is_zero_ether_addr(dev_addr)) { +- dev_addr = pri_ifp->mac_addr; +- local_admin = true; +- } ++ if (!dev_addr || is_zero_ether_addr(dev_addr)) ++ random_addr = true; + +- /* Generate the P2P Device Address. This consists of the device's +- * primary MAC address with the locally administered bit set. ++ /* Generate the P2P Device Address obtaining a random ethernet ++ * address with the locally administered bit set. + */ +- memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); +- if (local_admin) +- p2p->dev_addr[0] |= 0x02; ++ if (random_addr) ++ eth_random_addr(p2p->dev_addr); ++ else ++ memcpy(p2p->dev_addr, dev_addr, ETH_ALEN); + + /* Generate the P2P Interface Address. If the discovery and connection + * BSSCFGs need to simultaneously co-exist, then this address must be diff --git a/queue-3.18/can-cc770-fix-queue-stall-dropped-rtr-reply.patch b/queue-3.18/can-cc770-fix-queue-stall-dropped-rtr-reply.patch new file mode 100644 index 00000000000..9c2a6300f23 --- /dev/null +++ b/queue-3.18/can-cc770-fix-queue-stall-dropped-rtr-reply.patch @@ -0,0 +1,190 @@ +From 746201235b3f876792099079f4c6fea941d76183 Mon Sep 17 00:00:00 2001 +From: Andri Yngvason +Date: Wed, 14 Mar 2018 11:52:57 +0000 +Subject: can: cc770: Fix queue stall & dropped RTR reply + +From: Andri Yngvason + +commit 746201235b3f876792099079f4c6fea941d76183 upstream. + +While waiting for the TX object to send an RTR, an external message with a +matching id can overwrite the TX data. In this case we must call the rx +routine and then try transmitting the message that was overwritten again. + +The queue was being stalled because the RX event did not generate an +interrupt to wake up the queue again and the TX event did not happen +because the TXRQST flag is reset by the chip when new data is received. + +According to the CC770 datasheet the id of a message object should not be +changed while the MSGVAL bit is set. This has been fixed by resetting the +MSGVAL bit before modifying the object in the transmit function and setting +it after. It is not enough to set & reset CPUUPD. + +It is important to keep the MSGVAL bit reset while the message object is +being modified. Otherwise, during RTR transmission, a frame with matching +id could trigger an rx-interrupt, which would cause a race condition +between the interrupt routine and the transmit function. + +Signed-off-by: Andri Yngvason +Tested-by: Richard Weinberger +Cc: linux-stable +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/cc770/cc770.c | 94 +++++++++++++++++++++++++++++------------- + drivers/net/can/cc770/cc770.h | 2 + 2 files changed, 68 insertions(+), 28 deletions(-) + +--- a/drivers/net/can/cc770/cc770.c ++++ b/drivers/net/can/cc770/cc770.c +@@ -390,37 +390,23 @@ static int cc770_get_berr_counter(const + return 0; + } + +-static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) ++static void cc770_tx(struct net_device *dev, int mo) + { + struct cc770_priv *priv = netdev_priv(dev); +- struct net_device_stats *stats = &dev->stats; +- struct can_frame *cf = (struct can_frame *)skb->data; +- unsigned int mo = obj2msgobj(CC770_OBJ_TX); ++ struct can_frame *cf = (struct can_frame *)priv->tx_skb->data; + u8 dlc, rtr; + u32 id; + int i; + +- if (can_dropped_invalid_skb(dev, skb)) +- return NETDEV_TX_OK; +- +- if ((cc770_read_reg(priv, +- msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { +- netdev_err(dev, "TX register is still occupied!\n"); +- return NETDEV_TX_BUSY; +- } +- +- netif_stop_queue(dev); +- + dlc = cf->can_dlc; + id = cf->can_id; +- if (cf->can_id & CAN_RTR_FLAG) +- rtr = 0; +- else +- rtr = MSGCFG_DIR; ++ rtr = cf->can_id & CAN_RTR_FLAG ? 0 : MSGCFG_DIR; ++ ++ cc770_write_reg(priv, msgobj[mo].ctrl0, ++ MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); + cc770_write_reg(priv, msgobj[mo].ctrl1, + RMTPND_RES | TXRQST_RES | CPUUPD_SET | NEWDAT_RES); +- cc770_write_reg(priv, msgobj[mo].ctrl0, +- MSGVAL_SET | TXIE_SET | RXIE_RES | INTPND_RES); ++ + if (id & CAN_EFF_FLAG) { + id &= CAN_EFF_MASK; + cc770_write_reg(priv, msgobj[mo].config, +@@ -439,13 +425,30 @@ static netdev_tx_t cc770_start_xmit(stru + for (i = 0; i < dlc; i++) + cc770_write_reg(priv, msgobj[mo].data[i], cf->data[i]); + +- /* Store echo skb before starting the transfer */ +- can_put_echo_skb(skb, dev, 0); +- + cc770_write_reg(priv, msgobj[mo].ctrl1, +- RMTPND_RES | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); ++ RMTPND_UNC | TXRQST_SET | CPUUPD_RES | NEWDAT_UNC); ++ cc770_write_reg(priv, msgobj[mo].ctrl0, ++ MSGVAL_SET | TXIE_SET | RXIE_SET | INTPND_UNC); ++} ++ ++static netdev_tx_t cc770_start_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct cc770_priv *priv = netdev_priv(dev); ++ unsigned int mo = obj2msgobj(CC770_OBJ_TX); ++ ++ if (can_dropped_invalid_skb(dev, skb)) ++ return NETDEV_TX_OK; ++ ++ netif_stop_queue(dev); ++ ++ if ((cc770_read_reg(priv, ++ msgobj[mo].ctrl1) & TXRQST_UNC) == TXRQST_SET) { ++ netdev_err(dev, "TX register is still occupied!\n"); ++ return NETDEV_TX_BUSY; ++ } + +- stats->tx_bytes += dlc; ++ priv->tx_skb = skb; ++ cc770_tx(dev, mo); + + return NETDEV_TX_OK; + } +@@ -670,13 +673,47 @@ static void cc770_tx_interrupt(struct ne + struct cc770_priv *priv = netdev_priv(dev); + struct net_device_stats *stats = &dev->stats; + unsigned int mo = obj2msgobj(o); ++ struct can_frame *cf; ++ u8 ctrl1; ++ ++ ctrl1 = cc770_read_reg(priv, msgobj[mo].ctrl1); + +- /* Nothing more to send, switch off interrupts */ + cc770_write_reg(priv, msgobj[mo].ctrl0, + MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); ++ cc770_write_reg(priv, msgobj[mo].ctrl1, ++ RMTPND_RES | TXRQST_RES | MSGLST_RES | NEWDAT_RES); + +- stats->tx_packets++; ++ if (unlikely(!priv->tx_skb)) { ++ netdev_err(dev, "missing tx skb in tx interrupt\n"); ++ return; ++ } ++ ++ if (unlikely(ctrl1 & MSGLST_SET)) { ++ stats->rx_over_errors++; ++ stats->rx_errors++; ++ } ++ ++ /* When the CC770 is sending an RTR message and it receives a regular ++ * message that matches the id of the RTR message, it will overwrite the ++ * outgoing message in the TX register. When this happens we must ++ * process the received message and try to transmit the outgoing skb ++ * again. ++ */ ++ if (unlikely(ctrl1 & NEWDAT_SET)) { ++ cc770_rx(dev, mo, ctrl1); ++ cc770_tx(dev, mo); ++ return; ++ } ++ ++ can_put_echo_skb(priv->tx_skb, dev, 0); + can_get_echo_skb(dev, 0); ++ ++ cf = (struct can_frame *)priv->tx_skb->data; ++ stats->tx_bytes += cf->can_dlc; ++ stats->tx_packets++; ++ ++ priv->tx_skb = NULL; ++ + netif_wake_queue(dev); + } + +@@ -788,6 +825,7 @@ struct net_device *alloc_cc770dev(int si + priv->can.do_set_bittiming = cc770_set_bittiming; + priv->can.do_set_mode = cc770_set_mode; + priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; ++ priv->tx_skb = NULL; + + memcpy(priv->obj_flags, cc770_obj_flags, sizeof(cc770_obj_flags)); + +--- a/drivers/net/can/cc770/cc770.h ++++ b/drivers/net/can/cc770/cc770.h +@@ -193,6 +193,8 @@ struct cc770_priv { + u8 cpu_interface; /* CPU interface register */ + u8 clkout; /* Clock out register */ + u8 bus_config; /* Bus conffiguration register */ ++ ++ struct sk_buff *tx_skb; + }; + + struct net_device *alloc_cc770dev(int sizeof_priv); diff --git a/queue-3.18/can-cc770-fix-stalls-on-rt-linux-remove-redundant-irq-ack.patch b/queue-3.18/can-cc770-fix-stalls-on-rt-linux-remove-redundant-irq-ack.patch new file mode 100644 index 00000000000..17042871484 --- /dev/null +++ b/queue-3.18/can-cc770-fix-stalls-on-rt-linux-remove-redundant-irq-ack.patch @@ -0,0 +1,53 @@ +From f4353daf4905c0099fd25fa742e2ffd4a4bab26a Mon Sep 17 00:00:00 2001 +From: Andri Yngvason +Date: Wed, 14 Mar 2018 11:52:56 +0000 +Subject: can: cc770: Fix stalls on rt-linux, remove redundant IRQ ack + +From: Andri Yngvason + +commit f4353daf4905c0099fd25fa742e2ffd4a4bab26a upstream. + +This has been reported to cause stalls on rt-linux. + +Suggested-by: Richard Weinberger +Tested-by: Richard Weinberger +Signed-off-by: Andri Yngvason +Cc: linux-stable +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/cc770/cc770.c | 15 --------------- + 1 file changed, 15 deletions(-) + +--- a/drivers/net/can/cc770/cc770.c ++++ b/drivers/net/can/cc770/cc770.c +@@ -447,15 +447,6 @@ static netdev_tx_t cc770_start_xmit(stru + + stats->tx_bytes += dlc; + +- +- /* +- * HM: We had some cases of repeated IRQs so make sure the +- * INT is acknowledged I know it's already further up, but +- * doing again fixed the issue +- */ +- cc770_write_reg(priv, msgobj[mo].ctrl0, +- MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); +- + return NETDEV_TX_OK; + } + +@@ -683,12 +674,6 @@ static void cc770_tx_interrupt(struct ne + /* Nothing more to send, switch off interrupts */ + cc770_write_reg(priv, msgobj[mo].ctrl0, + MSGVAL_RES | TXIE_RES | RXIE_RES | INTPND_RES); +- /* +- * We had some cases of repeated IRQ so make sure the +- * INT is acknowledged +- */ +- cc770_write_reg(priv, msgobj[mo].ctrl0, +- MSGVAL_UNC | TXIE_UNC | RXIE_UNC | INTPND_RES); + + stats->tx_packets++; + can_get_echo_skb(dev, 0); diff --git a/queue-3.18/can-cc770-fix-use-after-free-in-cc770_tx_interrupt.patch b/queue-3.18/can-cc770-fix-use-after-free-in-cc770_tx_interrupt.patch new file mode 100644 index 00000000000..1f93d0020bb --- /dev/null +++ b/queue-3.18/can-cc770-fix-use-after-free-in-cc770_tx_interrupt.patch @@ -0,0 +1,39 @@ +From 9ffd7503944ec7c0ef41c3245d1306c221aef2be Mon Sep 17 00:00:00 2001 +From: Andri Yngvason +Date: Thu, 15 Mar 2018 18:23:17 +0000 +Subject: can: cc770: Fix use after free in cc770_tx_interrupt() + +From: Andri Yngvason + +commit 9ffd7503944ec7c0ef41c3245d1306c221aef2be upstream. + +This fixes use after free introduced by the last cc770 patch. + +Signed-off-by: Andri Yngvason +Fixes: 746201235b3f ("can: cc770: Fix queue stall & dropped RTR reply") +Cc: linux-stable +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/can/cc770/cc770.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/drivers/net/can/cc770/cc770.c ++++ b/drivers/net/can/cc770/cc770.c +@@ -705,13 +705,12 @@ static void cc770_tx_interrupt(struct ne + return; + } + +- can_put_echo_skb(priv->tx_skb, dev, 0); +- can_get_echo_skb(dev, 0); +- + cf = (struct can_frame *)priv->tx_skb->data; + stats->tx_bytes += cf->can_dlc; + stats->tx_packets++; + ++ can_put_echo_skb(priv->tx_skb, dev, 0); ++ can_get_echo_skb(dev, 0); + priv->tx_skb = NULL; + + netif_wake_queue(dev); diff --git a/queue-3.18/drm-udl-properly-check-framebuffer-mmap-offsets.patch b/queue-3.18/drm-udl-properly-check-framebuffer-mmap-offsets.patch new file mode 100644 index 00000000000..43fa1eb6248 --- /dev/null +++ b/queue-3.18/drm-udl-properly-check-framebuffer-mmap-offsets.patch @@ -0,0 +1,44 @@ +From 3b82a4db8eaccce735dffd50b4d4e1578099b8e8 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Wed, 21 Mar 2018 16:45:53 +0100 +Subject: drm: udl: Properly check framebuffer mmap offsets + +From: Greg Kroah-Hartman + +commit 3b82a4db8eaccce735dffd50b4d4e1578099b8e8 upstream. + +The memmap options sent to the udl framebuffer driver were not being +checked for all sets of possible crazy values. Fix this up by properly +bounding the allowed values. + +Reported-by: Eyal Itkin +Cc: stable +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Daniel Vetter +Link: https://patchwork.freedesktop.org/patch/msgid/20180321154553.GA18454@kroah.com +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/udl/udl_fb.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/gpu/drm/udl/udl_fb.c ++++ b/drivers/gpu/drm/udl/udl_fb.c +@@ -256,10 +256,15 @@ static int udl_fb_mmap(struct fb_info *i + { + unsigned long start = vma->vm_start; + unsigned long size = vma->vm_end - vma->vm_start; +- unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; ++ unsigned long offset; + unsigned long page, pos; + +- if (offset + size > info->fix.smem_len) ++ if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) ++ return -EINVAL; ++ ++ offset = vma->vm_pgoff << PAGE_SHIFT; ++ ++ if (offset > info->fix.smem_len || size > info->fix.smem_len - offset) + return -EINVAL; + + pos = (unsigned long)info->fix.smem_start + offset; diff --git a/queue-3.18/series b/queue-3.18/series index 7167902ddc5..3ed1a55d93b 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -9,3 +9,10 @@ libata-enable-queued-trim-for-samsung-ssd-860.patch libata-apply-nolpm-quirk-to-crucial-m500-480-and-960gb-ssds.patch libata-make-crucial-bx100-500gb-lpm-quirk-apply-to-all-firmware-versions.patch libata-modify-quirks-for-mx100-to-limit-ncq_trim-quirk-to-mu01-version.patch +drm-udl-properly-check-framebuffer-mmap-offsets.patch +brcmfmac-fix-p2p_device-ethernet-address-generation.patch +tracing-probeevent-fix-to-support-minus-offset-from-symbol.patch +staging-ncpfs-memory-corruption-in-ncp_read_kernel.patch +can-cc770-fix-stalls-on-rt-linux-remove-redundant-irq-ack.patch +can-cc770-fix-queue-stall-dropped-rtr-reply.patch +can-cc770-fix-use-after-free-in-cc770_tx_interrupt.patch diff --git a/queue-3.18/staging-ncpfs-memory-corruption-in-ncp_read_kernel.patch b/queue-3.18/staging-ncpfs-memory-corruption-in-ncp_read_kernel.patch new file mode 100644 index 00000000000..4cf14fbc100 --- /dev/null +++ b/queue-3.18/staging-ncpfs-memory-corruption-in-ncp_read_kernel.patch @@ -0,0 +1,35 @@ +From 4c41aa24baa4ed338241d05494f2c595c885af8f Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Mon, 19 Mar 2018 14:07:45 +0300 +Subject: staging: ncpfs: memory corruption in ncp_read_kernel() + +From: Dan Carpenter + +commit 4c41aa24baa4ed338241d05494f2c595c885af8f upstream. + +If the server is malicious then *bytes_read could be larger than the +size of the "target" buffer. It would lead to memory corruption when we +do the memcpy(). + +Reported-by: Dr Silvio Cesare of InfoSect +Signed-off-by: Dan Carpenter +Cc: stable +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ncpfs/ncplib_kernel.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/fs/ncpfs/ncplib_kernel.c ++++ b/fs/ncpfs/ncplib_kernel.c +@@ -980,6 +980,10 @@ ncp_read_kernel(struct ncp_server *serve + goto out; + } + *bytes_read = ncp_reply_be16(server, 0); ++ if (*bytes_read > to_read) { ++ result = -EINVAL; ++ goto out; ++ } + source = ncp_reply_data(server, 2 + (offset & 1)); + + memcpy(target, source, *bytes_read); diff --git a/queue-3.18/tracing-probeevent-fix-to-support-minus-offset-from-symbol.patch b/queue-3.18/tracing-probeevent-fix-to-support-minus-offset-from-symbol.patch new file mode 100644 index 00000000000..1c18845631a --- /dev/null +++ b/queue-3.18/tracing-probeevent-fix-to-support-minus-offset-from-symbol.patch @@ -0,0 +1,99 @@ +From c5d343b6b7badd1f5fe0873eff2e8d63a193e732 Mon Sep 17 00:00:00 2001 +From: Masami Hiramatsu +Date: Sat, 17 Mar 2018 21:38:10 +0900 +Subject: tracing: probeevent: Fix to support minus offset from symbol + +From: Masami Hiramatsu + +commit c5d343b6b7badd1f5fe0873eff2e8d63a193e732 upstream. + +In Documentation/trace/kprobetrace.txt, it says + + @SYM[+|-offs] : Fetch memory at SYM +|- offs (SYM should be a data symbol) + +However, the parser doesn't parse minus offset correctly, since +commit 2fba0c8867af ("tracing/kprobes: Fix probe offset to be +unsigned") drops minus ("-") offset support for kprobe probe +address usage. + +This fixes the traceprobe_split_symbol_offset() to parse minus +offset again with checking the offset range, and add a minus +offset check in kprobe probe address usage. + +Link: http://lkml.kernel.org/r/152129028983.31874.13419301530285775521.stgit@devbox + +Cc: Ingo Molnar +Cc: Tom Zanussi +Cc: Arnaldo Carvalho de Melo +Cc: Ravi Bangoria +Cc: stable@vger.kernel.org +Fixes: 2fba0c8867af ("tracing/kprobes: Fix probe offset to be unsigned") +Acked-by: Namhyung Kim +Signed-off-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_kprobe.c | 4 ++-- + kernel/trace/trace_probe.c | 8 +++----- + kernel/trace/trace_probe.h | 2 +- + 3 files changed, 6 insertions(+), 8 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -611,7 +611,7 @@ static int create_trace_kprobe(int argc, + bool is_return = false, is_delete = false; + char *symbol = NULL, *event = NULL, *group = NULL; + char *arg; +- unsigned long offset = 0; ++ long offset = 0; + void *addr = NULL; + char buf[MAX_EVENT_NAME_LEN]; + +@@ -679,7 +679,7 @@ static int create_trace_kprobe(int argc, + symbol = argv[1]; + /* TODO: support .init module functions */ + ret = traceprobe_split_symbol_offset(symbol, &offset); +- if (ret) { ++ if (ret || offset < 0 || offset > UINT_MAX) { + pr_info("Failed to parse either an address or a symbol.\n"); + return ret; + } +--- a/kernel/trace/trace_probe.c ++++ b/kernel/trace/trace_probe.c +@@ -291,7 +291,7 @@ static fetch_func_t get_fetch_size_funct + } + + /* Split symbol and offset. */ +-int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset) ++int traceprobe_split_symbol_offset(char *symbol, long *offset) + { + char *tmp; + int ret; +@@ -299,13 +299,11 @@ int traceprobe_split_symbol_offset(char + if (!offset) + return -EINVAL; + +- tmp = strchr(symbol, '+'); ++ tmp = strpbrk(symbol, "+-"); + if (tmp) { +- /* skip sign because kstrtoul doesn't accept '+' */ +- ret = kstrtoul(tmp + 1, 0, offset); ++ ret = kstrtol(tmp, 0, offset); + if (ret) + return ret; +- + *tmp = '\0'; + } else + *offset = 0; +--- a/kernel/trace/trace_probe.h ++++ b/kernel/trace/trace_probe.h +@@ -341,7 +341,7 @@ extern int traceprobe_conflict_field_nam + extern void traceprobe_update_arg(struct probe_arg *arg); + extern void traceprobe_free_probe_arg(struct probe_arg *arg); + +-extern int traceprobe_split_symbol_offset(char *symbol, unsigned long *offset); ++extern int traceprobe_split_symbol_offset(char *symbol, long *offset); + + extern ssize_t traceprobe_probes_write(struct file *file, + const char __user *buffer, size_t count, loff_t *ppos,