]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 10:57:36 +0000 (11:57 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 4 Jan 2017 10:57:36 +0000 (11:57 +0100)
added patches:
exec-ensure-mm-user_ns-contains-the-execed-files.patch
usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch

queue-4.4/exec-ensure-mm-user_ns-contains-the-execed-files.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch [new file with mode: 0644]

diff --git a/queue-4.4/exec-ensure-mm-user_ns-contains-the-execed-files.patch b/queue-4.4/exec-ensure-mm-user_ns-contains-the-execed-files.patch
new file mode 100644 (file)
index 0000000..105832c
--- /dev/null
@@ -0,0 +1,126 @@
+From f84df2a6f268de584a201e8911384a2d244876e3 Mon Sep 17 00:00:00 2001
+From: "Eric W. Biederman" <ebiederm@xmission.com>
+Date: Wed, 16 Nov 2016 22:06:51 -0600
+Subject: exec: Ensure mm->user_ns contains the execed files
+
+From: Eric W. Biederman <ebiederm@xmission.com>
+
+commit f84df2a6f268de584a201e8911384a2d244876e3 upstream.
+
+When the user namespace support was merged the need to prevent
+ptrace from revealing the contents of an unreadable executable
+was overlooked.
+
+Correct this oversight by ensuring that the executed file
+or files are in mm->user_ns, by adjusting mm->user_ns.
+
+Use the new function privileged_wrt_inode_uidgid to see if
+the executable is a member of the user namespace, and as such
+if having CAP_SYS_PTRACE in the user namespace should allow
+tracing the executable.  If not update mm->user_ns to
+the parent user namespace until an appropriate parent is found.
+
+Reported-by: Jann Horn <jann@thejh.net>
+Fixes: 9e4a36ece652 ("userns: Fail exec for suid and sgid binaries with ids outside our user namespace.")
+Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/exec.c                  |   20 ++++++++++++++++++--
+ include/linux/capability.h |    1 +
+ kernel/capability.c        |   16 ++++++++++++++--
+ 3 files changed, 33 insertions(+), 4 deletions(-)
+
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -56,6 +56,7 @@
+ #include <linux/pipe_fs_i.h>
+ #include <linux/oom.h>
+ #include <linux/compat.h>
++#include <linux/user_namespace.h>
+ #include <asm/uaccess.h>
+ #include <asm/mmu_context.h>
+@@ -1130,8 +1131,22 @@ EXPORT_SYMBOL(flush_old_exec);
+ void would_dump(struct linux_binprm *bprm, struct file *file)
+ {
+-      if (inode_permission(file_inode(file), MAY_READ) < 0)
++      struct inode *inode = file_inode(file);
++      if (inode_permission(inode, MAY_READ) < 0) {
++              struct user_namespace *old, *user_ns;
+               bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
++
++              /* Ensure mm->user_ns contains the executable */
++              user_ns = old = bprm->mm->user_ns;
++              while ((user_ns != &init_user_ns) &&
++                     !privileged_wrt_inode_uidgid(user_ns, inode))
++                      user_ns = user_ns->parent;
++
++              if (old != user_ns) {
++                      bprm->mm->user_ns = get_user_ns(user_ns);
++                      put_user_ns(old);
++              }
++      }
+ }
+ EXPORT_SYMBOL(would_dump);
+@@ -1161,7 +1176,6 @@ void setup_new_exec(struct linux_binprm
+           !gid_eq(bprm->cred->gid, current_egid())) {
+               current->pdeath_signal = 0;
+       } else {
+-              would_dump(bprm, bprm->file);
+               if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
+                       set_dumpable(current->mm, suid_dumpable);
+       }
+@@ -1593,6 +1607,8 @@ static int do_execveat_common(int fd, st
+       if (retval < 0)
+               goto out;
++      would_dump(bprm, bprm->file);
++
+       retval = exec_binprm(bprm);
+       if (retval < 0)
+               goto out;
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -247,6 +247,7 @@ static inline bool ns_capable_noaudit(st
+       return true;
+ }
+ #endif /* CONFIG_MULTIUSER */
++extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
+ extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
+ extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
+ extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -457,6 +457,19 @@ bool file_ns_capable(const struct file *
+ EXPORT_SYMBOL(file_ns_capable);
+ /**
++ * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
++ * @ns: The user namespace in question
++ * @inode: The inode in question
++ *
++ * Return true if the inode uid and gid are within the namespace.
++ */
++bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
++{
++      return kuid_has_mapping(ns, inode->i_uid) &&
++              kgid_has_mapping(ns, inode->i_gid);
++}
++
++/**
+  * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
+  * @inode: The inode in question
+  * @cap: The capability in question
+@@ -469,8 +482,7 @@ bool capable_wrt_inode_uidgid(const stru
+ {
+       struct user_namespace *ns = current_user_ns();
+-      return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+-              kgid_has_mapping(ns, inode->i_gid);
++      return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
+ }
+ EXPORT_SYMBOL(capable_wrt_inode_uidgid);
index 62a75f840566e6b58123cbfcb5c9c4a0e982dd1b..b0cd3d378860cab818d2660ff0926fe3aa4746de 100644 (file)
@@ -41,3 +41,5 @@ f2fs-set-owner-for-debugfs-status-file-s-file_operations.patch
 loop-return-proper-error-from-loop_queue_rq.patch
 mm-vmscan.c-set-correct-defer-count-for-shrinker.patch
 fs-exec-apply-cloexec-before-changing-dumpable-task-flags.patch
+exec-ensure-mm-user_ns-contains-the-execed-files.patch
+usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch
diff --git a/queue-4.4/usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch b/queue-4.4/usb-gadget-composite-always-set-ep-mult-to-a-sensible-value.patch
new file mode 100644 (file)
index 0000000..af86dea
--- /dev/null
@@ -0,0 +1,67 @@
+From eaa496ffaaf19591fe471a36cef366146eeb9153 Mon Sep 17 00:00:00 2001
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+Date: Wed, 28 Sep 2016 12:33:31 +0300
+Subject: usb: gadget: composite: always set ep->mult to a sensible value
+
+From: Felipe Balbi <felipe.balbi@linux.intel.com>
+
+commit eaa496ffaaf19591fe471a36cef366146eeb9153 upstream.
+
+ep->mult is supposed to be set to Isochronous and
+Interrupt Endapoint's multiplier value. This value
+is computed from different places depending on the
+link speed.
+
+If we're dealing with HighSpeed, then it's part of
+bits [12:11] of wMaxPacketSize. This case wasn't
+taken into consideration before.
+
+While at that, also make sure the ep->mult defaults
+to one so drivers can use it unconditionally and
+assume they'll never multiply ep->maxpacket to zero.
+
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/gadget/composite.c          |    9 +++++++--
+ drivers/usb/gadget/function/uvc_video.c |    2 +-
+ 2 files changed, 8 insertions(+), 3 deletions(-)
+
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -148,7 +148,12 @@ ep_found:
+       _ep->desc = chosen_desc;
+       _ep->comp_desc = NULL;
+       _ep->maxburst = 0;
+-      _ep->mult = 0;
++      _ep->mult = 1;
++
++      if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) ||
++                              usb_endpoint_xfer_int(_ep->desc)))
++              _ep->mult = usb_endpoint_maxp(_ep->desc) & 0x7ff;
++
+       if (!want_comp_desc)
+               return 0;
+@@ -165,7 +170,7 @@ ep_found:
+               switch (usb_endpoint_type(_ep->desc)) {
+               case USB_ENDPOINT_XFER_ISOC:
+                       /* mult: bits 1:0 of bmAttributes */
+-                      _ep->mult = comp_desc->bmAttributes & 0x3;
++                      _ep->mult = (comp_desc->bmAttributes & 0x3) + 1;
+               case USB_ENDPOINT_XFER_BULK:
+               case USB_ENDPOINT_XFER_INT:
+                       _ep->maxburst = comp_desc->bMaxBurst + 1;
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -243,7 +243,7 @@ uvc_video_alloc_requests(struct uvc_vide
+       req_size = video->ep->maxpacket
+                * max_t(unsigned int, video->ep->maxburst, 1)
+-               * (video->ep->mult + 1);
++               * (video->ep->mult);
+       for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
+               video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);