From: Greg Kroah-Hartman Date: Sat, 9 Apr 2016 23:40:00 +0000 (-0700) Subject: 4.4-stable patches X-Git-Tag: v4.5.1~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=26de55e097e4fef93f7ed2e7a81de0a3590a841d;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: aacraid-fix-memory-leak-in-aac_fib_map_free.patch aacraid-fix-rrq-overload.patch aacraid-set-correct-msix-count-for-eeh-recovery.patch aic7xxx-fix-queue-depth-handling.patch alsa-usb-audio-add-microsoft-hd-5001-to-quirks.patch alsa-usb-audio-add-sanity-checks-for-endpoint-accesses.patch alsa-usb-audio-fix-double-free-in-error-paths-after-snd_usb_add_audio_stream-call.patch alsa-usb-audio-fix-null-dereference-in-create_fixed_stream_quirk.patch alsa-usb-audio-minor-code-cleanup-in-create_fixed_stream_quirk.patch be2iscsi-set-the-boot_kset-pointer-to-null-in-case-of-failure.patch bluetooth-btusb-add-a-new-ar3012-id-04ca-3014.patch bluetooth-btusb-add-a-new-ar3012-id-13d3-3472.patch bluetooth-btusb-add-new-ar3012-id-13d3-3395.patch dm-cache-make-sure-every-metadata-function-checks-fail_io.patch dm-fix-excessive-dm-mq-context-switching.patch dm-fix-rq_end_stats-null-pointer-in-dm_requeue_original_request.patch dm-snapshot-disallow-the-cow-and-origin-devices-from-being-identical.patch dm-thin-metadata-don-t-issue-prefetches-if-a-transaction-abort-has-failed.patch input-powermate-fix-oops-with-malicious-usb-descriptors.patch libnvdimm-fix-security-issue-with-dsm-ioctl.patch pwc-add-usb-id-for-philips-spc880nc-webcam.patch scsi-storvsc-fix-srb_status_aborted-handling.patch sd-fix-discard-granularity-when-lbprz-1.patch sg-fix-dxferp-in-from_to-case.patch usb-cdc-acm-more-sanity-checking.patch usb-cypress_m8-add-endpoint-sanity-check.patch usb-digi_acceleport-do-sanity-checking-for-the-number-of-ports.patch usb-hub-fix-a-typo-in-hub_port_init-leading-to-wrong-logic.patch usb-iowarrior-fix-oops-with-malicious-usb-descriptors.patch usb-mct_u232-add-sanity-checking-in-probe.patch usb-option-add-d-link-dwm-221-b1-device-id.patch usb-retry-reset-if-a-device-times-out.patch usb-serial-cp210x-adding-ge-healthcare-device-id.patch usb-serial-ftdi_sio-add-support-for-icp-das-i-756xu-devices.patch usb-uas-reduce-can_queue-to-max_cmnds.patch usb-usb_driver_claim_interface-add-sanity-checking.patch --- diff --git a/queue-4.4/aacraid-fix-memory-leak-in-aac_fib_map_free.patch b/queue-4.4/aacraid-fix-memory-leak-in-aac_fib_map_free.patch new file mode 100644 index 00000000000..918e14ce6b1 --- /dev/null +++ b/queue-4.4/aacraid-fix-memory-leak-in-aac_fib_map_free.patch @@ -0,0 +1,47 @@ +From f88fa79a61726ce9434df9b4aede36961f709f17 Mon Sep 17 00:00:00 2001 +From: Raghava Aditya Renukunta +Date: Wed, 3 Feb 2016 15:06:02 -0800 +Subject: aacraid: Fix memory leak in aac_fib_map_free + +From: Raghava Aditya Renukunta + +commit f88fa79a61726ce9434df9b4aede36961f709f17 upstream. + +aac_fib_map_free() calls pci_free_consistent() without checking that +dev->hw_fib_va is not NULL and dev->max_fib_size is not zero.If they are +indeed NULL/0, this will result in a hang as pci_free_consistent() will +attempt to invalidate cache for the entire 64-bit address space +(which would take a very long time). + +Fixed by adding a check to make sure that dev->hw_fib_va and +dev->max_fib_size are not NULL and 0 respectively. + +Fixes: 9ad5204d6 - "[SCSI]aacraid: incorrect dma mapping mask during blinked recover or user initiated reset" +Signed-off-by: Raghava Aditya Renukunta +Reviewed-by: Johannes Thumshirn +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/aacraid/commsup.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/scsi/aacraid/commsup.c ++++ b/drivers/scsi/aacraid/commsup.c +@@ -83,9 +83,12 @@ static int fib_map_alloc(struct aac_dev + + void aac_fib_map_free(struct aac_dev *dev) + { +- pci_free_consistent(dev->pdev, +- dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), +- dev->hw_fib_va, dev->hw_fib_pa); ++ if (dev->hw_fib_va && dev->max_fib_size) { ++ pci_free_consistent(dev->pdev, ++ (dev->max_fib_size * ++ (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)), ++ dev->hw_fib_va, dev->hw_fib_pa); ++ } + dev->hw_fib_va = NULL; + dev->hw_fib_pa = 0; + } diff --git a/queue-4.4/aacraid-fix-rrq-overload.patch b/queue-4.4/aacraid-fix-rrq-overload.patch new file mode 100644 index 00000000000..0f5ab309320 --- /dev/null +++ b/queue-4.4/aacraid-fix-rrq-overload.patch @@ -0,0 +1,152 @@ +From 3f4ce057d51a9c0ed9b01ba693df685d230ffcae Mon Sep 17 00:00:00 2001 +From: Raghava Aditya Renukunta +Date: Wed, 3 Feb 2016 15:06:00 -0800 +Subject: aacraid: Fix RRQ overload + +From: Raghava Aditya Renukunta + +commit 3f4ce057d51a9c0ed9b01ba693df685d230ffcae upstream. + +The driver utilizes an array of atomic variables to keep track of IO +submissions to each vector. To submit an IO multiple threads iterate +through the array to find a vector which has empty slots to send an +IO. The reading and updating of the variable is not atomic, causing race +conditions when a thread uses a full vector to submit an IO. + +Fixed by mapping each FIB to a vector, the submission path then uses +said vector to submit IO thereby removing the possibly of a race +condition.The vector assignment is started from 1 since vector 0 is +reserved for the use of AIF management FIBS.If the number of MSIx +vectors is 1 (MSI or INTx mode) then all the fibs are allocated to +vector 0. + +Fixes: 495c0217 "aacraid: MSI-x support" +Signed-off-by: Raghava Aditya Renukunta +Reviewed-by: Johannes Thumshirn +Reviewed-by: Tomas Henzl +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/aacraid/aacraid.h | 2 ++ + drivers/scsi/aacraid/commsup.c | 28 ++++++++++++++++++++++++++++ + drivers/scsi/aacraid/src.c | 30 +++++++----------------------- + 3 files changed, 37 insertions(+), 23 deletions(-) + +--- a/drivers/scsi/aacraid/aacraid.h ++++ b/drivers/scsi/aacraid/aacraid.h +@@ -944,6 +944,7 @@ struct fib { + */ + struct list_head fiblink; + void *data; ++ u32 vector_no; + struct hw_fib *hw_fib_va; /* Actual shared object */ + dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ + }; +@@ -2113,6 +2114,7 @@ static inline unsigned int cap_to_cyls(s + int aac_acquire_irq(struct aac_dev *dev); + void aac_free_irq(struct aac_dev *dev); + const char *aac_driverinfo(struct Scsi_Host *); ++void aac_fib_vector_assign(struct aac_dev *dev); + struct fib *aac_fib_alloc(struct aac_dev *dev); + int aac_fib_setup(struct aac_dev *dev); + void aac_fib_map_free(struct aac_dev *dev); +--- a/drivers/scsi/aacraid/commsup.c ++++ b/drivers/scsi/aacraid/commsup.c +@@ -90,6 +90,28 @@ void aac_fib_map_free(struct aac_dev *de + dev->hw_fib_pa = 0; + } + ++void aac_fib_vector_assign(struct aac_dev *dev) ++{ ++ u32 i = 0; ++ u32 vector = 1; ++ struct fib *fibptr = NULL; ++ ++ for (i = 0, fibptr = &dev->fibs[i]; ++ i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); ++ i++, fibptr++) { ++ if ((dev->max_msix == 1) || ++ (i > ((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1) ++ - dev->vector_cap))) { ++ fibptr->vector_no = 0; ++ } else { ++ fibptr->vector_no = vector; ++ vector++; ++ if (vector == dev->max_msix) ++ vector = 1; ++ } ++ } ++} ++ + /** + * aac_fib_setup - setup the fibs + * @dev: Adapter to set up +@@ -151,6 +173,12 @@ int aac_fib_setup(struct aac_dev * dev) + hw_fib_pa = hw_fib_pa + + dev->max_fib_size + sizeof(struct aac_fib_xporthdr); + } ++ ++ /* ++ *Assign vector numbers to fibs ++ */ ++ aac_fib_vector_assign(dev); ++ + /* + * Add the fib chain to the free list + */ +--- a/drivers/scsi/aacraid/src.c ++++ b/drivers/scsi/aacraid/src.c +@@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message( + break; + if (dev->msi_enabled && dev->max_msix > 1) + atomic_dec(&dev->rrq_outstanding[vector_no]); +- aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL); + dev->host_rrq[index++] = 0; ++ aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL); + if (index == (vector_no + 1) * dev->vector_cap) + index = vector_no * dev->vector_cap; + dev->host_rrq_idx[vector_no] = index; +@@ -452,36 +452,20 @@ static int aac_src_deliver_message(struc + #endif + + u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size); ++ u16 vector_no; + + atomic_inc(&q->numpending); + + if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest && + dev->max_msix > 1) { +- u_int16_t vector_no, first_choice = 0xffff; +- +- vector_no = dev->fibs_pushed_no % dev->max_msix; +- do { +- vector_no += 1; +- if (vector_no == dev->max_msix) +- vector_no = 1; +- if (atomic_read(&dev->rrq_outstanding[vector_no]) < +- dev->vector_cap) +- break; +- if (0xffff == first_choice) +- first_choice = vector_no; +- else if (vector_no == first_choice) +- break; +- } while (1); +- if (vector_no == first_choice) +- vector_no = 0; +- atomic_inc(&dev->rrq_outstanding[vector_no]); +- if (dev->fibs_pushed_no == 0xffffffff) +- dev->fibs_pushed_no = 0; +- else +- dev->fibs_pushed_no++; ++ vector_no = fib->vector_no; + fib->hw_fib_va->header.Handle += (vector_no << 16); ++ } else { ++ vector_no = 0; + } + ++ atomic_inc(&dev->rrq_outstanding[vector_no]); ++ + if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { + /* Calculate the amount to the fibsize bits */ + fibsize = (hdr_size + 127) / 128 - 1; diff --git a/queue-4.4/aacraid-set-correct-msix-count-for-eeh-recovery.patch b/queue-4.4/aacraid-set-correct-msix-count-for-eeh-recovery.patch new file mode 100644 index 00000000000..c079793b245 --- /dev/null +++ b/queue-4.4/aacraid-set-correct-msix-count-for-eeh-recovery.patch @@ -0,0 +1,51 @@ +From ecc479e00db8eb110b200afe1effcb3df20ca7ae Mon Sep 17 00:00:00 2001 +From: Raghava Aditya Renukunta +Date: Wed, 3 Feb 2016 15:06:03 -0800 +Subject: aacraid: Set correct msix count for EEH recovery + +From: Raghava Aditya Renukunta + +commit ecc479e00db8eb110b200afe1effcb3df20ca7ae upstream. + +During EEH recovery number of online CPU's might change thereby changing +the number of MSIx vectors. Since each fib is allocated to a vector, +changes in the number of vectors causes fib to be sent thru invalid +vectors.In addition the correct number of MSIx vectors is not updated in +the INIT struct sent to the controller, when it is reinitialized. + +Fixed by reassigning vectors to fibs based on the updated number of MSIx +vectors and updating the INIT structure before sending to controller. + +Fixes: MSI-X vector calculation for suspend/resume +Signed-off-by: Raghava Aditya Renukunta +Reviewed-by: Shane Seymour +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/aacraid/linit.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/aacraid/linit.c ++++ b/drivers/scsi/aacraid/linit.c +@@ -1404,8 +1404,18 @@ static int aac_acquire_resources(struct + + aac_adapter_enable_int(dev); + +- if (!dev->sync_mode) ++ /*max msix may change after EEH ++ * Re-assign vectors to fibs ++ */ ++ aac_fib_vector_assign(dev); ++ ++ if (!dev->sync_mode) { ++ /* After EEH recovery or suspend resume, max_msix count ++ * may change, therfore updating in init as well. ++ */ + aac_adapter_start(dev); ++ dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix); ++ } + return 0; + + error_iounmap: diff --git a/queue-4.4/aic7xxx-fix-queue-depth-handling.patch b/queue-4.4/aic7xxx-fix-queue-depth-handling.patch new file mode 100644 index 00000000000..decea990298 --- /dev/null +++ b/queue-4.4/aic7xxx-fix-queue-depth-handling.patch @@ -0,0 +1,32 @@ +From 5a51a7abca133860a6f4429655a9eda3c4afde32 Mon Sep 17 00:00:00 2001 +From: Alan +Date: Mon, 15 Feb 2016 18:53:15 +0000 +Subject: aic7xxx: Fix queue depth handling + +From: Alan + +commit 5a51a7abca133860a6f4429655a9eda3c4afde32 upstream. + +We were setting the queue depth correctly, then setting it back to +two. If you hit this as a bisection point then please send me an email +as it would imply we've been hiding other bugs with this one. + +Signed-off-by: Alan Cox +Reviewed-by: Hannes Reinicke +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/aic7xxx/aic7xxx_osm.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c ++++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c +@@ -1336,6 +1336,7 @@ ahc_platform_set_tags(struct ahc_softc * + case AHC_DEV_Q_TAGGED: + scsi_change_queue_depth(sdev, + dev->openings + dev->active); ++ break; + default: + /* + * We allow the OS to queue 2 untagged transactions to diff --git a/queue-4.4/alsa-usb-audio-add-microsoft-hd-5001-to-quirks.patch b/queue-4.4/alsa-usb-audio-add-microsoft-hd-5001-to-quirks.patch new file mode 100644 index 00000000000..5cea90c53f8 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-add-microsoft-hd-5001-to-quirks.patch @@ -0,0 +1,34 @@ +From 0ef21100ae912f76ed89f76ecd894f4ffb3689c1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Victor=20Cl=C3=A9ment?= +Date: Sat, 19 Mar 2016 13:17:42 +0100 +Subject: ALSA: usb-audio: add Microsoft HD-5001 to quirks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Victor Clément + +commit 0ef21100ae912f76ed89f76ecd894f4ffb3689c1 upstream. + +The Microsoft HD-5001 webcam microphone does not support sample rate +reading as the HD-5000 one. +This results in dmesg errors and sound hanging with pulseaudio. + +Signed-off-by: Victor Clément +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -1127,6 +1127,7 @@ bool snd_usb_get_sample_rate_quirk(struc + switch (chip->usb_id) { + case USB_ID(0x045E, 0x075D): /* MS Lifecam Cinema */ + case USB_ID(0x045E, 0x076D): /* MS Lifecam HD-5000 */ ++ case USB_ID(0x045E, 0x076E): /* MS Lifecam HD-5001 */ + case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */ + case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */ + case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */ diff --git a/queue-4.4/alsa-usb-audio-add-sanity-checks-for-endpoint-accesses.patch b/queue-4.4/alsa-usb-audio-add-sanity-checks-for-endpoint-accesses.patch new file mode 100644 index 00000000000..8593db35927 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-add-sanity-checks-for-endpoint-accesses.patch @@ -0,0 +1,74 @@ +From 447d6275f0c21f6cc97a88b3a0c601436a4cdf2a Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 15 Mar 2016 15:20:58 +0100 +Subject: ALSA: usb-audio: Add sanity checks for endpoint accesses + +From: Takashi Iwai + +commit 447d6275f0c21f6cc97a88b3a0c601436a4cdf2a upstream. + +Add some sanity check codes before actually accessing the endpoint via +get_endpoint() in order to avoid the invalid access through a +malformed USB descriptor. Mostly just checking bNumEndpoints, but in +one place (snd_microii_spdif_default_get()), the validity of iface and +altsetting index is checked as well. + +Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/clock.c | 2 ++ + sound/usb/endpoint.c | 3 +++ + sound/usb/mixer_quirks.c | 4 ++++ + sound/usb/pcm.c | 2 ++ + 4 files changed, 11 insertions(+) + +--- a/sound/usb/clock.c ++++ b/sound/usb/clock.c +@@ -285,6 +285,8 @@ static int set_sample_rate_v1(struct snd + unsigned char data[3]; + int err, crate; + ++ if (get_iface_desc(alts)->bNumEndpoints < 1) ++ return -EINVAL; + ep = get_endpoint(alts, 0)->bEndpointAddress; + + /* if endpoint doesn't have sampling rate control, bail out */ +--- a/sound/usb/endpoint.c ++++ b/sound/usb/endpoint.c +@@ -438,6 +438,9 @@ exit_clear: + * + * New endpoints will be added to chip->ep_list and must be freed by + * calling snd_usb_endpoint_free(). ++ * ++ * For SND_USB_ENDPOINT_TYPE_SYNC, the caller needs to guarantee that ++ * bNumEndpoints > 1 beforehand. + */ + struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, + struct usb_host_interface *alts, +--- a/sound/usb/mixer_quirks.c ++++ b/sound/usb/mixer_quirks.c +@@ -1519,7 +1519,11 @@ static int snd_microii_spdif_default_get + + /* use known values for that card: interface#1 altsetting#1 */ + iface = usb_ifnum_to_if(chip->dev, 1); ++ if (!iface || iface->num_altsetting < 2) ++ return -EINVAL; + alts = &iface->altsetting[1]; ++ if (get_iface_desc(alts)->bNumEndpoints < 1) ++ return -EINVAL; + ep = get_endpoint(alts, 0)->bEndpointAddress; + + err = snd_usb_ctl_msg(chip->dev, +--- a/sound/usb/pcm.c ++++ b/sound/usb/pcm.c +@@ -159,6 +159,8 @@ static int init_pitch_v1(struct snd_usb_ + unsigned char data[1]; + int err; + ++ if (get_iface_desc(alts)->bNumEndpoints < 1) ++ return -EINVAL; + ep = get_endpoint(alts, 0)->bEndpointAddress; + + data[0] = 1; diff --git a/queue-4.4/alsa-usb-audio-fix-double-free-in-error-paths-after-snd_usb_add_audio_stream-call.patch b/queue-4.4/alsa-usb-audio-fix-double-free-in-error-paths-after-snd_usb_add_audio_stream-call.patch new file mode 100644 index 00000000000..afa28416ae1 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-fix-double-free-in-error-paths-after-snd_usb_add_audio_stream-call.patch @@ -0,0 +1,98 @@ +From 836b34a935abc91e13e63053d0a83b24dfb5ea78 Mon Sep 17 00:00:00 2001 +From: Vladis Dronov +Date: Thu, 31 Mar 2016 12:05:43 -0400 +Subject: ALSA: usb-audio: Fix double-free in error paths after snd_usb_add_audio_stream() call + +From: Vladis Dronov + +commit 836b34a935abc91e13e63053d0a83b24dfb5ea78 upstream. + +create_fixed_stream_quirk(), snd_usb_parse_audio_interface() and +create_uaxx_quirk() functions allocate the audioformat object by themselves +and free it upon error before returning. However, once the object is linked +to a stream, it's freed again in snd_usb_audio_pcm_free(), thus it'll be +double-freed, eventually resulting in a memory corruption. + +This patch fixes these failures in the error paths by unlinking the audioformat +object before freeing it. + +Based on a patch by Takashi Iwai + +[Note for stable backports: + this patch requires the commit 902eb7fd1e4a ('ALSA: usb-audio: Minor + code cleanup in create_fixed_stream_quirk()')] + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1283358 +Reported-by: Ralf Spenneberg +Signed-off-by: Vladis Dronov +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks.c | 4 ++++ + sound/usb/stream.c | 6 +++++- + 2 files changed, 9 insertions(+), 1 deletion(-) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -150,6 +150,7 @@ static int create_fixed_stream_quirk(str + usb_audio_err(chip, "cannot memdup\n"); + return -ENOMEM; + } ++ INIT_LIST_HEAD(&fp->list); + if (fp->nr_rates > MAX_NR_RATES) { + kfree(fp); + return -EINVAL; +@@ -193,6 +194,7 @@ static int create_fixed_stream_quirk(str + return 0; + + error: ++ list_del(&fp->list); /* unlink for avoiding double-free */ + kfree(fp); + kfree(rate_table); + return err; +@@ -468,6 +470,7 @@ static int create_uaxx_quirk(struct snd_ + fp->ep_attr = get_endpoint(alts, 0)->bmAttributes; + fp->datainterval = 0; + fp->maxpacksize = le16_to_cpu(get_endpoint(alts, 0)->wMaxPacketSize); ++ INIT_LIST_HEAD(&fp->list); + + switch (fp->maxpacksize) { + case 0x120: +@@ -491,6 +494,7 @@ static int create_uaxx_quirk(struct snd_ + ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + err = snd_usb_add_audio_stream(chip, stream, fp); + if (err < 0) { ++ list_del(&fp->list); /* unlink for avoiding double-free */ + kfree(fp); + return err; + } +--- a/sound/usb/stream.c ++++ b/sound/usb/stream.c +@@ -316,7 +316,9 @@ static struct snd_pcm_chmap_elem *conver + /* + * add this endpoint to the chip instance. + * if a stream with the same endpoint already exists, append to it. +- * if not, create a new pcm stream. ++ * if not, create a new pcm stream. note, fp is added to the substream ++ * fmt_list and will be freed on the chip instance release. do not free ++ * fp or do remove it from the substream fmt_list to avoid double-free. + */ + int snd_usb_add_audio_stream(struct snd_usb_audio *chip, + int stream, +@@ -677,6 +679,7 @@ int snd_usb_parse_audio_interface(struct + * (fp->maxpacksize & 0x7ff); + fp->attributes = parse_uac_endpoint_attributes(chip, alts, protocol, iface_no); + fp->clock = clock; ++ INIT_LIST_HEAD(&fp->list); + + /* some quirks for attributes here */ + +@@ -725,6 +728,7 @@ int snd_usb_parse_audio_interface(struct + dev_dbg(&dev->dev, "%u:%d: add audio endpoint %#x\n", iface_no, altno, fp->endpoint); + err = snd_usb_add_audio_stream(chip, stream, fp); + if (err < 0) { ++ list_del(&fp->list); /* unlink for avoiding double-free */ + kfree(fp->rate_table); + kfree(fp->chmap); + kfree(fp); diff --git a/queue-4.4/alsa-usb-audio-fix-null-dereference-in-create_fixed_stream_quirk.patch b/queue-4.4/alsa-usb-audio-fix-null-dereference-in-create_fixed_stream_quirk.patch new file mode 100644 index 00000000000..c0d5cc19164 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-fix-null-dereference-in-create_fixed_stream_quirk.patch @@ -0,0 +1,39 @@ +From 0f886ca12765d20124bd06291c82951fd49a33be Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 15 Mar 2016 12:09:10 +0100 +Subject: ALSA: usb-audio: Fix NULL dereference in create_fixed_stream_quirk() + +From: Takashi Iwai + +commit 0f886ca12765d20124bd06291c82951fd49a33be upstream. + +create_fixed_stream_quirk() may cause a NULL-pointer dereference by +accessing the non-existing endpoint when a USB device with a malformed +USB descriptor is used. + +This patch avoids it simply by adding a sanity check of bNumEndpoints +before the accesses. + +Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=971125 +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -180,6 +180,12 @@ static int create_fixed_stream_quirk(str + } + alts = &iface->altsetting[fp->altset_idx]; + altsd = get_iface_desc(alts); ++ if (altsd->bNumEndpoints < 1) { ++ kfree(fp); ++ kfree(rate_table); ++ return -EINVAL; ++ } ++ + fp->protocol = altsd->bInterfaceProtocol; + + if (fp->datainterval == 0) diff --git a/queue-4.4/alsa-usb-audio-minor-code-cleanup-in-create_fixed_stream_quirk.patch b/queue-4.4/alsa-usb-audio-minor-code-cleanup-in-create_fixed_stream_quirk.patch new file mode 100644 index 00000000000..04614e631c6 --- /dev/null +++ b/queue-4.4/alsa-usb-audio-minor-code-cleanup-in-create_fixed_stream_quirk.patch @@ -0,0 +1,62 @@ +From 902eb7fd1e4af3ac69b9b30f8373f118c92b9729 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 15 Mar 2016 12:14:49 +0100 +Subject: ALSA: usb-audio: Minor code cleanup in create_fixed_stream_quirk() + +From: Takashi Iwai + +commit 902eb7fd1e4af3ac69b9b30f8373f118c92b9729 upstream. + +Just a minor code cleanup: unify the error paths. + +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/usb/quirks.c | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -167,23 +167,18 @@ static int create_fixed_stream_quirk(str + stream = (fp->endpoint & USB_DIR_IN) + ? SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK; + err = snd_usb_add_audio_stream(chip, stream, fp); +- if (err < 0) { +- kfree(fp); +- kfree(rate_table); +- return err; +- } ++ if (err < 0) ++ goto error; + if (fp->iface != get_iface_desc(&iface->altsetting[0])->bInterfaceNumber || + fp->altset_idx >= iface->num_altsetting) { +- kfree(fp); +- kfree(rate_table); +- return -EINVAL; ++ err = -EINVAL; ++ goto error; + } + alts = &iface->altsetting[fp->altset_idx]; + altsd = get_iface_desc(alts); + if (altsd->bNumEndpoints < 1) { +- kfree(fp); +- kfree(rate_table); +- return -EINVAL; ++ err = -EINVAL; ++ goto error; + } + + fp->protocol = altsd->bInterfaceProtocol; +@@ -196,6 +191,11 @@ static int create_fixed_stream_quirk(str + snd_usb_init_pitch(chip, fp->iface, alts, fp); + snd_usb_init_sample_rate(chip, fp->iface, alts, fp, fp->rate_max); + return 0; ++ ++ error: ++ kfree(fp); ++ kfree(rate_table); ++ return err; + } + + static int create_auto_pcm_quirk(struct snd_usb_audio *chip, diff --git a/queue-4.4/be2iscsi-set-the-boot_kset-pointer-to-null-in-case-of-failure.patch b/queue-4.4/be2iscsi-set-the-boot_kset-pointer-to-null-in-case-of-failure.patch new file mode 100644 index 00000000000..1efbbc28b51 --- /dev/null +++ b/queue-4.4/be2iscsi-set-the-boot_kset-pointer-to-null-in-case-of-failure.patch @@ -0,0 +1,33 @@ +From 84bd64993f916bcf86270c67686ecf4cea7b8933 Mon Sep 17 00:00:00 2001 +From: Maurizio Lombardi +Date: Fri, 4 Mar 2016 10:41:49 +0100 +Subject: be2iscsi: set the boot_kset pointer to NULL in case of failure + +From: Maurizio Lombardi + +commit 84bd64993f916bcf86270c67686ecf4cea7b8933 upstream. + +In beiscsi_setup_boot_info(), the boot_kset pointer should be set to +NULL in case of failure otherwise an invalid pointer dereference may +occur later. + +Signed-off-by: Maurizio Lombardi +Reviewed-by: Johannes Thumshirn +Reviewed-by: Jitendra Bhivare +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/be2iscsi/be_main.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/scsi/be2iscsi/be_main.c ++++ b/drivers/scsi/be2iscsi/be_main.c +@@ -4470,6 +4470,7 @@ put_shost: + scsi_host_put(phba->shost); + free_kset: + iscsi_boot_destroy_kset(phba->boot_kset); ++ phba->boot_kset = NULL; + return -ENOMEM; + } + diff --git a/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-04ca-3014.patch b/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-04ca-3014.patch new file mode 100644 index 00000000000..f8b673c6dc9 --- /dev/null +++ b/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-04ca-3014.patch @@ -0,0 +1,55 @@ +From 81d90442eac779938217c3444b240aa51fd3db47 Mon Sep 17 00:00:00 2001 +From: Dmitry Tunin +Date: Sun, 28 Feb 2016 11:04:06 +0300 +Subject: Bluetooth: btusb: Add a new AR3012 ID 04ca:3014 + +From: Dmitry Tunin + +commit 81d90442eac779938217c3444b240aa51fd3db47 upstream. + +T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=03 Dev#= 5 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=04ca ProdID=3014 Rev=00.02 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +BugLink: https://bugs.launchpad.net/bugs/1546694 + +Signed-off-by: Dmitry Tunin +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/ath3k.c | 2 ++ + drivers/bluetooth/btusb.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -92,6 +92,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x04CA, 0x300d) }, + { USB_DEVICE(0x04CA, 0x300f) }, + { USB_DEVICE(0x04CA, 0x3010) }, ++ { USB_DEVICE(0x04CA, 0x3014) }, + { USB_DEVICE(0x0930, 0x0219) }, + { USB_DEVICE(0x0930, 0x021c) }, + { USB_DEVICE(0x0930, 0x0220) }, +@@ -155,6 +156,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -206,6 +206,7 @@ static const struct usb_device_id blackl + { USB_DEVICE(0x04ca, 0x300d), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x300f), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3010), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x04ca, 0x3014), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x021c), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0930, 0x0220), .driver_info = BTUSB_ATH3012 }, diff --git a/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-13d3-3472.patch b/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-13d3-3472.patch new file mode 100644 index 00000000000..d79ceb8d7c1 --- /dev/null +++ b/queue-4.4/bluetooth-btusb-add-a-new-ar3012-id-13d3-3472.patch @@ -0,0 +1,55 @@ +From 75c6aca4765dbe3d0c1507ab5052f2e373dc2331 Mon Sep 17 00:00:00 2001 +From: Dmitry Tunin +Date: Fri, 4 Mar 2016 01:32:19 +0300 +Subject: Bluetooth: btusb: Add a new AR3012 ID 13d3:3472 + +From: Dmitry Tunin + +commit 75c6aca4765dbe3d0c1507ab5052f2e373dc2331 upstream. + +T: Bus=01 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#= 4 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3472 Rev=00.01 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +BugLink: https://bugs.launchpad.net/bugs/1552925 + +Signed-off-by: Dmitry Tunin +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/ath3k.c | 2 ++ + drivers/bluetooth/btusb.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -119,6 +119,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x13d3, 0x3408) }, + { USB_DEVICE(0x13d3, 0x3423) }, + { USB_DEVICE(0x13d3, 0x3432) }, ++ { USB_DEVICE(0x13d3, 0x3472) }, + { USB_DEVICE(0x13d3, 0x3474) }, + + /* Atheros AR5BBU12 with sflash firmware */ +@@ -183,6 +184,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, + + /* Atheros AR5BBU22 with sflash firmware */ +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -233,6 +233,7 @@ static const struct usb_device_id blackl + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3432), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x13d3, 0x3472), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3474), .driver_info = BTUSB_ATH3012 }, + + /* Atheros AR5BBU12 with sflash firmware */ diff --git a/queue-4.4/bluetooth-btusb-add-new-ar3012-id-13d3-3395.patch b/queue-4.4/bluetooth-btusb-add-new-ar3012-id-13d3-3395.patch new file mode 100644 index 00000000000..fadb9d638da --- /dev/null +++ b/queue-4.4/bluetooth-btusb-add-new-ar3012-id-13d3-3395.patch @@ -0,0 +1,56 @@ +From 609574eb46335cfac1421a07c0505627cbbab1f0 Mon Sep 17 00:00:00 2001 +From: Dmitry Tunin +Date: Wed, 10 Feb 2016 15:33:17 +0300 +Subject: Bluetooth: btusb: Add new AR3012 ID 13d3:3395 + +From: Dmitry Tunin + +commit 609574eb46335cfac1421a07c0505627cbbab1f0 upstream. + +T: Bus=03 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 +D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3395 Rev=00.01 +C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA +I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb + +BugLink: https://bugs.launchpad.net/bugs/1542564 + +Reported-and-tested-by: Christopher Simerly +Signed-off-by: Dmitry Tunin +Signed-off-by: Marcel Holtmann +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/bluetooth/ath3k.c | 2 ++ + drivers/bluetooth/btusb.c | 1 + + 2 files changed, 3 insertions(+) + +--- a/drivers/bluetooth/ath3k.c ++++ b/drivers/bluetooth/ath3k.c +@@ -113,6 +113,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x13d3, 0x3362) }, + { USB_DEVICE(0x13d3, 0x3375) }, + { USB_DEVICE(0x13d3, 0x3393) }, ++ { USB_DEVICE(0x13d3, 0x3395) }, + { USB_DEVICE(0x13d3, 0x3402) }, + { USB_DEVICE(0x13d3, 0x3408) }, + { USB_DEVICE(0x13d3, 0x3423) }, +@@ -175,6 +176,7 @@ static const struct usb_device_id ath3k_ + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -227,6 +227,7 @@ static const struct usb_device_id blackl + { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 }, ++ { USB_DEVICE(0x13d3, 0x3395), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3402), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3408), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x13d3, 0x3423), .driver_info = BTUSB_ATH3012 }, diff --git a/queue-4.4/dm-cache-make-sure-every-metadata-function-checks-fail_io.patch b/queue-4.4/dm-cache-make-sure-every-metadata-function-checks-fail_io.patch new file mode 100644 index 00000000000..697f004ae96 --- /dev/null +++ b/queue-4.4/dm-cache-make-sure-every-metadata-function-checks-fail_io.patch @@ -0,0 +1,282 @@ +From d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Thu, 10 Mar 2016 16:20:58 +0000 +Subject: dm cache: make sure every metadata function checks fail_io + +From: Joe Thornber + +commit d14fcf3dd79c0b8a8d0ba469c44a6b04f3a1403b upstream. + +Otherwise operations may be attempted that will only ever go on to crash +(since the metadata device is either missing or unreliable if 'fail_io' +is set). + +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-cache-metadata.c | 98 ++++++++++++++++++++++++----------------- + drivers/md/dm-cache-metadata.h | 4 - + drivers/md/dm-cache-target.c | 12 ++++- + 3 files changed, 71 insertions(+), 43 deletions(-) + +--- a/drivers/md/dm-cache-metadata.c ++++ b/drivers/md/dm-cache-metadata.c +@@ -867,19 +867,40 @@ static int blocks_are_unmapped_or_clean( + return 0; + } + +-#define WRITE_LOCK(cmd) \ +- if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ ++#define WRITE_LOCK(cmd) \ ++ down_write(&cmd->root_lock); \ ++ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ ++ up_write(&cmd->root_lock); \ + return -EINVAL; \ +- down_write(&cmd->root_lock) ++ } + + #define WRITE_LOCK_VOID(cmd) \ +- if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) \ ++ down_write(&cmd->root_lock); \ ++ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ ++ up_write(&cmd->root_lock); \ + return; \ +- down_write(&cmd->root_lock) ++ } + + #define WRITE_UNLOCK(cmd) \ + up_write(&cmd->root_lock) + ++#define READ_LOCK(cmd) \ ++ down_read(&cmd->root_lock); \ ++ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ ++ up_read(&cmd->root_lock); \ ++ return -EINVAL; \ ++ } ++ ++#define READ_LOCK_VOID(cmd) \ ++ down_read(&cmd->root_lock); \ ++ if (cmd->fail_io || dm_bm_is_read_only(cmd->bm)) { \ ++ up_read(&cmd->root_lock); \ ++ return; \ ++ } ++ ++#define READ_UNLOCK(cmd) \ ++ up_read(&cmd->root_lock) ++ + int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size) + { + int r; +@@ -1015,22 +1036,20 @@ int dm_cache_load_discards(struct dm_cac + { + int r; + +- down_read(&cmd->root_lock); ++ READ_LOCK(cmd); + r = __load_discards(cmd, fn, context); +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + + return r; + } + +-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd) ++int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result) + { +- dm_cblock_t r; ++ READ_LOCK(cmd); ++ *result = cmd->cache_blocks; ++ READ_UNLOCK(cmd); + +- down_read(&cmd->root_lock); +- r = cmd->cache_blocks; +- up_read(&cmd->root_lock); +- +- return r; ++ return 0; + } + + static int __remove(struct dm_cache_metadata *cmd, dm_cblock_t cblock) +@@ -1188,9 +1207,9 @@ int dm_cache_load_mappings(struct dm_cac + { + int r; + +- down_read(&cmd->root_lock); ++ READ_LOCK(cmd); + r = __load_mappings(cmd, policy, fn, context); +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + + return r; + } +@@ -1215,18 +1234,18 @@ static int __dump_mappings(struct dm_cac + + void dm_cache_dump(struct dm_cache_metadata *cmd) + { +- down_read(&cmd->root_lock); ++ READ_LOCK_VOID(cmd); + __dump_mappings(cmd); +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + } + + int dm_cache_changed_this_transaction(struct dm_cache_metadata *cmd) + { + int r; + +- down_read(&cmd->root_lock); ++ READ_LOCK(cmd); + r = cmd->changed; +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + + return r; + } +@@ -1276,9 +1295,9 @@ int dm_cache_set_dirty(struct dm_cache_m + void dm_cache_metadata_get_stats(struct dm_cache_metadata *cmd, + struct dm_cache_statistics *stats) + { +- down_read(&cmd->root_lock); ++ READ_LOCK_VOID(cmd); + *stats = cmd->stats; +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + } + + void dm_cache_metadata_set_stats(struct dm_cache_metadata *cmd, +@@ -1312,9 +1331,9 @@ int dm_cache_get_free_metadata_block_cou + { + int r = -EINVAL; + +- down_read(&cmd->root_lock); ++ READ_LOCK(cmd); + r = dm_sm_get_nr_free(cmd->metadata_sm, result); +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + + return r; + } +@@ -1324,9 +1343,9 @@ int dm_cache_get_metadata_dev_size(struc + { + int r = -EINVAL; + +- down_read(&cmd->root_lock); ++ READ_LOCK(cmd); + r = dm_sm_get_nr_blocks(cmd->metadata_sm, result); +- up_read(&cmd->root_lock); ++ READ_UNLOCK(cmd); + + return r; + } +@@ -1417,7 +1436,13 @@ int dm_cache_write_hints(struct dm_cache + + int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result) + { +- return blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result); ++ int r; ++ ++ READ_LOCK(cmd); ++ r = blocks_are_unmapped_or_clean(cmd, 0, cmd->cache_blocks, result); ++ READ_UNLOCK(cmd); ++ ++ return r; + } + + void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd) +@@ -1440,10 +1465,7 @@ int dm_cache_metadata_set_needs_check(st + struct dm_block *sblock; + struct cache_disk_superblock *disk_super; + +- /* +- * We ignore fail_io for this function. +- */ +- down_write(&cmd->root_lock); ++ WRITE_LOCK(cmd); + set_bit(NEEDS_CHECK, &cmd->flags); + + r = superblock_lock(cmd, &sblock); +@@ -1458,19 +1480,17 @@ int dm_cache_metadata_set_needs_check(st + dm_bm_unlock(sblock); + + out: +- up_write(&cmd->root_lock); ++ WRITE_UNLOCK(cmd); + return r; + } + +-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd) ++int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result) + { +- bool needs_check; ++ READ_LOCK(cmd); ++ *result = !!test_bit(NEEDS_CHECK, &cmd->flags); ++ READ_UNLOCK(cmd); + +- down_read(&cmd->root_lock); +- needs_check = !!test_bit(NEEDS_CHECK, &cmd->flags); +- up_read(&cmd->root_lock); +- +- return needs_check; ++ return 0; + } + + int dm_cache_metadata_abort(struct dm_cache_metadata *cmd) +--- a/drivers/md/dm-cache-metadata.h ++++ b/drivers/md/dm-cache-metadata.h +@@ -66,7 +66,7 @@ void dm_cache_metadata_close(struct dm_c + * origin blocks to map to. + */ + int dm_cache_resize(struct dm_cache_metadata *cmd, dm_cblock_t new_cache_size); +-dm_cblock_t dm_cache_size(struct dm_cache_metadata *cmd); ++int dm_cache_size(struct dm_cache_metadata *cmd, dm_cblock_t *result); + + int dm_cache_discard_bitset_resize(struct dm_cache_metadata *cmd, + sector_t discard_block_size, +@@ -137,7 +137,7 @@ int dm_cache_write_hints(struct dm_cache + */ + int dm_cache_metadata_all_clean(struct dm_cache_metadata *cmd, bool *result); + +-bool dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd); ++int dm_cache_metadata_needs_check(struct dm_cache_metadata *cmd, bool *result); + int dm_cache_metadata_set_needs_check(struct dm_cache_metadata *cmd); + void dm_cache_metadata_set_read_only(struct dm_cache_metadata *cmd); + void dm_cache_metadata_set_read_write(struct dm_cache_metadata *cmd); +--- a/drivers/md/dm-cache-target.c ++++ b/drivers/md/dm-cache-target.c +@@ -987,9 +987,14 @@ static void notify_mode_switch(struct ca + + static void set_cache_mode(struct cache *cache, enum cache_metadata_mode new_mode) + { +- bool needs_check = dm_cache_metadata_needs_check(cache->cmd); ++ bool needs_check; + enum cache_metadata_mode old_mode = get_cache_mode(cache); + ++ if (dm_cache_metadata_needs_check(cache->cmd, &needs_check)) { ++ DMERR("unable to read needs_check flag, setting failure mode"); ++ new_mode = CM_FAIL; ++ } ++ + if (new_mode == CM_WRITE && needs_check) { + DMERR("%s: unable to switch cache to write mode until repaired.", + cache_device_name(cache)); +@@ -3513,6 +3518,7 @@ static void cache_status(struct dm_targe + char buf[BDEVNAME_SIZE]; + struct cache *cache = ti->private; + dm_cblock_t residency; ++ bool needs_check; + + switch (type) { + case STATUSTYPE_INFO: +@@ -3586,7 +3592,9 @@ static void cache_status(struct dm_targe + else + DMEMIT("rw "); + +- if (dm_cache_metadata_needs_check(cache->cmd)) ++ r = dm_cache_metadata_needs_check(cache->cmd, &needs_check); ++ ++ if (r || needs_check) + DMEMIT("needs_check "); + else + DMEMIT("- "); diff --git a/queue-4.4/dm-fix-excessive-dm-mq-context-switching.patch b/queue-4.4/dm-fix-excessive-dm-mq-context-switching.patch new file mode 100644 index 00000000000..081b5e868d9 --- /dev/null +++ b/queue-4.4/dm-fix-excessive-dm-mq-context-switching.patch @@ -0,0 +1,116 @@ +From 6acfe68bac7e6f16dc312157b1fa6e2368985013 Mon Sep 17 00:00:00 2001 +From: Mike Snitzer +Date: Fri, 5 Feb 2016 08:49:01 -0500 +Subject: dm: fix excessive dm-mq context switching + +From: Mike Snitzer + +commit 6acfe68bac7e6f16dc312157b1fa6e2368985013 upstream. + +Request-based DM's blk-mq support (dm-mq) was reported to be 50% slower +than if an underlying null_blk device were used directly. One of the +reasons for this drop in performance is that blk_insert_clone_request() +was calling blk_mq_insert_request() with @async=true. This forced the +use of kblockd_schedule_delayed_work_on() to run the blk-mq hw queues +which ushered in ping-ponging between process context (fio in this case) +and kblockd's kworker to submit the cloned request. The ftrace +function_graph tracer showed: + + kworker-2013 => fio-12190 + fio-12190 => kworker-2013 + ... + kworker-2013 => fio-12190 + fio-12190 => kworker-2013 + ... + +Fixing blk_insert_clone_request()'s blk_mq_insert_request() call to +_not_ use kblockd to submit the cloned requests isn't enough to +eliminate the observed context switches. + +In addition to this dm-mq specific blk-core fix, there are 2 DM core +fixes to dm-mq that (when paired with the blk-core fix) completely +eliminate the observed context switching: + +1) don't blk_mq_run_hw_queues in blk-mq request completion + + Motivated by desire to reduce overhead of dm-mq, punting to kblockd + just increases context switches. + + In my testing against a really fast null_blk device there was no benefit + to running blk_mq_run_hw_queues() on completion (and no other blk-mq + driver does this). So hopefully this change doesn't induce the need for + yet another revert like commit 621739b00e16ca2d ! + +2) use blk_mq_complete_request() in dm_complete_request() + + blk_complete_request() doesn't offer the traditional q->mq_ops vs + .request_fn branching pattern that other historic block interfaces + do (e.g. blk_get_request). Using blk_mq_complete_request() for + blk-mq requests is important for performance. It should be noted + that, like blk_complete_request(), blk_mq_complete_request() doesn't + natively handle partial completions -- but the request-based + DM-multipath target does provide the required partial completion + support by dm.c:end_clone_bio() triggering requeueing of the request + via dm-mpath.c:multipath_end_io()'s return of DM_ENDIO_REQUEUE. + +dm-mq fix #2 is _much_ more important than #1 for eliminating the +context switches. +Before: cpu : usr=15.10%, sys=59.39%, ctx=7905181, majf=0, minf=475 +After: cpu : usr=20.60%, sys=79.35%, ctx=2008, majf=0, minf=472 + +With these changes multithreaded async read IOPs improved from ~950K +to ~1350K for this dm-mq stacked on null_blk test-case. The raw read +IOPs of the underlying null_blk device for the same workload is ~1950K. + +Fixes: 7fb4898e0 ("block: add blk-mq support to blk_insert_cloned_request()") +Fixes: bfebd1cdb ("dm: add full blk-mq support to request-based DM") +Reported-by: Sagi Grimberg +Signed-off-by: Mike Snitzer +Acked-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/blk-core.c | 2 +- + drivers/md/dm.c | 13 ++++++------- + 2 files changed, 7 insertions(+), 8 deletions(-) + +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -2189,7 +2189,7 @@ int blk_insert_cloned_request(struct req + if (q->mq_ops) { + if (blk_queue_io_stat(q)) + blk_account_io_start(rq, true); +- blk_mq_insert_request(rq, false, true, true); ++ blk_mq_insert_request(rq, false, true, false); + return 0; + } + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1109,12 +1109,8 @@ static void rq_completed(struct mapped_d + * back into ->request_fn() could deadlock attempting to grab the + * queue lock again. + */ +- if (run_queue) { +- if (md->queue->mq_ops) +- blk_mq_run_hw_queues(md->queue, true); +- else +- blk_run_queue_async(md->queue); +- } ++ if (!md->queue->mq_ops && run_queue) ++ blk_run_queue_async(md->queue); + + /* + * dm_put() must be at the end of this function. See the comment above +@@ -1336,7 +1332,10 @@ static void dm_complete_request(struct r + struct dm_rq_target_io *tio = tio_from_request(rq); + + tio->error = error; +- blk_complete_request(rq); ++ if (!rq->q->mq_ops) ++ blk_complete_request(rq); ++ else ++ blk_mq_complete_request(rq, error); + } + + /* diff --git a/queue-4.4/dm-fix-rq_end_stats-null-pointer-in-dm_requeue_original_request.patch b/queue-4.4/dm-fix-rq_end_stats-null-pointer-in-dm_requeue_original_request.patch new file mode 100644 index 00000000000..92f8b139ce9 --- /dev/null +++ b/queue-4.4/dm-fix-rq_end_stats-null-pointer-in-dm_requeue_original_request.patch @@ -0,0 +1,41 @@ +From 98dbc9c6c61698792e3a66f32f3bf066201d42d7 Mon Sep 17 00:00:00 2001 +From: "Bryn M. Reeves" +Date: Mon, 14 Mar 2016 17:04:34 -0400 +Subject: dm: fix rq_end_stats() NULL pointer in dm_requeue_original_request() + +From: Bryn M. Reeves + +commit 98dbc9c6c61698792e3a66f32f3bf066201d42d7 upstream. + +An "old" (.request_fn) DM 'struct request' stores a pointer to the +associated 'struct dm_rq_target_io' in rq->special. + +dm_requeue_original_request(), previously named +dm_requeue_unmapped_original_request(), called dm_unprep_request() to +reset rq->special to NULL. But rq_end_stats() would go on to hit a NULL +pointer deference because its call to tio_from_request() returned NULL. + +Fix this by calling rq_end_stats() _before_ dm_unprep_request() + +Signed-off-by: Bryn M. Reeves +Signed-off-by: Mike Snitzer +Fixes: e262f34741 ("dm stats: add support for request-based DM devices") +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/md/dm.c ++++ b/drivers/md/dm.c +@@ -1210,9 +1210,9 @@ static void dm_requeue_original_request( + { + int rw = rq_data_dir(rq); + ++ rq_end_stats(md, rq); + dm_unprep_request(rq); + +- rq_end_stats(md, rq); + if (!rq->q->mq_ops) + old_requeue_request(rq); + else { diff --git a/queue-4.4/dm-snapshot-disallow-the-cow-and-origin-devices-from-being-identical.patch b/queue-4.4/dm-snapshot-disallow-the-cow-and-origin-devices-from-being-identical.patch new file mode 100644 index 00000000000..afd053b0877 --- /dev/null +++ b/queue-4.4/dm-snapshot-disallow-the-cow-and-origin-devices-from-being-identical.patch @@ -0,0 +1,168 @@ +From 4df2bf466a9c9c92f40d27c4aa9120f4e8227bfc Mon Sep 17 00:00:00 2001 +From: DingXiang +Date: Tue, 2 Feb 2016 12:29:18 +0800 +Subject: dm snapshot: disallow the COW and origin devices from being identical + +From: DingXiang + +commit 4df2bf466a9c9c92f40d27c4aa9120f4e8227bfc upstream. + +Otherwise loading a "snapshot" table using the same device for the +origin and COW devices, e.g.: + +echo "0 20971520 snapshot 253:3 253:3 P 8" | dmsetup create snap + +will trigger: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000098 +[ 1958.979934] IP: [] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot] +[ 1958.989655] PGD 0 +[ 1958.991903] Oops: 0000 [#1] SMP +... +[ 1959.059647] CPU: 9 PID: 3556 Comm: dmsetup Tainted: G IO 4.5.0-rc5.snitm+ #150 +... +[ 1959.083517] task: ffff8800b9660c80 ti: ffff88032a954000 task.ti: ffff88032a954000 +[ 1959.091865] RIP: 0010:[] [] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot] +[ 1959.104295] RSP: 0018:ffff88032a957b30 EFLAGS: 00010246 +[ 1959.110219] RAX: 0000000000000000 RBX: 0000000000000008 RCX: 0000000000000001 +[ 1959.118180] RDX: 0000000000000000 RSI: 0000000000000008 RDI: ffff880329334a00 +[ 1959.126141] RBP: ffff88032a957b50 R08: 0000000000000000 R09: 0000000000000001 +[ 1959.134102] R10: 000000000000000a R11: f000000000000000 R12: ffff880330884d80 +[ 1959.142061] R13: 0000000000000008 R14: ffffc90001c13088 R15: ffff880330884d80 +[ 1959.150021] FS: 00007f8926ba3840(0000) GS:ffff880333440000(0000) knlGS:0000000000000000 +[ 1959.159047] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[ 1959.165456] CR2: 0000000000000098 CR3: 000000032f48b000 CR4: 00000000000006e0 +[ 1959.173415] Stack: +[ 1959.175656] ffffc90001c13040 ffff880329334a00 ffff880330884ed0 ffff88032a957bdc +[ 1959.183946] ffff88032a957bb8 ffffffffa040f225 ffff880329334a30 ffff880300000000 +[ 1959.192233] ffffffffa04133e0 ffff880329334b30 0000000830884d58 00000000569c58cf +[ 1959.200521] Call Trace: +[ 1959.203248] [] dm_exception_store_create+0x1d5/0x240 [dm_snapshot] +[ 1959.211986] [] snapshot_ctr+0x140/0x630 [dm_snapshot] +[ 1959.219469] [] ? dm_split_args+0x64/0x150 [dm_mod] +[ 1959.226656] [] dm_table_add_target+0x177/0x440 [dm_mod] +[ 1959.234328] [] table_load+0x143/0x370 [dm_mod] +[ 1959.241129] [] ? retrieve_status+0x1b0/0x1b0 [dm_mod] +[ 1959.248607] [] ctl_ioctl+0x255/0x4d0 [dm_mod] +[ 1959.255307] [] ? memzero_explicit+0x12/0x20 +[ 1959.261816] [] dm_ctl_ioctl+0x13/0x20 [dm_mod] +[ 1959.268615] [] do_vfs_ioctl+0xa6/0x5c0 +[ 1959.274637] [] ? __audit_syscall_entry+0xaf/0x100 +[ 1959.281726] [] ? do_audit_syscall_entry+0x66/0x70 +[ 1959.288814] [] SyS_ioctl+0x79/0x90 +[ 1959.294450] [] entry_SYSCALL_64_fastpath+0x12/0x71 +... +[ 1959.323277] RIP [] dm_exception_store_set_chunk_size+0x7a/0x110 [dm_snapshot] +[ 1959.333090] RSP +[ 1959.336978] CR2: 0000000000000098 +[ 1959.344121] ---[ end trace b049991ccad1169e ]--- + +Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1195899 +Signed-off-by: Ding Xiang +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-snap.c | 9 +++++++++ + drivers/md/dm-table.c | 36 ++++++++++++++++++++++++------------ + include/linux/device-mapper.h | 2 ++ + 3 files changed, 35 insertions(+), 12 deletions(-) + +--- a/drivers/md/dm-snap.c ++++ b/drivers/md/dm-snap.c +@@ -1106,6 +1106,7 @@ static int snapshot_ctr(struct dm_target + int i; + int r = -EINVAL; + char *origin_path, *cow_path; ++ dev_t origin_dev, cow_dev; + unsigned args_used, num_flush_bios = 1; + fmode_t origin_mode = FMODE_READ; + +@@ -1136,11 +1137,19 @@ static int snapshot_ctr(struct dm_target + ti->error = "Cannot get origin device"; + goto bad_origin; + } ++ origin_dev = s->origin->bdev->bd_dev; + + cow_path = argv[0]; + argv++; + argc--; + ++ cow_dev = dm_get_dev_t(cow_path); ++ if (cow_dev && cow_dev == origin_dev) { ++ ti->error = "COW device cannot be the same as origin device"; ++ r = -EINVAL; ++ goto bad_cow; ++ } ++ + r = dm_get_device(ti, cow_path, dm_table_get_mode(ti->table), &s->cow); + if (r) { + ti->error = "Cannot get COW device"; +--- a/drivers/md/dm-table.c ++++ b/drivers/md/dm-table.c +@@ -365,6 +365,26 @@ static int upgrade_mode(struct dm_dev_in + } + + /* ++ * Convert the path to a device ++ */ ++dev_t dm_get_dev_t(const char *path) ++{ ++ dev_t uninitialized_var(dev); ++ struct block_device *bdev; ++ ++ bdev = lookup_bdev(path); ++ if (IS_ERR(bdev)) ++ dev = name_to_dev_t(path); ++ else { ++ dev = bdev->bd_dev; ++ bdput(bdev); ++ } ++ ++ return dev; ++} ++EXPORT_SYMBOL_GPL(dm_get_dev_t); ++ ++/* + * Add a device to the list, or just increment the usage count if + * it's already present. + */ +@@ -372,23 +392,15 @@ int dm_get_device(struct dm_target *ti, + struct dm_dev **result) + { + int r; +- dev_t uninitialized_var(dev); ++ dev_t dev; + struct dm_dev_internal *dd; + struct dm_table *t = ti->table; +- struct block_device *bdev; + + BUG_ON(!t); + +- /* convert the path to a device */ +- bdev = lookup_bdev(path); +- if (IS_ERR(bdev)) { +- dev = name_to_dev_t(path); +- if (!dev) +- return -ENODEV; +- } else { +- dev = bdev->bd_dev; +- bdput(bdev); +- } ++ dev = dm_get_dev_t(path); ++ if (!dev) ++ return -ENODEV; + + dd = find_device(&t->devices, dev); + if (!dd) { +--- a/include/linux/device-mapper.h ++++ b/include/linux/device-mapper.h +@@ -124,6 +124,8 @@ struct dm_dev { + char name[16]; + }; + ++dev_t dm_get_dev_t(const char *path); ++ + /* + * Constructors should call these functions to ensure destination devices + * are opened/closed correctly. diff --git a/queue-4.4/dm-thin-metadata-don-t-issue-prefetches-if-a-transaction-abort-has-failed.patch b/queue-4.4/dm-thin-metadata-don-t-issue-prefetches-if-a-transaction-abort-has-failed.patch new file mode 100644 index 00000000000..4911d319434 --- /dev/null +++ b/queue-4.4/dm-thin-metadata-don-t-issue-prefetches-if-a-transaction-abort-has-failed.patch @@ -0,0 +1,35 @@ +From 2eae9e4489b4cf83213fa3bd508b5afca3f01780 Mon Sep 17 00:00:00 2001 +From: Joe Thornber +Date: Tue, 1 Mar 2016 10:58:44 +0000 +Subject: dm thin metadata: don't issue prefetches if a transaction abort has failed + +From: Joe Thornber + +commit 2eae9e4489b4cf83213fa3bd508b5afca3f01780 upstream. + +If a transaction abort has failed then we can no longer use the metadata +device. Typically this happens if the superblock is unreadable. + +This fix addresses a crash seen during metadata device failure testing. + +Fixes: 8a01a6af75 ("dm thin: prefetch missing metadata pages") +Signed-off-by: Joe Thornber +Signed-off-by: Mike Snitzer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/dm-thin-metadata.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/md/dm-thin-metadata.c ++++ b/drivers/md/dm-thin-metadata.c +@@ -1943,5 +1943,8 @@ bool dm_pool_metadata_needs_check(struct + + void dm_pool_issue_prefetches(struct dm_pool_metadata *pmd) + { +- dm_tm_issue_prefetches(pmd->tm); ++ down_read(&pmd->root_lock); ++ if (!pmd->fail_io) ++ dm_tm_issue_prefetches(pmd->tm); ++ up_read(&pmd->root_lock); + } diff --git a/queue-4.4/input-powermate-fix-oops-with-malicious-usb-descriptors.patch b/queue-4.4/input-powermate-fix-oops-with-malicious-usb-descriptors.patch new file mode 100644 index 00000000000..c798e8f9ede --- /dev/null +++ b/queue-4.4/input-powermate-fix-oops-with-malicious-usb-descriptors.patch @@ -0,0 +1,38 @@ +From 9c6ba456711687b794dcf285856fc14e2c76074f Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Mon, 14 Mar 2016 09:33:40 -0700 +Subject: Input: powermate - fix oops with malicious USB descriptors + +From: Josh Boyer + +commit 9c6ba456711687b794dcf285856fc14e2c76074f upstream. + +The powermate driver expects at least one valid USB endpoint in its +probe function. If given malicious descriptors that specify 0 for +the number of endpoints, it will crash. Validate the number of +endpoints on the interface before using them. + +The full report for this issue can be found here: +http://seclists.org/bugtraq/2016/Mar/85 + +Reported-by: Ralf Spenneberg +Signed-off-by: Josh Boyer +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/misc/powermate.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/input/misc/powermate.c ++++ b/drivers/input/misc/powermate.c +@@ -307,6 +307,9 @@ static int powermate_probe(struct usb_in + int error = -ENOMEM; + + interface = intf->cur_altsetting; ++ if (interface->desc.bNumEndpoints < 1) ++ return -EINVAL; ++ + endpoint = &interface->endpoint[0].desc; + if (!usb_endpoint_is_int_in(endpoint)) + return -EIO; diff --git a/queue-4.4/libnvdimm-fix-security-issue-with-dsm-ioctl.patch b/queue-4.4/libnvdimm-fix-security-issue-with-dsm-ioctl.patch new file mode 100644 index 00000000000..bedd7021f2a --- /dev/null +++ b/queue-4.4/libnvdimm-fix-security-issue-with-dsm-ioctl.patch @@ -0,0 +1,41 @@ +From 07accfa9d1a8bac8262f6d24a94a54d2d1f35149 Mon Sep 17 00:00:00 2001 +From: Jerry Hoemann +Date: Wed, 6 Jan 2016 16:03:41 -0700 +Subject: libnvdimm: Fix security issue with DSM IOCTL. + +From: Jerry Hoemann + +commit 07accfa9d1a8bac8262f6d24a94a54d2d1f35149 upstream. + +Code attempts to prevent certain IOCTL DSM from being called +when device is opened read only. This security feature can +be trivially overcome by changing the size portion of the +ioctl_command which isn't used. + +Check only the _IOC_NR (i.e. the command). + +Signed-off-by: Jerry Hoemann +Signed-off-by: Dan Williams +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/nvdimm/bus.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/nvdimm/bus.c ++++ b/drivers/nvdimm/bus.c +@@ -513,10 +513,10 @@ static int __nd_ioctl(struct nvdimm_bus + + /* fail write commands (when read-only) */ + if (read_only) +- switch (ioctl_cmd) { +- case ND_IOCTL_VENDOR: +- case ND_IOCTL_SET_CONFIG_DATA: +- case ND_IOCTL_ARS_START: ++ switch (cmd) { ++ case ND_CMD_VENDOR: ++ case ND_CMD_SET_CONFIG_DATA: ++ case ND_CMD_ARS_START: + dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n", + nvdimm ? nvdimm_cmd_name(cmd) + : nvdimm_bus_cmd_name(cmd)); diff --git a/queue-4.4/pwc-add-usb-id-for-philips-spc880nc-webcam.patch b/queue-4.4/pwc-add-usb-id-for-philips-spc880nc-webcam.patch new file mode 100644 index 00000000000..6cc94373234 --- /dev/null +++ b/queue-4.4/pwc-add-usb-id-for-philips-spc880nc-webcam.patch @@ -0,0 +1,43 @@ +From 7445e45d19a09e5269dc85f17f9635be29d2f76c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 22 Jan 2016 08:53:55 -0200 +Subject: [media] pwc: Add USB id for Philips Spc880nc webcam + +From: Hans de Goede + +commit 7445e45d19a09e5269dc85f17f9635be29d2f76c upstream. + +SPC 880NC PC camera discussions: + http://www.pclinuxos.com/forum/index.php/topic,135688.0.html + +Reported-by: Kikim +Signed-off-by: Hans de Goede +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/usb/pwc/pwc-if.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/media/usb/pwc/pwc-if.c ++++ b/drivers/media/usb/pwc/pwc-if.c +@@ -91,6 +91,7 @@ static const struct usb_device_id pwc_de + { USB_DEVICE(0x0471, 0x0312) }, + { USB_DEVICE(0x0471, 0x0313) }, /* the 'new' 720K */ + { USB_DEVICE(0x0471, 0x0329) }, /* Philips SPC 900NC PC Camera */ ++ { USB_DEVICE(0x0471, 0x032C) }, /* Philips SPC 880NC PC Camera */ + { USB_DEVICE(0x069A, 0x0001) }, /* Askey */ + { USB_DEVICE(0x046D, 0x08B0) }, /* Logitech QuickCam Pro 3000 */ + { USB_DEVICE(0x046D, 0x08B1) }, /* Logitech QuickCam Notebook Pro */ +@@ -811,6 +812,11 @@ static int usb_pwc_probe(struct usb_inte + name = "Philips SPC 900NC webcam"; + type_id = 740; + break; ++ case 0x032C: ++ PWC_INFO("Philips SPC 880NC USB webcam detected.\n"); ++ name = "Philips SPC 880NC webcam"; ++ type_id = 740; ++ break; + default: + return -ENODEV; + break; diff --git a/queue-4.4/scsi-storvsc-fix-srb_status_aborted-handling.patch b/queue-4.4/scsi-storvsc-fix-srb_status_aborted-handling.patch new file mode 100644 index 00000000000..57c8dd049c6 --- /dev/null +++ b/queue-4.4/scsi-storvsc-fix-srb_status_aborted-handling.patch @@ -0,0 +1,39 @@ +From ff06c5ffbcb4ffa542fb80c897be977956fafecc Mon Sep 17 00:00:00 2001 +From: Vitaly Kuznetsov +Date: Mon, 7 Mar 2016 11:59:44 +0100 +Subject: scsi: storvsc: fix SRB_STATUS_ABORTED handling + +From: Vitaly Kuznetsov + +commit ff06c5ffbcb4ffa542fb80c897be977956fafecc upstream. + +Commit 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB +status flags") filtered SRB_STATUS_AUTOSENSE_VALID out effectively making +the (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID) case a dead code. The +logic from this branch (e.g. storvsc_device_scan() call) is still required, +fix the check. + +Fixes: 3209f9d780d1 ("scsi: storvsc: Fix a bug in the handling of SRB status flags") +Signed-off-by: Vitaly Kuznetsov +Acked-by: K. Y. Srinivasan +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/storvsc_drv.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -889,8 +889,9 @@ static void storvsc_handle_error(struct + do_work = true; + process_err_fn = storvsc_remove_lun; + break; +- case (SRB_STATUS_ABORTED | SRB_STATUS_AUTOSENSE_VALID): +- if ((asc == 0x2a) && (ascq == 0x9)) { ++ case SRB_STATUS_ABORTED: ++ if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID && ++ (asc == 0x2a) && (ascq == 0x9)) { + do_work = true; + process_err_fn = storvsc_device_scan; + /* diff --git a/queue-4.4/sd-fix-discard-granularity-when-lbprz-1.patch b/queue-4.4/sd-fix-discard-granularity-when-lbprz-1.patch new file mode 100644 index 00000000000..953cb055ee9 --- /dev/null +++ b/queue-4.4/sd-fix-discard-granularity-when-lbprz-1.patch @@ -0,0 +1,36 @@ +From 6540a65da90c09590897310e31993b1f6e28485a Mon Sep 17 00:00:00 2001 +From: "Martin K. Petersen" +Date: Sat, 5 Mar 2016 17:52:02 -0500 +Subject: sd: Fix discard granularity when LBPRZ=1 + +From: Martin K. Petersen + +commit 6540a65da90c09590897310e31993b1f6e28485a upstream. + +Commit 397737223c59 ("sd: Make discard granularity match logical block +size when LBPRZ=1") accidentally set the granularity to one byte instead +of one logical block on devices that provide deterministic zeroes after +UNMAP. + +Signed-off-by: Martin K. Petersen +Reported-by: Mike Snitzer +Reviewed-by: Ewan Milne +Reviewed-by: Bart Van Assche +Fixes: 397737223c59e89dca7305feb6528caef8fbef84 +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/sd.c ++++ b/drivers/scsi/sd.c +@@ -648,7 +648,7 @@ static void sd_config_discard(struct scs + */ + if (sdkp->lbprz) { + q->limits.discard_alignment = 0; +- q->limits.discard_granularity = 1; ++ q->limits.discard_granularity = logical_block_size; + } else { + q->limits.discard_alignment = sdkp->unmap_alignment * + logical_block_size; diff --git a/queue-4.4/series b/queue-4.4/series index c6f967bb0e0..7777d24df47 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -35,3 +35,39 @@ x86-apic-fix-suspicious-rcu-usage-in-smp_trace_call_function_interrupt.patch x86-iopl-64-properly-context-switch-iopl-on-xen-pv.patch x86-iopl-fix-iopl-capability-check-on-xen-pv.patch x86-mm-tlb_remote_send_ipi-should-count-pages.patch +sg-fix-dxferp-in-from_to-case.patch +aacraid-fix-rrq-overload.patch +aacraid-fix-memory-leak-in-aac_fib_map_free.patch +aacraid-set-correct-msix-count-for-eeh-recovery.patch +sd-fix-discard-granularity-when-lbprz-1.patch +scsi-storvsc-fix-srb_status_aborted-handling.patch +be2iscsi-set-the-boot_kset-pointer-to-null-in-case-of-failure.patch +aic7xxx-fix-queue-depth-handling.patch +libnvdimm-fix-security-issue-with-dsm-ioctl.patch +dm-snapshot-disallow-the-cow-and-origin-devices-from-being-identical.patch +dm-fix-excessive-dm-mq-context-switching.patch +dm-thin-metadata-don-t-issue-prefetches-if-a-transaction-abort-has-failed.patch +dm-cache-make-sure-every-metadata-function-checks-fail_io.patch +dm-fix-rq_end_stats-null-pointer-in-dm_requeue_original_request.patch +usb-retry-reset-if-a-device-times-out.patch +usb-hub-fix-a-typo-in-hub_port_init-leading-to-wrong-logic.patch +usb-uas-reduce-can_queue-to-max_cmnds.patch +usb-cdc-acm-more-sanity-checking.patch +usb-iowarrior-fix-oops-with-malicious-usb-descriptors.patch +usb-usb_driver_claim_interface-add-sanity-checking.patch +usb-mct_u232-add-sanity-checking-in-probe.patch +usb-digi_acceleport-do-sanity-checking-for-the-number-of-ports.patch +usb-cypress_m8-add-endpoint-sanity-check.patch +usb-serial-cp210x-adding-ge-healthcare-device-id.patch +usb-serial-ftdi_sio-add-support-for-icp-das-i-756xu-devices.patch +usb-option-add-d-link-dwm-221-b1-device-id.patch +pwc-add-usb-id-for-philips-spc880nc-webcam.patch +input-powermate-fix-oops-with-malicious-usb-descriptors.patch +alsa-usb-audio-fix-null-dereference-in-create_fixed_stream_quirk.patch +alsa-usb-audio-add-sanity-checks-for-endpoint-accesses.patch +alsa-usb-audio-add-microsoft-hd-5001-to-quirks.patch +alsa-usb-audio-minor-code-cleanup-in-create_fixed_stream_quirk.patch +alsa-usb-audio-fix-double-free-in-error-paths-after-snd_usb_add_audio_stream-call.patch +bluetooth-btusb-add-new-ar3012-id-13d3-3395.patch +bluetooth-btusb-add-a-new-ar3012-id-04ca-3014.patch +bluetooth-btusb-add-a-new-ar3012-id-13d3-3472.patch diff --git a/queue-4.4/sg-fix-dxferp-in-from_to-case.patch b/queue-4.4/sg-fix-dxferp-in-from_to-case.patch new file mode 100644 index 00000000000..14d5cf75f3e --- /dev/null +++ b/queue-4.4/sg-fix-dxferp-in-from_to-case.patch @@ -0,0 +1,47 @@ +From 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 Mon Sep 17 00:00:00 2001 +From: Douglas Gilbert +Date: Thu, 3 Mar 2016 00:31:29 -0500 +Subject: sg: fix dxferp in from_to case + +From: Douglas Gilbert + +commit 5ecee0a3ee8d74b6950cb41e8989b0c2174568d4 upstream. + +One of the strange things that the original sg driver did was let the +user provide both a data-out buffer (it followed the sg_header+cdb) +_and_ specify a reply length greater than zero. What happened was that +the user data-out buffer was copied into some kernel buffers and then +the mid level was told a read type operation would take place with the +data from the device overwriting the same kernel buffers. The user would +then read those kernel buffers back into the user space. + +From what I can tell, the above action was broken by commit fad7f01e61bf +("sg: set dxferp to NULL for READ with the older SG interface") in 2008 +and syzkaller found that out recently. + +Make sure that a user space pointer is passed through when data follows +the sg_header structure and command. Fix the abnormal case when a +non-zero reply_len is also given. + +Fixes: fad7f01e61bf737fe8a3740d803f000db57ecac6 +Signed-off-by: Douglas Gilbert +Reviewed-by: Ewan Milne +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sg.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -652,7 +652,8 @@ sg_write(struct file *filp, const char _ + else + hp->dxfer_direction = (mxsize > 0) ? SG_DXFER_FROM_DEV : SG_DXFER_NONE; + hp->dxfer_len = mxsize; +- if (hp->dxfer_direction == SG_DXFER_TO_DEV) ++ if ((hp->dxfer_direction == SG_DXFER_TO_DEV) || ++ (hp->dxfer_direction == SG_DXFER_TO_FROM_DEV)) + hp->dxferp = (char __user *)buf + cmd_size; + else + hp->dxferp = NULL; diff --git a/queue-4.4/usb-cdc-acm-more-sanity-checking.patch b/queue-4.4/usb-cdc-acm-more-sanity-checking.patch new file mode 100644 index 00000000000..b4379ea61bf --- /dev/null +++ b/queue-4.4/usb-cdc-acm-more-sanity-checking.patch @@ -0,0 +1,33 @@ +From 8835ba4a39cf53f705417b3b3a94eb067673f2c9 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Tue, 15 Mar 2016 10:14:04 +0100 +Subject: USB: cdc-acm: more sanity checking + +From: Oliver Neukum + +commit 8835ba4a39cf53f705417b3b3a94eb067673f2c9 upstream. + +An attack has become available which pretends to be a quirky +device circumventing normal sanity checks and crashes the kernel +by an insufficient number of interfaces. This patch adds a check +to the code path for quirky devices. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/class/cdc-acm.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/usb/class/cdc-acm.c ++++ b/drivers/usb/class/cdc-acm.c +@@ -1114,6 +1114,9 @@ static int acm_probe(struct usb_interfac + if (quirks == NO_UNION_NORMAL) { + data_interface = usb_ifnum_to_if(usb_dev, 1); + control_interface = usb_ifnum_to_if(usb_dev, 0); ++ /* we would crash */ ++ if (!data_interface || !control_interface) ++ return -ENODEV; + goto skip_normal_probe; + } + diff --git a/queue-4.4/usb-cypress_m8-add-endpoint-sanity-check.patch b/queue-4.4/usb-cypress_m8-add-endpoint-sanity-check.patch new file mode 100644 index 00000000000..5be14d8253f --- /dev/null +++ b/queue-4.4/usb-cypress_m8-add-endpoint-sanity-check.patch @@ -0,0 +1,48 @@ +From c55aee1bf0e6b6feec8b2927b43f7a09a6d5f754 Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 31 Mar 2016 12:04:25 -0400 +Subject: USB: cypress_m8: add endpoint sanity check + +From: Oliver Neukum + +commit c55aee1bf0e6b6feec8b2927b43f7a09a6d5f754 upstream. + +An attack using missing endpoints exists. + +CVE-2016-3137 + +Signed-off-by: Oliver Neukum +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cypress_m8.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/drivers/usb/serial/cypress_m8.c ++++ b/drivers/usb/serial/cypress_m8.c +@@ -447,6 +447,11 @@ static int cypress_generic_port_probe(st + struct usb_serial *serial = port->serial; + struct cypress_private *priv; + ++ if (!port->interrupt_out_urb || !port->interrupt_in_urb) { ++ dev_err(&port->dev, "required endpoint is missing\n"); ++ return -ENODEV; ++ } ++ + priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); + if (!priv) + return -ENOMEM; +@@ -606,12 +611,6 @@ static int cypress_open(struct tty_struc + cypress_set_termios(tty, port, &priv->tmp_termios); + + /* setup the port and start reading from the device */ +- if (!port->interrupt_in_urb) { +- dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n", +- __func__); +- return -1; +- } +- + usb_fill_int_urb(port->interrupt_in_urb, serial->dev, + usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress), + port->interrupt_in_urb->transfer_buffer, diff --git a/queue-4.4/usb-digi_acceleport-do-sanity-checking-for-the-number-of-ports.patch b/queue-4.4/usb-digi_acceleport-do-sanity-checking-for-the-number-of-ports.patch new file mode 100644 index 00000000000..0a96c0cd90f --- /dev/null +++ b/queue-4.4/usb-digi_acceleport-do-sanity-checking-for-the-number-of-ports.patch @@ -0,0 +1,53 @@ +From 5a07975ad0a36708c6b0a5b9fea1ff811d0b0c1f Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 31 Mar 2016 12:04:26 -0400 +Subject: USB: digi_acceleport: do sanity checking for the number of ports + +From: Oliver Neukum + +commit 5a07975ad0a36708c6b0a5b9fea1ff811d0b0c1f upstream. + +The driver can be crashed with devices that expose crafted descriptors +with too few endpoints. + +See: http://seclists.org/bugtraq/2016/Mar/61 + +Signed-off-by: Oliver Neukum +[johan: fix OOB endpoint check and add error messages ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/digi_acceleport.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +--- a/drivers/usb/serial/digi_acceleport.c ++++ b/drivers/usb/serial/digi_acceleport.c +@@ -1251,8 +1251,27 @@ static int digi_port_init(struct usb_ser + + static int digi_startup(struct usb_serial *serial) + { ++ struct device *dev = &serial->interface->dev; + struct digi_serial *serial_priv; + int ret; ++ int i; ++ ++ /* check whether the device has the expected number of endpoints */ ++ if (serial->num_port_pointers < serial->type->num_ports + 1) { ++ dev_err(dev, "OOB endpoints missing\n"); ++ return -ENODEV; ++ } ++ ++ for (i = 0; i < serial->type->num_ports + 1 ; i++) { ++ if (!serial->port[i]->read_urb) { ++ dev_err(dev, "bulk-in endpoint missing\n"); ++ return -ENODEV; ++ } ++ if (!serial->port[i]->write_urb) { ++ dev_err(dev, "bulk-out endpoint missing\n"); ++ return -ENODEV; ++ } ++ } + + serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); + if (!serial_priv) diff --git a/queue-4.4/usb-hub-fix-a-typo-in-hub_port_init-leading-to-wrong-logic.patch b/queue-4.4/usb-hub-fix-a-typo-in-hub_port_init-leading-to-wrong-logic.patch new file mode 100644 index 00000000000..6c96a53f1cf --- /dev/null +++ b/queue-4.4/usb-hub-fix-a-typo-in-hub_port_init-leading-to-wrong-logic.patch @@ -0,0 +1,66 @@ +From 0d5ce778c43bf888328231bcdce05d5c860655aa Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 17 Feb 2016 11:52:43 +0100 +Subject: usb: hub: fix a typo in hub_port_init() leading to wrong logic + +From: Oliver Neukum + +commit 0d5ce778c43bf888328231bcdce05d5c860655aa upstream. + +A typo of j for i led to a logic bug. To rule out future +confusion, the variable names are made meaningful. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4277,7 +4277,7 @@ hub_port_init(struct usb_hub *hub, struc + { + struct usb_device *hdev = hub->hdev; + struct usb_hcd *hcd = bus_to_hcd(hdev->bus); +- int i, j, retval; ++ int retries, operations, retval, i; + unsigned delay = HUB_SHORT_RESET_TIME; + enum usb_device_speed oldspeed = udev->speed; + const char *speed; +@@ -4379,7 +4379,7 @@ hub_port_init(struct usb_hub *hub, struc + * first 8 bytes of the device descriptor to get the ep0 maxpacket + * value. + */ +- for (i = 0; i < GET_DESCRIPTOR_TRIES; (++i, msleep(100))) { ++ for (retries = 0; retries < GET_DESCRIPTOR_TRIES; (++retries, msleep(100))) { + bool did_new_scheme = false; + + if (use_new_scheme(udev, retry_counter)) { +@@ -4406,7 +4406,7 @@ hub_port_init(struct usb_hub *hub, struc + * 255 is for WUSB devices, we actually need to use + * 512 (WUSB1.0[4.8.1]). + */ +- for (j = 0; j < 3; ++j) { ++ for (operations = 0; operations < 3; ++operations) { + buf->bMaxPacketSize0 = 0; + r = usb_control_msg(udev, usb_rcvaddr0pipe(), + USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, +@@ -4432,7 +4432,7 @@ hub_port_init(struct usb_hub *hub, struc + * reset. But only on the first attempt, + * lest we get into a time out/reset loop + */ +- if (r == 0 || (r == -ETIMEDOUT && j == 0)) ++ if (r == 0 || (r == -ETIMEDOUT && retries == 0)) + break; + } + udev->descriptor.bMaxPacketSize0 = +@@ -4464,7 +4464,7 @@ hub_port_init(struct usb_hub *hub, struc + * authorization will assign the final address. + */ + if (udev->wusb == 0) { +- for (j = 0; j < SET_ADDRESS_TRIES; ++j) { ++ for (operations = 0; operations < SET_ADDRESS_TRIES; ++operations) { + retval = hub_set_address(udev, devnum); + if (retval >= 0) + break; diff --git a/queue-4.4/usb-iowarrior-fix-oops-with-malicious-usb-descriptors.patch b/queue-4.4/usb-iowarrior-fix-oops-with-malicious-usb-descriptors.patch new file mode 100644 index 00000000000..e934a5f8995 --- /dev/null +++ b/queue-4.4/usb-iowarrior-fix-oops-with-malicious-usb-descriptors.patch @@ -0,0 +1,40 @@ +From 4ec0ef3a82125efc36173062a50624550a900ae0 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Mon, 14 Mar 2016 10:42:38 -0400 +Subject: USB: iowarrior: fix oops with malicious USB descriptors + +From: Josh Boyer + +commit 4ec0ef3a82125efc36173062a50624550a900ae0 upstream. + +The iowarrior driver expects at least one valid endpoint. If given +malicious descriptors that specify 0 for the number of endpoints, +it will crash in the probe function. Ensure there is at least +one endpoint on the interface before using it. + +The full report of this issue can be found here: +http://seclists.org/bugtraq/2016/Mar/87 + +Reported-by: Ralf Spenneberg +Signed-off-by: Josh Boyer +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/misc/iowarrior.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/usb/misc/iowarrior.c ++++ b/drivers/usb/misc/iowarrior.c +@@ -787,6 +787,12 @@ static int iowarrior_probe(struct usb_in + iface_desc = interface->cur_altsetting; + dev->product_id = le16_to_cpu(udev->descriptor.idProduct); + ++ if (iface_desc->desc.bNumEndpoints < 1) { ++ dev_err(&interface->dev, "Invalid number of endpoints\n"); ++ retval = -EINVAL; ++ goto error; ++ } ++ + /* set up the endpoint information */ + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; diff --git a/queue-4.4/usb-mct_u232-add-sanity-checking-in-probe.patch b/queue-4.4/usb-mct_u232-add-sanity-checking-in-probe.patch new file mode 100644 index 00000000000..2ff48d0078b --- /dev/null +++ b/queue-4.4/usb-mct_u232-add-sanity-checking-in-probe.patch @@ -0,0 +1,48 @@ +From 4e9a0b05257f29cf4b75f3209243ed71614d062e Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Thu, 31 Mar 2016 12:04:24 -0400 +Subject: USB: mct_u232: add sanity checking in probe + +From: Oliver Neukum + +commit 4e9a0b05257f29cf4b75f3209243ed71614d062e upstream. + +An attack using the lack of sanity checking in probe is known. This +patch checks for the existence of a second port. + +CVE-2016-3136 + +Signed-off-by: Oliver Neukum +[johan: add error message ] +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/mct_u232.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/usb/serial/mct_u232.c ++++ b/drivers/usb/serial/mct_u232.c +@@ -376,14 +376,21 @@ static void mct_u232_msr_to_state(struct + + static int mct_u232_port_probe(struct usb_serial_port *port) + { ++ struct usb_serial *serial = port->serial; + struct mct_u232_private *priv; + ++ /* check first to simplify error handling */ ++ if (!serial->port[1] || !serial->port[1]->interrupt_in_urb) { ++ dev_err(&port->dev, "expected endpoint missing\n"); ++ return -ENODEV; ++ } ++ + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + /* Use second interrupt-in endpoint for reading. */ +- priv->read_urb = port->serial->port[1]->interrupt_in_urb; ++ priv->read_urb = serial->port[1]->interrupt_in_urb; + priv->read_urb->context = port; + + spin_lock_init(&priv->lock); diff --git a/queue-4.4/usb-option-add-d-link-dwm-221-b1-device-id.patch b/queue-4.4/usb-option-add-d-link-dwm-221-b1-device-id.patch new file mode 100644 index 00000000000..81887176c0b --- /dev/null +++ b/queue-4.4/usb-option-add-d-link-dwm-221-b1-device-id.patch @@ -0,0 +1,57 @@ +From d48d5691ebf88a15d95ba96486917ffc79256536 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Thu, 7 Apr 2016 12:09:17 +0200 +Subject: USB: option: add "D-Link DWM-221 B1" device id +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjørn Mork + +commit d48d5691ebf88a15d95ba96486917ffc79256536 upstream. + +Thomas reports: +"Windows: + +00 diagnostics +01 modem +02 at-port +03 nmea +04 nic + +Linux: + +T: Bus=02 Lev=01 Prnt=01 Port=03 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 +D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 +P: Vendor=2001 ProdID=7e19 Rev=02.32 +S: Manufacturer=Mobile Connect +S: Product=Mobile Connect +S: SerialNumber=0123456789ABCDEF +C: #Ifs= 6 Cfg#= 1 Atr=a0 MxPwr=500mA +I: If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=option +I: If#= 1 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=00 Driver=option +I: If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=qmi_wwan +I: If#= 5 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage" + +Reported-by: Thomas Schäfer +Signed-off-by: Bjørn Mork +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/option.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/usb/serial/option.c ++++ b/drivers/usb/serial/option.c +@@ -1818,6 +1818,8 @@ static const struct usb_device_id option + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) }, + { USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) }, ++ { USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff), /* D-Link DWM-221 B1 */ ++ .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */ + { USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e02, 0xff, 0xff, 0xff) }, /* D-Link DWM-156/C1 */ + { USB_DEVICE_INTERFACE_CLASS(0x2020, 0x4000, 0xff) }, /* OLICARD300 - MT6225 */ diff --git a/queue-4.4/usb-retry-reset-if-a-device-times-out.patch b/queue-4.4/usb-retry-reset-if-a-device-times-out.patch new file mode 100644 index 00000000000..80bd8edc778 --- /dev/null +++ b/queue-4.4/usb-retry-reset-if-a-device-times-out.patch @@ -0,0 +1,43 @@ +From 264904ccc33c604d4b3141bbd33808152dfac45b Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 10 Feb 2016 11:33:18 +0100 +Subject: usb: retry reset if a device times out + +From: Oliver Neukum + +commit 264904ccc33c604d4b3141bbd33808152dfac45b upstream. + +Some devices I got show an inability to operate right after +power on if they are already connected. They are beyond recovery +if the descriptors are requested multiple times. So in case of +a timeout we rather bail early and reset again. But it must be +done only on the first loop lest we get into a reset/time out +spiral that can be overcome with a retry. + +This patch is a rework of a patch that fell through the cracks. +http://www.spinics.net/lists/linux-usb/msg103263.html + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/hub.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/hub.c ++++ b/drivers/usb/core/hub.c +@@ -4426,7 +4426,13 @@ hub_port_init(struct usb_hub *hub, struc + r = -EPROTO; + break; + } +- if (r == 0) ++ /* ++ * Some devices time out if they are powered on ++ * when already connected. They need a second ++ * reset. But only on the first attempt, ++ * lest we get into a time out/reset loop ++ */ ++ if (r == 0 || (r == -ETIMEDOUT && j == 0)) + break; + } + udev->descriptor.bMaxPacketSize0 = diff --git a/queue-4.4/usb-serial-cp210x-adding-ge-healthcare-device-id.patch b/queue-4.4/usb-serial-cp210x-adding-ge-healthcare-device-id.patch new file mode 100644 index 00000000000..b2a7c2e4393 --- /dev/null +++ b/queue-4.4/usb-serial-cp210x-adding-ge-healthcare-device-id.patch @@ -0,0 +1,30 @@ +From cddc9434e3dcc37a85c4412fb8e277d3a582e456 Mon Sep 17 00:00:00 2001 +From: Martyn Welch +Date: Tue, 29 Mar 2016 17:47:29 +0100 +Subject: USB: serial: cp210x: Adding GE Healthcare Device ID + +From: Martyn Welch + +commit cddc9434e3dcc37a85c4412fb8e277d3a582e456 upstream. + +The CP2105 is used in the GE Healthcare Remote Alarm Box, with the +Manufacturer ID of 0x1901 and Product ID of 0x0194. + +Signed-off-by: Martyn Welch +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/cp210x.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/usb/serial/cp210x.c ++++ b/drivers/usb/serial/cp210x.c +@@ -164,6 +164,7 @@ static const struct usb_device_id id_tab + { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */ + { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */ + { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */ ++ { USB_DEVICE(0x1901, 0x0194) }, /* GE Healthcare Remote Alarm Box */ + { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */ + { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */ + { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */ diff --git a/queue-4.4/usb-serial-ftdi_sio-add-support-for-icp-das-i-756xu-devices.patch b/queue-4.4/usb-serial-ftdi_sio-add-support-for-icp-das-i-756xu-devices.patch new file mode 100644 index 00000000000..8dd400c6e32 --- /dev/null +++ b/queue-4.4/usb-serial-ftdi_sio-add-support-for-icp-das-i-756xu-devices.patch @@ -0,0 +1,57 @@ +From ea6db90e750328068837bed34cb1302b7a177339 Mon Sep 17 00:00:00 2001 +From: Josh Boyer +Date: Thu, 10 Mar 2016 09:48:52 -0500 +Subject: USB: serial: ftdi_sio: Add support for ICP DAS I-756xU devices + +From: Josh Boyer + +commit ea6db90e750328068837bed34cb1302b7a177339 upstream. + +A Fedora user reports that the ftdi_sio driver works properly for the +ICP DAS I-7561U device. Further, the user manual for these devices +instructs users to load the driver and add the ids using the sysfs +interface. + +Add support for these in the driver directly so that the devices work +out of the box instead of needing manual configuration. + +Reported-by: +Signed-off-by: Josh Boyer +Signed-off-by: Johan Hovold +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/serial/ftdi_sio.c | 4 ++++ + drivers/usb/serial/ftdi_sio_ids.h | 8 ++++++++ + 2 files changed, 12 insertions(+) + +--- a/drivers/usb/serial/ftdi_sio.c ++++ b/drivers/usb/serial/ftdi_sio.c +@@ -1004,6 +1004,10 @@ static const struct usb_device_id id_tab + { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_DISPLAY_PID) }, + { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_LITE_PID) }, + { USB_DEVICE(FTDI_VID, CHETCO_SEASMART_ANALOG_PID) }, ++ /* ICP DAS I-756xU devices */ ++ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7560U_PID) }, ++ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) }, ++ { USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) }, + { } /* Terminating entry */ + }; + +--- a/drivers/usb/serial/ftdi_sio_ids.h ++++ b/drivers/usb/serial/ftdi_sio_ids.h +@@ -872,6 +872,14 @@ + #define NOVITUS_BONO_E_PID 0x6010 + + /* ++ * ICPDAS I-756*U devices ++ */ ++#define ICPDAS_VID 0x1b5c ++#define ICPDAS_I7560U_PID 0x0103 ++#define ICPDAS_I7561U_PID 0x0104 ++#define ICPDAS_I7563U_PID 0x0105 ++ ++/* + * RT Systems programming cables for various ham radios + */ + #define RTSYSTEMS_VID 0x2100 /* Vendor ID */ diff --git a/queue-4.4/usb-uas-reduce-can_queue-to-max_cmnds.patch b/queue-4.4/usb-uas-reduce-can_queue-to-max_cmnds.patch new file mode 100644 index 00000000000..d22f58178e5 --- /dev/null +++ b/queue-4.4/usb-uas-reduce-can_queue-to-max_cmnds.patch @@ -0,0 +1,37 @@ +From 55ff8cfbc4e12a7d2187df523938cc671fbebdd1 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Mon, 7 Mar 2016 20:11:52 +0100 +Subject: USB: uas: Reduce can_queue to MAX_CMNDS + +From: Hans de Goede + +commit 55ff8cfbc4e12a7d2187df523938cc671fbebdd1 upstream. + +The uas driver can never queue more then MAX_CMNDS (- 1) tags and tags +are shared between luns, so there is no need to claim that we can_queue +some random large number. + +Not claiming that we can_queue 65536 commands, fixes the uas driver +failing to initialize while allocating the tag map with a "Page allocation +failure (order 7)" error on systems which have been running for a while +and thus have fragmented memory. + +Reported-and-tested-by: Yves-Alexis Perez +Signed-off-by: Hans de Goede +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/storage/uas.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/usb/storage/uas.c ++++ b/drivers/usb/storage/uas.c +@@ -812,7 +812,7 @@ static struct scsi_host_template uas_hos + .slave_configure = uas_slave_configure, + .eh_abort_handler = uas_eh_abort_handler, + .eh_bus_reset_handler = uas_eh_bus_reset_handler, +- .can_queue = 65536, /* Is there a limit on the _host_ ? */ ++ .can_queue = MAX_CMNDS, + .this_id = -1, + .sg_tablesize = SG_NONE, + .skip_settle_delay = 1, diff --git a/queue-4.4/usb-usb_driver_claim_interface-add-sanity-checking.patch b/queue-4.4/usb-usb_driver_claim_interface-add-sanity-checking.patch new file mode 100644 index 00000000000..154af7a1c9a --- /dev/null +++ b/queue-4.4/usb-usb_driver_claim_interface-add-sanity-checking.patch @@ -0,0 +1,39 @@ +From 0b818e3956fc1ad976bee791eadcbb3b5fec5bfd Mon Sep 17 00:00:00 2001 +From: Oliver Neukum +Date: Wed, 16 Mar 2016 13:26:17 +0100 +Subject: USB: usb_driver_claim_interface: add sanity checking + +From: Oliver Neukum + +commit 0b818e3956fc1ad976bee791eadcbb3b5fec5bfd upstream. + +Attacks that trick drivers into passing a NULL pointer +to usb_driver_claim_interface() using forged descriptors are +known. This thwarts them by sanity checking. + +Signed-off-by: Oliver Neukum +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/usb/core/driver.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/usb/core/driver.c ++++ b/drivers/usb/core/driver.c +@@ -502,11 +502,15 @@ static int usb_unbind_interface(struct d + int usb_driver_claim_interface(struct usb_driver *driver, + struct usb_interface *iface, void *priv) + { +- struct device *dev = &iface->dev; ++ struct device *dev; + struct usb_device *udev; + int retval = 0; + int lpm_disable_error; + ++ if (!iface) ++ return -ENODEV; ++ ++ dev = &iface->dev; + if (dev->driver) + return -EBUSY; +