]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2017 19:45:53 +0000 (12:45 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Aug 2017 19:45:53 +0000 (12:45 -0700)
added patches:
make-file-credentials-available-to-the-seqfile-interfaces.patch
proc-iomem-only-expose-physical-resource-addresses-to-privileged-users.patch
vlan-propagate-mac-address-to-vlans.patch

queue-4.4/make-file-credentials-available-to-the-seqfile-interfaces.patch [new file with mode: 0644]
queue-4.4/proc-iomem-only-expose-physical-resource-addresses-to-privileged-users.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/vlan-propagate-mac-address-to-vlans.patch [new file with mode: 0644]

diff --git a/queue-4.4/make-file-credentials-available-to-the-seqfile-interfaces.patch b/queue-4.4/make-file-credentials-available-to-the-seqfile-interfaces.patch
new file mode 100644 (file)
index 0000000..4e62ef0
--- /dev/null
@@ -0,0 +1,96 @@
+From 34dbbcdbf63360661ff7bda6c5f52f99ac515f92 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 14 Apr 2016 11:22:00 -0700
+Subject: Make file credentials available to the seqfile interfaces
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 34dbbcdbf63360661ff7bda6c5f52f99ac515f92 upstream.
+
+A lot of seqfile users seem to be using things like %pK that uses the
+credentials of the current process, but that is actually completely
+wrong for filesystem interfaces.
+
+The unix semantics for permission checking files is to check permissions
+at _open_ time, not at read or write time, and that is not just a small
+detail: passing off stdin/stdout/stderr to a suid application and making
+the actual IO happen in privileged context is a classic exploit
+technique.
+
+So if we want to be able to look at permissions at read time, we need to
+use the file open credentials, not the current ones.  Normal file
+accesses can just use "f_cred" (or any of the helper functions that do
+that, like file_ns_capable()), but the seqfile interfaces do not have
+any such options.
+
+It turns out that seq_file _does_ save away the user_ns information of
+the file, though.  Since user_ns is just part of the full credential
+information, replace that special case with saving off the cred pointer
+instead, and suddenly seq_file has all the permission information it
+needs.
+
+[sumits: this is used in Ubuntu as a fix for CVE-2015-8944]
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/seq_file.c            |    7 ++++---
+ include/linux/seq_file.h |   13 ++++---------
+ 2 files changed, 8 insertions(+), 12 deletions(-)
+
+--- a/fs/seq_file.c
++++ b/fs/seq_file.c
+@@ -72,9 +72,10 @@ int seq_open(struct file *file, const st
+       mutex_init(&p->lock);
+       p->op = op;
+-#ifdef CONFIG_USER_NS
+-      p->user_ns = file->f_cred->user_ns;
+-#endif
++
++      // No refcounting: the lifetime of 'p' is constrained
++      // to the lifetime of the file.
++      p->file = file;
+       /*
+        * Wrappers around seq_open(e.g. swaps_open) need to be
+--- a/include/linux/seq_file.h
++++ b/include/linux/seq_file.h
+@@ -7,13 +7,10 @@
+ #include <linux/mutex.h>
+ #include <linux/cpumask.h>
+ #include <linux/nodemask.h>
++#include <linux/fs.h>
++#include <linux/cred.h>
+ struct seq_operations;
+-struct file;
+-struct path;
+-struct inode;
+-struct dentry;
+-struct user_namespace;
+ struct seq_file {
+       char *buf;
+@@ -27,9 +24,7 @@ struct seq_file {
+       struct mutex lock;
+       const struct seq_operations *op;
+       int poll_event;
+-#ifdef CONFIG_USER_NS
+-      struct user_namespace *user_ns;
+-#endif
++      const struct file *file;
+       void *private;
+ };
+@@ -147,7 +142,7 @@ int seq_release_private(struct inode *,
+ static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
+ {
+ #ifdef CONFIG_USER_NS
+-      return seq->user_ns;
++      return seq->file->f_cred->user_ns;
+ #else
+       extern struct user_namespace init_user_ns;
+       return &init_user_ns;
diff --git a/queue-4.4/proc-iomem-only-expose-physical-resource-addresses-to-privileged-users.patch b/queue-4.4/proc-iomem-only-expose-physical-resource-addresses-to-privileged-users.patch
new file mode 100644 (file)
index 0000000..035794c
--- /dev/null
@@ -0,0 +1,57 @@
+From 51d7b120418e99d6b3bf8df9eb3cc31e8171dee4 Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Thu, 14 Apr 2016 12:05:37 -0700
+Subject: /proc/iomem: only expose physical resource addresses to privileged users
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 51d7b120418e99d6b3bf8df9eb3cc31e8171dee4 upstream.
+
+In commit c4004b02f8e5b ("x86: remove the kernel code/data/bss resources
+from /proc/iomem") I was hoping to remove the phyiscal kernel address
+data from /proc/iomem entirely, but that had to be reverted because some
+system programs actually use it.
+
+This limits all the detailed resource information to properly
+credentialed users instead.
+
+[sumits: this is used in Ubuntu as a fix for CVE-2015-8944]
+
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/resource.c |   13 +++++++++++--
+ 1 file changed, 11 insertions(+), 2 deletions(-)
+
+--- a/kernel/resource.c
++++ b/kernel/resource.c
+@@ -105,16 +105,25 @@ static int r_show(struct seq_file *m, vo
+ {
+       struct resource *root = m->private;
+       struct resource *r = v, *p;
++      unsigned long long start, end;
+       int width = root->end < 0x10000 ? 4 : 8;
+       int depth;
+       for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
+               if (p->parent == root)
+                       break;
++
++      if (file_ns_capable(m->file, &init_user_ns, CAP_SYS_ADMIN)) {
++              start = r->start;
++              end = r->end;
++      } else {
++              start = end = 0;
++      }
++
+       seq_printf(m, "%*s%0*llx-%0*llx : %s\n",
+                       depth * 2, "",
+-                      width, (unsigned long long) r->start,
+-                      width, (unsigned long long) r->end,
++                      width, start,
++                      width, end,
+                       r->name ? r->name : "<BAD>");
+       return 0;
+ }
index 27b1e59ae2db93f5e1f8b16d903ec24d11c114af..67eea8a9227479fe7726d5f9e3cd75b96e00d508 100644 (file)
@@ -39,3 +39,6 @@ libnvdimm-btt-fix-btt_rw_page-not-returning-errors.patch
 ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch
 dentry-name-snapshots.patch
 v4l-s5c73m3-fix-negation-operator.patch
+make-file-credentials-available-to-the-seqfile-interfaces.patch
+proc-iomem-only-expose-physical-resource-addresses-to-privileged-users.patch
+vlan-propagate-mac-address-to-vlans.patch
diff --git a/queue-4.4/vlan-propagate-mac-address-to-vlans.patch b/queue-4.4/vlan-propagate-mac-address-to-vlans.patch
new file mode 100644 (file)
index 0000000..07842c2
--- /dev/null
@@ -0,0 +1,105 @@
+From 308453aa9156a3b8ee382c0949befb507a32b0c1 Mon Sep 17 00:00:00 2001
+From: Mike Manning <mmanning@brocade.com>
+Date: Fri, 27 May 2016 17:45:07 +0100
+Subject: vlan: Propagate MAC address to VLANs
+
+From: Mike Manning <mmanning@brocade.com>
+
+commit 308453aa9156a3b8ee382c0949befb507a32b0c1 upstream.
+
+The MAC address of the physical interface is only copied to the VLAN
+when it is first created, resulting in an inconsistency after MAC
+address changes of only newly created VLANs having an up-to-date MAC.
+
+The VLANs should continue inheriting the MAC address of the physical
+interface until the VLAN MAC address is explicitly set to any value.
+This allows IPv6 EUI64 addresses for the VLAN to reflect any changes
+to the MAC of the physical interface and thus for DAD to behave as
+expected.
+
+Signed-off-by: Mike Manning <mmanning@brocade.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/8021q/vlan.c     |    5 +++++
+ net/8021q/vlan.h     |    2 ++
+ net/8021q/vlan_dev.c |   20 +++++++++++++++++---
+ 3 files changed, 24 insertions(+), 3 deletions(-)
+
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -292,6 +292,10 @@ static void vlan_sync_address(struct net
+       if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr))
+               return;
++      /* vlan continues to inherit address of lower device */
++      if (vlan_dev_inherit_address(vlandev, dev))
++              goto out;
++
+       /* vlan address was different from the old address and is equal to
+        * the new address */
+       if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) &&
+@@ -304,6 +308,7 @@ static void vlan_sync_address(struct net
+           !ether_addr_equal(vlandev->dev_addr, dev->dev_addr))
+               dev_uc_add(dev, vlandev->dev_addr);
++out:
+       ether_addr_copy(vlan->real_dev_addr, dev->dev_addr);
+ }
+--- a/net/8021q/vlan.h
++++ b/net/8021q/vlan.h
+@@ -109,6 +109,8 @@ int vlan_check_real_dev(struct net_devic
+ void vlan_setup(struct net_device *dev);
+ int register_vlan_dev(struct net_device *dev);
+ void unregister_vlan_dev(struct net_device *dev, struct list_head *head);
++bool vlan_dev_inherit_address(struct net_device *dev,
++                            struct net_device *real_dev);
+ static inline u32 vlan_get_ingress_priority(struct net_device *dev,
+                                           u16 vlan_tci)
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -244,6 +244,17 @@ void vlan_dev_get_realdev_name(const str
+       strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23);
+ }
++bool vlan_dev_inherit_address(struct net_device *dev,
++                            struct net_device *real_dev)
++{
++      if (dev->addr_assign_type != NET_ADDR_STOLEN)
++              return false;
++
++      ether_addr_copy(dev->dev_addr, real_dev->dev_addr);
++      call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
++      return true;
++}
++
+ static int vlan_dev_open(struct net_device *dev)
+ {
+       struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
+@@ -254,7 +265,8 @@ static int vlan_dev_open(struct net_devi
+           !(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
+               return -ENETDOWN;
+-      if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) {
++      if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr) &&
++          !vlan_dev_inherit_address(dev, real_dev)) {
+               err = dev_uc_add(real_dev, dev->dev_addr);
+               if (err < 0)
+                       goto out;
+@@ -558,8 +570,10 @@ static int vlan_dev_init(struct net_devi
+       /* ipv6 shared card related stuff */
+       dev->dev_id = real_dev->dev_id;
+-      if (is_zero_ether_addr(dev->dev_addr))
+-              eth_hw_addr_inherit(dev, real_dev);
++      if (is_zero_ether_addr(dev->dev_addr)) {
++              ether_addr_copy(dev->dev_addr, real_dev->dev_addr);
++              dev->addr_assign_type = NET_ADDR_STOLEN;
++      }
+       if (is_zero_ether_addr(dev->broadcast))
+               memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len);