]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Nov 2017 11:50:05 +0000 (12:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Nov 2017 11:50:05 +0000 (12:50 +0100)
added patches:
cdc_ncm-set-ntb-format-again-after-altsetting-switch-for-huawei-devices.patch
keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
keys-trusted-sanitize-all-key-material.patch
platform-x86-hp-wmi-fix-detection-for-dock-and-tablet-mode.patch

queue-4.9/cdc_ncm-set-ntb-format-again-after-altsetting-switch-for-huawei-devices.patch [new file with mode: 0644]
queue-4.9/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch [new file with mode: 0644]
queue-4.9/keys-trusted-sanitize-all-key-material.patch [new file with mode: 0644]
queue-4.9/platform-x86-hp-wmi-fix-detection-for-dock-and-tablet-mode.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/cdc_ncm-set-ntb-format-again-after-altsetting-switch-for-huawei-devices.patch b/queue-4.9/cdc_ncm-set-ntb-format-again-after-altsetting-switch-for-huawei-devices.patch
new file mode 100644 (file)
index 0000000..0e5e6c9
--- /dev/null
@@ -0,0 +1,115 @@
+From 2b02c20ce0c28974b44e69a2e2f5ddc6a470ad6f Mon Sep 17 00:00:00 2001
+From: Enrico Mioso <mrkiko.rs@gmail.com>
+Date: Tue, 11 Jul 2017 17:21:52 +0200
+Subject: cdc_ncm: Set NTB format again after altsetting switch for Huawei devices
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Enrico Mioso <mrkiko.rs@gmail.com>
+
+commit 2b02c20ce0c28974b44e69a2e2f5ddc6a470ad6f upstream.
+
+Some firmwares in Huawei E3372H devices have been observed to switch back
+to NTB 32-bit format after altsetting switch.
+This patch implements a driver flag to check for the device settings and
+set NTB format to 16-bit again if needed.
+The flag has been activated for devices controlled by the huawei_cdc_ncm.c
+driver.
+
+V1->V2:
+- fixed broken error checks
+- some corrections to the commit message
+V2->V3:
+- variable name changes, to clarify what's happening
+- check (and possibly set) the NTB format later in the common bind code path
+
+Signed-off-by: Enrico Mioso <mrkiko.rs@gmail.com>
+Reported-and-tested-by: Christian Panton <christian@panton.org>
+Reviewed-by: Bjørn Mork <bjorn@mork.no>
+CC: Bjørn Mork <bjorn@mork.no>
+CC: Christian Panton <christian@panton.org>
+CC: linux-usb@vger.kernel.org
+CC: netdev@vger.kernel.org
+CC: Oliver Neukum <oliver@neukum.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Porto Rio <porto.rio@gmx.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/usb/cdc_ncm.c        |   28 ++++++++++++++++++++++++++++
+ drivers/net/usb/huawei_cdc_ncm.c |    6 ++++++
+ include/linux/usb/cdc_ncm.h      |    1 +
+ 3 files changed, 35 insertions(+)
+
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -769,8 +769,10 @@ int cdc_ncm_bind_common(struct usbnet *d
+       u8 *buf;
+       int len;
+       int temp;
++      int err;
+       u8 iface_no;
+       struct usb_cdc_parsed_header hdr;
++      u16 curr_ntb_format;
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+@@ -875,6 +877,32 @@ int cdc_ncm_bind_common(struct usbnet *d
+               goto error2;
+       }
++      /*
++       * Some Huawei devices have been observed to come out of reset in NDP32 mode.
++       * Let's check if this is the case, and set the device to NDP16 mode again if
++       * needed.
++      */
++      if (ctx->drvflags & CDC_NCM_FLAG_RESET_NTB16) {
++              err = usbnet_read_cmd(dev, USB_CDC_GET_NTB_FORMAT,
++                                    USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
++                                    0, iface_no, &curr_ntb_format, 2);
++              if (err < 0) {
++                      goto error2;
++              }
++
++              if (curr_ntb_format == USB_CDC_NCM_NTB32_FORMAT) {
++                      dev_info(&intf->dev, "resetting NTB format to 16-bit");
++                      err = usbnet_write_cmd(dev, USB_CDC_SET_NTB_FORMAT,
++                                             USB_TYPE_CLASS | USB_DIR_OUT
++                                             | USB_RECIP_INTERFACE,
++                                             USB_CDC_NCM_NTB16_FORMAT,
++                                             iface_no, NULL, 0);
++
++                      if (err < 0)
++                              goto error2;
++              }
++      }
++
+       cdc_ncm_find_endpoints(dev, ctx->data);
+       cdc_ncm_find_endpoints(dev, ctx->control);
+       if (!dev->in || !dev->out || !dev->status) {
+--- a/drivers/net/usb/huawei_cdc_ncm.c
++++ b/drivers/net/usb/huawei_cdc_ncm.c
+@@ -80,6 +80,12 @@ static int huawei_cdc_ncm_bind(struct us
+        * be at the end of the frame.
+        */
+       drvflags |= CDC_NCM_FLAG_NDP_TO_END;
++
++      /* Additionally, it has been reported that some Huawei E3372H devices, with
++       * firmware version 21.318.01.00.541, come out of reset in NTB32 format mode, hence
++       * needing to be set to the NTB16 one again.
++       */
++      drvflags |= CDC_NCM_FLAG_RESET_NTB16;
+       ret = cdc_ncm_bind_common(usbnet_dev, intf, 1, drvflags);
+       if (ret)
+               goto err;
+--- a/include/linux/usb/cdc_ncm.h
++++ b/include/linux/usb/cdc_ncm.h
+@@ -83,6 +83,7 @@
+ /* Driver flags */
+ #define CDC_NCM_FLAG_NDP_TO_END                       0x02    /* NDP is placed at end of frame */
+ #define CDC_MBIM_FLAG_AVOID_ALTSETTING_TOGGLE 0x04    /* Avoid altsetting toggle during init */
++#define CDC_NCM_FLAG_RESET_NTB16 0x08 /* set NDP16 one more time after altsetting switch */
+ #define cdc_ncm_comm_intf_is_mbim(x)  ((x)->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_MBIM && \
+                                      (x)->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE)
diff --git a/queue-4.9/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch b/queue-4.9/keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch
new file mode 100644 (file)
index 0000000..4fe3ac6
--- /dev/null
@@ -0,0 +1,68 @@
+From a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 2 Nov 2017 00:47:12 +0000
+Subject: KEYS: trusted: fix writing past end of buffer in trusted_read()
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit a3c812f7cfd80cf51e8f5b7034f7418f6beb56c1 upstream.
+
+When calling keyctl_read() on a key of type "trusted", if the
+user-supplied buffer was too small, the kernel ignored the buffer length
+and just wrote past the end of the buffer, potentially corrupting
+userspace memory.  Fix it by instead returning the size required, as per
+the documentation for keyctl_read().
+
+We also don't even fill the buffer at all in this case, as this is
+slightly easier to implement than doing a short read, and either
+behavior appears to be permitted.  It also makes it match the behavior
+of the "encrypted" key type.
+
+Fixes: d00a1c72f7f4 ("keys: add new trusted key-type")
+Reported-by: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Reviewed-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Reviewed-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/trusted.c |   23 ++++++++++++-----------
+ 1 file changed, 12 insertions(+), 11 deletions(-)
+
+--- a/security/keys/trusted.c
++++ b/security/keys/trusted.c
+@@ -1147,20 +1147,21 @@ static long trusted_read(const struct ke
+       p = rcu_dereference_key(key);
+       if (!p)
+               return -EINVAL;
+-      if (!buffer || buflen <= 0)
+-              return 2 * p->blob_len;
+-      ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
+-      if (!ascii_buf)
+-              return -ENOMEM;
+-      bufp = ascii_buf;
+-      for (i = 0; i < p->blob_len; i++)
+-              bufp = hex_byte_pack(bufp, p->blob[i]);
+-      if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
++      if (buffer && buflen >= 2 * p->blob_len) {
++              ascii_buf = kmalloc(2 * p->blob_len, GFP_KERNEL);
++              if (!ascii_buf)
++                      return -ENOMEM;
++
++              bufp = ascii_buf;
++              for (i = 0; i < p->blob_len; i++)
++                      bufp = hex_byte_pack(bufp, p->blob[i]);
++              if (copy_to_user(buffer, ascii_buf, 2 * p->blob_len) != 0) {
++                      kzfree(ascii_buf);
++                      return -EFAULT;
++              }
+               kzfree(ascii_buf);
+-              return -EFAULT;
+       }
+-      kzfree(ascii_buf);
+       return 2 * p->blob_len;
+ }
diff --git a/queue-4.9/keys-trusted-sanitize-all-key-material.patch b/queue-4.9/keys-trusted-sanitize-all-key-material.patch
new file mode 100644 (file)
index 0000000..95aabb5
--- /dev/null
@@ -0,0 +1,198 @@
+From ee618b4619b72527aaed765f0f0b74072b281159 Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Thu, 8 Jun 2017 14:49:18 +0100
+Subject: KEYS: trusted: sanitize all key material
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit ee618b4619b72527aaed765f0f0b74072b281159 upstream.
+
+As the previous patch did for encrypted-keys, zero sensitive any
+potentially sensitive data related to the "trusted" key type before it
+is freed.  Notably, we were not zeroing the tpm_buf structures in which
+the actual key is stored for TPM seal and unseal, nor were we zeroing
+the trusted_key_payload in certain error paths.
+
+Cc: Mimi Zohar <zohar@linux.vnet.ibm.com>
+Cc: David Safford <safford@us.ibm.com>
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: James Morris <james.l.morris@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/trusted.c |   50 +++++++++++++++++++++---------------------------
+ 1 file changed, 22 insertions(+), 28 deletions(-)
+
+--- a/security/keys/trusted.c
++++ b/security/keys/trusted.c
+@@ -70,7 +70,7 @@ static int TSS_sha1(const unsigned char
+       }
+       ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
+-      kfree(sdesc);
++      kzfree(sdesc);
+       return ret;
+ }
+@@ -114,7 +114,7 @@ static int TSS_rawhmac(unsigned char *di
+       if (!ret)
+               ret = crypto_shash_final(&sdesc->shash, digest);
+ out:
+-      kfree(sdesc);
++      kzfree(sdesc);
+       return ret;
+ }
+@@ -165,7 +165,7 @@ static int TSS_authhmac(unsigned char *d
+                                 paramdigest, TPM_NONCE_SIZE, h1,
+                                 TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
+ out:
+-      kfree(sdesc);
++      kzfree(sdesc);
+       return ret;
+ }
+@@ -246,7 +246,7 @@ static int TSS_checkhmac1(unsigned char
+       if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
+               ret = -EINVAL;
+ out:
+-      kfree(sdesc);
++      kzfree(sdesc);
+       return ret;
+ }
+@@ -347,7 +347,7 @@ static int TSS_checkhmac2(unsigned char
+       if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
+               ret = -EINVAL;
+ out:
+-      kfree(sdesc);
++      kzfree(sdesc);
+       return ret;
+ }
+@@ -564,7 +564,7 @@ static int tpm_seal(struct tpm_buf *tb,
+               *bloblen = storedsize;
+       }
+ out:
+-      kfree(td);
++      kzfree(td);
+       return ret;
+ }
+@@ -678,7 +678,7 @@ static int key_seal(struct trusted_key_p
+       if (ret < 0)
+               pr_info("trusted_key: srkseal failed (%d)\n", ret);
+-      kfree(tb);
++      kzfree(tb);
+       return ret;
+ }
+@@ -703,7 +703,7 @@ static int key_unseal(struct trusted_key
+               /* pull migratable flag out of sealed key */
+               p->migratable = p->key[--p->key_len];
+-      kfree(tb);
++      kzfree(tb);
+       return ret;
+ }
+@@ -1037,12 +1037,12 @@ static int trusted_instantiate(struct ke
+       if (!ret && options->pcrlock)
+               ret = pcrlock(options->pcrlock);
+ out:
+-      kfree(datablob);
+-      kfree(options);
++      kzfree(datablob);
++      kzfree(options);
+       if (!ret)
+               rcu_assign_keypointer(key, payload);
+       else
+-              kfree(payload);
++              kzfree(payload);
+       return ret;
+ }
+@@ -1051,8 +1051,7 @@ static void trusted_rcu_free(struct rcu_
+       struct trusted_key_payload *p;
+       p = container_of(rcu, struct trusted_key_payload, rcu);
+-      memset(p->key, 0, p->key_len);
+-      kfree(p);
++      kzfree(p);
+ }
+ /*
+@@ -1094,13 +1093,13 @@ static int trusted_update(struct key *ke
+       ret = datablob_parse(datablob, new_p, new_o);
+       if (ret != Opt_update) {
+               ret = -EINVAL;
+-              kfree(new_p);
++              kzfree(new_p);
+               goto out;
+       }
+       if (!new_o->keyhandle) {
+               ret = -EINVAL;
+-              kfree(new_p);
++              kzfree(new_p);
+               goto out;
+       }
+@@ -1114,22 +1113,22 @@ static int trusted_update(struct key *ke
+       ret = key_seal(new_p, new_o);
+       if (ret < 0) {
+               pr_info("trusted_key: key_seal failed (%d)\n", ret);
+-              kfree(new_p);
++              kzfree(new_p);
+               goto out;
+       }
+       if (new_o->pcrlock) {
+               ret = pcrlock(new_o->pcrlock);
+               if (ret < 0) {
+                       pr_info("trusted_key: pcrlock failed (%d)\n", ret);
+-                      kfree(new_p);
++                      kzfree(new_p);
+                       goto out;
+               }
+       }
+       rcu_assign_keypointer(key, new_p);
+       call_rcu(&p->rcu, trusted_rcu_free);
+ out:
+-      kfree(datablob);
+-      kfree(new_o);
++      kzfree(datablob);
++      kzfree(new_o);
+       return ret;
+ }
+@@ -1158,24 +1157,19 @@ static long trusted_read(const struct ke
+       for (i = 0; i < p->blob_len; i++)
+               bufp = hex_byte_pack(bufp, p->blob[i]);
+       if ((copy_to_user(buffer, ascii_buf, 2 * p->blob_len)) != 0) {
+-              kfree(ascii_buf);
++              kzfree(ascii_buf);
+               return -EFAULT;
+       }
+-      kfree(ascii_buf);
++      kzfree(ascii_buf);
+       return 2 * p->blob_len;
+ }
+ /*
+- * trusted_destroy - before freeing the key, clear the decrypted data
++ * trusted_destroy - clear and free the key's payload
+  */
+ static void trusted_destroy(struct key *key)
+ {
+-      struct trusted_key_payload *p = key->payload.data[0];
+-
+-      if (!p)
+-              return;
+-      memset(p->key, 0, p->key_len);
+-      kfree(key->payload.data[0]);
++      kzfree(key->payload.data[0]);
+ }
+ struct key_type key_type_trusted = {
diff --git a/queue-4.9/platform-x86-hp-wmi-fix-detection-for-dock-and-tablet-mode.patch b/queue-4.9/platform-x86-hp-wmi-fix-detection-for-dock-and-tablet-mode.patch
new file mode 100644 (file)
index 0000000..af73d8f
--- /dev/null
@@ -0,0 +1,107 @@
+From 298747b7579f5bbbced793d997b333fd10a24921 Mon Sep 17 00:00:00 2001
+From: Carlo Caione <carlo@endlessm.com>
+Date: Sun, 9 Apr 2017 15:56:08 +0200
+Subject: platform/x86: hp-wmi: Fix detection for dock and tablet mode
+
+From: Carlo Caione <carlo@endlessm.com>
+
+commit 298747b7579f5bbbced793d997b333fd10a24921 upstream.
+
+The current driver code is not checking for the error values returned by
+'hp_wmi_dock_state()' and 'hp_wmi_tablet_state()' before passing the
+returned values down to 'input_report_switch()'. This error code is
+being translated to '1' in the input subsystem, reporting the wrong
+status.
+
+The biggest problem caused by this issue is that several laptops are
+wrongly reported by the driver as docked, preventing them to be put to
+sleep using the LID (and in most cases they are not even dockable).
+
+With this patch we create the report switches only if we are able to
+read the dock and tablet mode status correctly from ACPI.
+
+Signed-off-by: Carlo Caione <carlo@endlessm.com>
+Signed-off-by: Darren Hart (VMware) <dvhart@infradead.org>
+Cc: Philip Müller <philm@manjaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/platform/x86/hp-wmi.c |   40 +++++++++++++++++++++++++++-------------
+ 1 file changed, 27 insertions(+), 13 deletions(-)
+
+--- a/drivers/platform/x86/hp-wmi.c
++++ b/drivers/platform/x86/hp-wmi.c
+@@ -572,10 +572,12 @@ static void hp_wmi_notify(u32 value, voi
+       switch (event_id) {
+       case HPWMI_DOCK_EVENT:
+-              input_report_switch(hp_wmi_input_dev, SW_DOCK,
+-                                  hp_wmi_dock_state());
+-              input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+-                                  hp_wmi_tablet_state());
++              if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
++                      input_report_switch(hp_wmi_input_dev, SW_DOCK,
++                                          hp_wmi_dock_state());
++              if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
++                      input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
++                                          hp_wmi_tablet_state());
+               input_sync(hp_wmi_input_dev);
+               break;
+       case HPWMI_PARK_HDD:
+@@ -644,6 +646,7 @@ static int __init hp_wmi_input_setup(voi
+ {
+       acpi_status status;
+       int err;
++      int val;
+       hp_wmi_input_dev = input_allocate_device();
+       if (!hp_wmi_input_dev)
+@@ -654,17 +657,26 @@ static int __init hp_wmi_input_setup(voi
+       hp_wmi_input_dev->id.bustype = BUS_HOST;
+       __set_bit(EV_SW, hp_wmi_input_dev->evbit);
+-      __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
+-      __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
++
++      /* Dock */
++      val = hp_wmi_dock_state();
++      if (!(val < 0)) {
++              __set_bit(SW_DOCK, hp_wmi_input_dev->swbit);
++              input_report_switch(hp_wmi_input_dev, SW_DOCK, val);
++      }
++
++      /* Tablet mode */
++      val = hp_wmi_tablet_state();
++      if (!(val < 0)) {
++              __set_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit);
++              input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE, val);
++      }
+       err = sparse_keymap_setup(hp_wmi_input_dev, hp_wmi_keymap, NULL);
+       if (err)
+               goto err_free_dev;
+       /* Set initial hardware state */
+-      input_report_switch(hp_wmi_input_dev, SW_DOCK, hp_wmi_dock_state());
+-      input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+-                          hp_wmi_tablet_state());
+       input_sync(hp_wmi_input_dev);
+       if (!hp_wmi_bios_2009_later() && hp_wmi_bios_2008_later())
+@@ -950,10 +962,12 @@ static int hp_wmi_resume_handler(struct
+        * changed.
+        */
+       if (hp_wmi_input_dev) {
+-              input_report_switch(hp_wmi_input_dev, SW_DOCK,
+-                                  hp_wmi_dock_state());
+-              input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
+-                                  hp_wmi_tablet_state());
++              if (test_bit(SW_DOCK, hp_wmi_input_dev->swbit))
++                      input_report_switch(hp_wmi_input_dev, SW_DOCK,
++                                          hp_wmi_dock_state());
++              if (test_bit(SW_TABLET_MODE, hp_wmi_input_dev->swbit))
++                      input_report_switch(hp_wmi_input_dev, SW_TABLET_MODE,
++                                          hp_wmi_tablet_state());
+               input_sync(hp_wmi_input_dev);
+       }
index 542f744b8fced08603181213505f146527c459e4..2bbadaaa391533b65d83bb89cc0693d077c0f96f 100644 (file)
@@ -47,3 +47,7 @@ wcn36xx-don-t-use-the-destroyed-hal_mutex.patch
 ib-rxe-fix-reference-leaks-in-memory-key-invalidation-code.patch
 clk-mvebu-adjust-ap806-cpu-clock-frequencies-to-production-chip.patch
 net-dsa-select-net_switchdev.patch
+platform-x86-hp-wmi-fix-detection-for-dock-and-tablet-mode.patch
+cdc_ncm-set-ntb-format-again-after-altsetting-switch-for-huawei-devices.patch
+keys-trusted-sanitize-all-key-material.patch
+keys-trusted-fix-writing-past-end-of-buffer-in-trusted_read.patch