I'm announcing the release of the 3.18.109 kernel.
All users of the 3.18 kernel series must upgrade.
The updated 3.18.y git tree can be found at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-3.18.y and can be browsed at the normal kernel.org git web browser: http://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git%3Ba=summar...
thanks,
greg k-h
------------
Makefile | 2 - drivers/ata/libata-core.c | 3 + drivers/infiniband/hw/mlx5/qp.c | 4 ++ drivers/net/can/usb/kvaser_usb.c | 2 - drivers/net/usb/qmi_wwan.c | 1 drivers/usb/musb/musb_host.c | 4 +- drivers/usb/serial/visor.c | 69 ++++++++++++++++++------------------- include/net/inet_timewait_sock.h | 1 include/net/nexthop.h | 2 - kernel/events/callchain.c | 10 +---- kernel/events/core.c | 2 - kernel/trace/trace_events_filter.c | 3 + kernel/trace/trace_uprobe.c | 2 + mm/percpu.c | 1 net/core/dev_addr_lists.c | 4 +- net/core/skbuff.c | 1 net/ipv4/inet_timewait_sock.c | 1 net/ipv4/tcp.c | 2 - net/netlink/af_netlink.c | 2 + net/rfkill/rfkill-gpio.c | 7 +++ sound/core/pcm_compat.c | 2 + sound/core/seq/seq_virmidi.c | 4 +- sound/drivers/aloop.c | 29 ++++++++++++--- tools/perf/util/session.c | 1 24 files changed, 101 insertions(+), 58 deletions(-)
Bin Liu (1): usb: musb: host: fix potential NULL pointer dereference
Eric Dumazet (6): netlink: fix uninit-value in netlink_sendmsg net: fix rtnh_ok() net: initialize skb->peeked when cloning net: fix uninit-value in __hw_addr_add_ex() soreuseport: initialise timewait reuseport field tcp: fix TCP_REPAIR_QUEUE bound checking
Greg Kroah-Hartman (2): USB: serial: visor: handle potential invalid device configuration Linux 3.18.109
Hans de Goede (1): libata: Apply NOLPM quirk for SanDisk SD7UB3Q*G1001 SSDs
Jimmy Assarsson (1): can: kvaser_usb: Increase correct stats counter in kvaser_usb_rx_can_msg()
Jiri Olsa (1): perf: Remove superfluous allocation error check
Johan Hovold (1): rfkill: gpio: fix memory leak in probe error path
Leon Romanovsky (1): RDMA/mlx5: Protect from shift operand overflow
Masami Hiramatsu (1): tracing/uprobe_event: Fix strncpy corner case
Murilo Opsfelder Araujo (1): perf session: Fix undeclared 'oe'
Robert Rosengren (1): ALSA: aloop: Mark paused device as inactive
SZ Lin (林上智) (1): NET: usb: qmi_wwan: add support for ublox R410M PID 0x90b2
Steven Rostedt (VMware) (1): tracing: Fix regex_match_front() to not over compare the test string
Takashi Iwai (3): ALSA: pcm: Check PCM state at xfern compat ioctl ALSA: seq: Fix races at MIDI encoding in snd_virmidi_output_trigger() ALSA: aloop: Add missing cable lock to ctl API callbacks
Tan Xiaojun (1): perf/core: Fix the perf_cpu_time_max_percent check
Tejun Heo (1): percpu: include linux/sched.h for cond_resched()
diff --git a/Makefile b/Makefile index a562ebf4d500..2b756a97bdd4 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 3 PATCHLEVEL = 18 -SUBLEVEL = 108 +SUBLEVEL = 109 EXTRAVERSION = NAME = Diseased Newt
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index ac18149637be..c0b5661f87b2 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -4244,6 +4244,9 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = { ATA_HORKAGE_ZERO_AFTER_TRIM | ATA_HORKAGE_NOLPM, },
+ /* Sandisk devices which are known to not handle LPM well */ + { "SanDisk SD7UB3Q*G1001", NULL, ATA_HORKAGE_NOLPM, }, + /* devices that don't properly handle queued TRIM commands */ { "Micron_M500_*", NULL, ATA_HORKAGE_NO_NCQ_TRIM | ATA_HORKAGE_ZERO_AFTER_TRIM, }, diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c index e261a53f9a02..881e893aba82 100644 --- a/drivers/infiniband/hw/mlx5/qp.c +++ b/drivers/infiniband/hw/mlx5/qp.c @@ -174,7 +174,11 @@ static int set_rq_size(struct mlx5_ib_dev *dev, struct ib_qp_cap *cap, } else { if (ucmd) { qp->rq.wqe_cnt = ucmd->rq_wqe_count; + if (ucmd->rq_wqe_shift > BITS_PER_BYTE * sizeof(ucmd->rq_wqe_shift)) + return -EINVAL; qp->rq.wqe_shift = ucmd->rq_wqe_shift; + if ((1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) < qp->wq_sig) + return -EINVAL; qp->rq.max_gs = (1 << qp->rq.wqe_shift) / sizeof(struct mlx5_wqe_data_seg) - qp->wq_sig; qp->rq.max_post = qp->rq.wqe_cnt; } else { diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c index 355914a31591..a50b32bebd75 100644 --- a/drivers/net/can/usb/kvaser_usb.c +++ b/drivers/net/can/usb/kvaser_usb.c @@ -850,7 +850,7 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
skb = alloc_can_skb(priv->netdev, &cf); if (!skb) { - stats->tx_dropped++; + stats->rx_dropped++; return; }
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index cdaeb9295afc..03fabd71ddfc 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -673,6 +673,7 @@ static const struct usb_device_id products[] = { {QMI_FIXED_INTF(0x05c6, 0x9080, 8)}, {QMI_FIXED_INTF(0x05c6, 0x9083, 3)}, {QMI_FIXED_INTF(0x05c6, 0x9084, 4)}, + {QMI_FIXED_INTF(0x05c6, 0x90b2, 3)}, /* ublox R410M */ {QMI_FIXED_INTF(0x05c6, 0x920d, 0)}, {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, {QMI_FIXED_INTF(0x0846, 0x68a2, 8)}, diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 7da914bc2094..fed7da8a5f60 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c @@ -1002,7 +1002,9 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep, /* set tx_reinit and schedule the next qh */ ep->tx_reinit = 1; } - musb_start_urb(musb, is_in, next_qh); + + if (next_qh) + musb_start_urb(musb, is_in, next_qh); } }
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 337a0be89fcf..dbc3801b43eb 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -338,47 +338,48 @@ static int palm_os_3_probe(struct usb_serial *serial, goto exit; }
- if (retval == sizeof(*connection_info)) { - connection_info = (struct visor_connection_info *) - transfer_buffer; - - num_ports = le16_to_cpu(connection_info->num_ports); - for (i = 0; i < num_ports; ++i) { - switch ( - connection_info->connections[i].port_function_id) { - case VISOR_FUNCTION_GENERIC: - string = "Generic"; - break; - case VISOR_FUNCTION_DEBUGGER: - string = "Debugger"; - break; - case VISOR_FUNCTION_HOTSYNC: - string = "HotSync"; - break; - case VISOR_FUNCTION_CONSOLE: - string = "Console"; - break; - case VISOR_FUNCTION_REMOTE_FILE_SYS: - string = "Remote File System"; - break; - default: - string = "unknown"; - break; - } - dev_info(dev, "%s: port %d, is for %s use\n", - serial->type->description, - connection_info->connections[i].port, string); - } + if (retval != sizeof(*connection_info)) { + dev_err(dev, "Invalid connection information received from device\n"); + retval = -ENODEV; + goto exit; } - /* - * Handle devices that report invalid stuff here. - */ + + connection_info = (struct visor_connection_info *)transfer_buffer; + + num_ports = le16_to_cpu(connection_info->num_ports); + + /* Handle devices that report invalid stuff here. */ if (num_ports == 0 || num_ports > 2) { dev_warn(dev, "%s: No valid connect info available\n", serial->type->description); num_ports = 2; }
+ for (i = 0; i < num_ports; ++i) { + switch (connection_info->connections[i].port_function_id) { + case VISOR_FUNCTION_GENERIC: + string = "Generic"; + break; + case VISOR_FUNCTION_DEBUGGER: + string = "Debugger"; + break; + case VISOR_FUNCTION_HOTSYNC: + string = "HotSync"; + break; + case VISOR_FUNCTION_CONSOLE: + string = "Console"; + break; + case VISOR_FUNCTION_REMOTE_FILE_SYS: + string = "Remote File System"; + break; + default: + string = "unknown"; + break; + } + dev_info(dev, "%s: port %d, is for %s use\n", + serial->type->description, + connection_info->connections[i].port, string); + } dev_info(dev, "%s: Number of ports: %d\n", serial->type->description, num_ports);
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 6c566034e26d..ebbe5f4215d5 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -108,6 +108,7 @@ struct inet_timewait_sock { #define tw_family __tw_common.skc_family #define tw_state __tw_common.skc_state #define tw_reuse __tw_common.skc_reuse +#define tw_reuseport __tw_common.skc_reuseport #define tw_ipv6only __tw_common.skc_ipv6only #define tw_bound_dev_if __tw_common.skc_bound_dev_if #define tw_node __tw_common.skc_nulls_node diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 3334dbfa5aa4..7fc78663ec9d 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -6,7 +6,7 @@
static inline int rtnh_ok(const struct rtnexthop *rtnh, int remaining) { - return remaining >= sizeof(*rtnh) && + return remaining >= (int)sizeof(*rtnh) && rtnh->rtnh_len >= sizeof(*rtnh) && rtnh->rtnh_len <= remaining; } diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c index d659487254d5..d37acf86037a 100644 --- a/kernel/events/callchain.c +++ b/kernel/events/callchain.c @@ -107,14 +107,8 @@ int get_callchain_buffers(void) goto exit; }
- if (count > 1) { - /* If the allocation failed, give up */ - if (!callchain_cpus_entries) - err = -ENOMEM; - goto exit; - } - - err = alloc_callchain_buffers(); + if (count == 1) + err = alloc_callchain_buffers(); exit: if (err) atomic_dec(&nr_callchain_events); diff --git a/kernel/events/core.c b/kernel/events/core.c index af2780655f5b..e97986c99ed7 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -224,7 +224,7 @@ int perf_cpu_time_max_percent_handler(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { - int ret = proc_dointvec(table, write, buffer, lenp, ppos); + int ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret || !write) return ret; diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c index fee491d5af9f..27b7bf00457c 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -273,6 +273,9 @@ static int regex_match_full(char *str, struct regex *r, int len)
static int regex_match_front(char *str, struct regex *r, int len) { + if (len < r->len) + return 0; + if (strncmp(str, r->pattern, r->len) == 0) return 1; return 0; diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index db92b385c155..f7e75f3dfcb2 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -149,6 +149,8 @@ static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs, return;
ret = strncpy_from_user(dst, src, maxlen); + if (ret == maxlen) + dst[--ret] = '\0';
if (ret < 0) { /* Failed to fetch string */ ((u8 *)get_rloc_data(dest))[0] = '\0'; diff --git a/mm/percpu.c b/mm/percpu.c index f7da3a3070c4..ac0b633e8947 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -68,6 +68,7 @@ #include <linux/vmalloc.h> #include <linux/workqueue.h> #include <linux/kmemleak.h> +#include <linux/sched.h>
#include <asm/cacheflush.h> #include <asm/sections.h> diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index b6b230600b97..41aad226c69b 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c @@ -57,8 +57,8 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, return -EINVAL;
list_for_each_entry(ha, &list->list, list) { - if (!memcmp(ha->addr, addr, addr_len) && - ha->type == addr_type) { + if (ha->type == addr_type && + !memcmp(ha->addr, addr, addr_len)) { if (global) { /* check if addr is already used as global */ if (ha->global_use) diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 1666c8eaaaf0..e02948e9727a 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -779,6 +779,7 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb) n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len; n->cloned = 1; n->nohdr = 0; + n->peeked = 0; n->destructor = NULL; C(tail); C(end); diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c index 6d592f8555fb..04ec29ec670a 100644 --- a/net/ipv4/inet_timewait_sock.c +++ b/net/ipv4/inet_timewait_sock.c @@ -191,6 +191,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat tw->tw_dport = inet->inet_dport; tw->tw_family = sk->sk_family; tw->tw_reuse = sk->sk_reuse; + tw->tw_reuseport = sk->sk_reuseport; tw->tw_hash = sk->sk_hash; tw->tw_ipv6only = 0; tw->tw_transparent = inet->transparent; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 0ed7fe7d8d54..49b31070635f 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2461,7 +2461,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, case TCP_REPAIR_QUEUE: if (!tp->repair) err = -EPERM; - else if (val < TCP_QUEUES_NR) + else if ((unsigned int)val < TCP_QUEUES_NR) tp->repair_queue = val; else err = -EINVAL; diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ed9f07c46815..50096e0edd8e 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1641,6 +1641,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
if (msg->msg_namelen) { err = -EINVAL; + if (msg->msg_namelen < sizeof(struct sockaddr_nl)) + goto out; if (addr->nl_family != AF_NETLINK) goto out; dst_portid = addr->nl_pid; diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c index 0f62326c0f5e..ffa7a20e7b02 100644 --- a/net/rfkill/rfkill-gpio.c +++ b/net/rfkill/rfkill-gpio.c @@ -134,13 +134,18 @@ static int rfkill_gpio_probe(struct platform_device *pdev)
ret = rfkill_register(rfkill->rfkill_dev); if (ret < 0) - return ret; + goto err_destroy;
platform_set_drvdata(pdev, rfkill);
dev_info(&pdev->dev, "%s device registered.\n", rfkill->name);
return 0; + +err_destroy: + rfkill_destroy(rfkill->rfkill_dev); + + return ret; }
static int rfkill_gpio_remove(struct platform_device *pdev) diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c index 2d957ba63557..9e7afcb03cd8 100644 --- a/sound/core/pcm_compat.c +++ b/sound/core/pcm_compat.c @@ -333,6 +333,8 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream, return -ENOTTY; if (substream->stream != dir) return -EINVAL; + if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN) + return -EBADFD;
if ((ch = substream->runtime->channels) > 128) return -EINVAL; diff --git a/sound/core/seq/seq_virmidi.c b/sound/core/seq/seq_virmidi.c index 3b126af4a026..ef494ffc1369 100644 --- a/sound/core/seq/seq_virmidi.c +++ b/sound/core/seq/seq_virmidi.c @@ -174,12 +174,12 @@ static void snd_virmidi_output_trigger(struct snd_rawmidi_substream *substream, } return; } + spin_lock_irqsave(&substream->runtime->lock, flags); if (vmidi->event.type != SNDRV_SEQ_EVENT_NONE) { if (snd_seq_kernel_client_dispatch(vmidi->client, &vmidi->event, in_atomic(), 0) < 0) - return; + goto out; vmidi->event.type = SNDRV_SEQ_EVENT_NONE; } - spin_lock_irqsave(&substream->runtime->lock, flags); while (1) { count = __snd_rawmidi_transmit_peek(substream, buf, sizeof(buf)); if (count <= 0) diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 6c5b4e057521..835f3093a48d 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c @@ -297,6 +297,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) cable->pause |= stream; loopback_timer_stop(dpcm); spin_unlock(&cable->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + loopback_active_notify(dpcm); break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: @@ -305,6 +307,8 @@ static int loopback_trigger(struct snd_pcm_substream *substream, int cmd) cable->pause &= ~stream; loopback_timer_start(dpcm); spin_unlock(&cable->lock); + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + loopback_active_notify(dpcm); break; default: return -EINVAL; @@ -829,9 +833,11 @@ static int loopback_rate_shift_get(struct snd_kcontrol *kcontrol, { struct loopback *loopback = snd_kcontrol_chip(kcontrol); + mutex_lock(&loopback->cable_lock); ucontrol->value.integer.value[0] = loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].rate_shift; + mutex_unlock(&loopback->cable_lock); return 0; }
@@ -863,9 +869,11 @@ static int loopback_notify_get(struct snd_kcontrol *kcontrol, { struct loopback *loopback = snd_kcontrol_chip(kcontrol); + mutex_lock(&loopback->cable_lock); ucontrol->value.integer.value[0] = loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].notify; + mutex_unlock(&loopback->cable_lock); return 0; }
@@ -877,12 +885,14 @@ static int loopback_notify_put(struct snd_kcontrol *kcontrol, int change = 0;
val = ucontrol->value.integer.value[0] ? 1 : 0; + mutex_lock(&loopback->cable_lock); if (val != loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].notify) { loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].notify = val; change = 1; } + mutex_unlock(&loopback->cable_lock); return change; }
@@ -890,13 +900,18 @@ static int loopback_active_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct loopback *loopback = snd_kcontrol_chip(kcontrol); - struct loopback_cable *cable = loopback->cables - [kcontrol->id.subdevice][kcontrol->id.device ^ 1]; + struct loopback_cable *cable; + unsigned int val = 0;
- if (cable != NULL) - val = (cable->running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? - 1 : 0; + mutex_lock(&loopback->cable_lock); + cable = loopback->cables[kcontrol->id.subdevice][kcontrol->id.device ^ 1]; + if (cable != NULL) { + unsigned int running = cable->running ^ cable->pause; + + val = (running & (1 << SNDRV_PCM_STREAM_PLAYBACK)) ? 1 : 0; + } + mutex_unlock(&loopback->cable_lock); ucontrol->value.integer.value[0] = val; return 0; } @@ -939,9 +954,11 @@ static int loopback_rate_get(struct snd_kcontrol *kcontrol, { struct loopback *loopback = snd_kcontrol_chip(kcontrol); + mutex_lock(&loopback->cable_lock); ucontrol->value.integer.value[0] = loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].rate; + mutex_unlock(&loopback->cable_lock); return 0; }
@@ -961,9 +978,11 @@ static int loopback_channels_get(struct snd_kcontrol *kcontrol, { struct loopback *loopback = snd_kcontrol_chip(kcontrol); + mutex_lock(&loopback->cable_lock); ucontrol->value.integer.value[0] = loopback->setup[kcontrol->id.subdevice] [kcontrol->id.device].channels; + mutex_unlock(&loopback->cable_lock); return 0; }
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index dc3d3b1b813e..c2d4a7ec40df 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1073,6 +1073,7 @@ volatile int session_done; static int __perf_session__process_pipe_events(struct perf_session *session, struct perf_tool *tool) { + struct ordered_events *oe = &session->ordered_events; int fd = perf_data_file__fd(session->file); union perf_event *event; uint32_t size, cur_size = 0;
linux-stable-mirror@lists.linaro.org