Publicus/cvefixes-security-ir-graphrag huggingface dataset:
CVE-2012-2375: Numeric Errors (CWE-189)
value: The __nfs4_get_acl_uncached function in fs/nfs/nfs4proc.c in the NFSv4 implementation in the Linux kernel before 3.3.2 uses an incorrect length variable during a copy operation, which allows remote NFS servers to cause a denial of service (OOPS) by sending an excessive number of bitmap words in an FATTR4_ACL reply.  NOTE: this vulnerability exists because of an incomplete fix for CVE-2011-4131.
CWE description: Weaknesses in this category are related to improper calculation or conversion of numbers.
Published: 2012-06-13T10:24Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: fs/nfs/nfs4proc.c
Commit date: 2012-03-24 14:33:26 -0400
Commit message: Fix length of buffer copied in __nfs4_get_acl_uncached

_copy_from_pages() used to copy data from the temporary buffer to the
user passed buffer is passed the wrong size parameter when copying
data. res.acl_len contains both the bitmap and acl lenghts while
acl_len contains the acl length after adjusting for the bitmap size.

Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

Diff: diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index e809d2305ebf3..45df7d4a3acc1 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3710,11 +3710,11 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
 	if (buf) {
 		ret = -ERANGE;
 		if (acl_len > buflen)
 			goto out_free;
 		_copy_from_pages(buf, pages, res.acl_data_offset,
-				res.acl_len);
+				acl_len);
 	}
 	ret = acl_len;
 out_free:
 	for (i = 0; i < npages; i++)
 		if (pages[i])

Vulnerable code: 				res.acl_len);
Fixed code: 				acl_len);
CVE-2017-16535: Out-of-bounds Read (CWE-125)
value: The usb_get_bos_descriptor function in drivers/usb/core/config.c in the Linux kernel before 4.13.10 allows local users to cause a denial of service (out-of-bounds read and system crash) or possibly have unspecified other impact via a crafted USB device.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 6.6
Published: 2017-11-04T01:29Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/usb/core/config.c
Commit date: 2017-10-18 19:11:52 +0200
Commit message: USB: core: fix out-of-bounds access bug in usb_get_bos_descriptor()

Andrey used the syzkaller fuzzer to find an out-of-bounds memory
access in usb_get_bos_descriptor().  The code wasn't checking that the
next usb_dev_cap_header structure could fit into the remaining buffer
space.

This patch fixes the error and also reduces the bNumDeviceCaps field
in the header to match the actual number of capabilities found, in
cases where there are fewer than expected.

Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Tested-by: Andrey Konovalov <andreyknvl@google.com>
CC: <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Diff: diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
index 68b54bd88d1eb0..883549ee946cb5 100644
--- a/drivers/usb/core/config.c
+++ b/drivers/usb/core/config.c
@@ -958,14 +958,16 @@ int usb_get_bos_descriptor(struct usb_device *dev)
 	total_len -= length;
 
 	for (i = 0; i < num; i++) {
 		buffer += length;
 		cap = (struct usb_dev_cap_header *)buffer;
-		length = cap->bLength;
 
-		if (total_len < length)
+		if (total_len < sizeof(*cap) || total_len < cap->bLength) {
+			dev->bos->desc->bNumDeviceCaps = i;
 			break;
+		}
+		length = cap->bLength;
 		total_len -= length;
 
 		if (cap->bDescriptorType != USB_DT_DEVICE_CAPABILITY) {
 			dev_warn(ddev, "descriptor type invalid, skip\n");
 			continue;

Vulnerable code: 		length = cap->bLength;
		if (total_len < length)
Fixed code: 		if (total_len < sizeof(*cap) || total_len < cap->bLength) {
			dev->bos->desc->bNumDeviceCaps = i;
		}
		length = cap->bLength;
CVE-2017-10662: Insufficient Information (NVD-CWE-noinfo)
value: The sanity_check_raw_super function in fs/f2fs/super.c in the Linux kernel before 4.11.1 does not validate the segment count, which allows local users to gain privileges via unspecified vectors.
CWE description: There is insufficient information about the issue to classify it; details are unkown or unspecified.
CVSS v3 base score: 7.8
Published: 2017-08-19T18:29Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: fs/f2fs/super.c, include/linux/f2fs_fs.h
Commit date: 2017-05-02 21:19:48 -0700
Commit message: f2fs: sanity check segment count

F2FS uses 4 bytes to represent block address. As a result, supported
size of disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.

Signed-off-by: Jin Qian <jinqian@google.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

Diff: diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 97c07a5153e968..4cd3bee6775f23 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1492,10 +1492,17 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
 			le32_to_cpu(raw_super->meta_ino),
 			le32_to_cpu(raw_super->root_ino));
 		return 1;
 	}
 
+	if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
+		f2fs_msg(sb, KERN_INFO,
+			"Invalid segment count (%u)",
+			le32_to_cpu(raw_super->segment_count));
+		return 1;
+	}
+
 	/* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
 	if (sanity_check_area_boundary(sbi, bh))
 		return 1;
 
 	return 0;
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 639cbdf65e2bf7..093549e10ee267 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -299,10 +299,16 @@ struct f2fs_nat_block {
  * Not allow to change this.
  */
 #define SIT_VBLOCK_MAP_SIZE 64
 #define SIT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_sit_entry))
 
+/*
+ * F2FS uses 4 bytes to represent block address. As a result, supported size of
+ * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
+ */
+#define F2FS_MAX_SEGMENT       ((16 * 1024 * 1024) / 2)
+
 /*
  * Note that f2fs_sit_entry->vblocks has the following bit-field information.
  * [15:10] : allocation type such as CURSEG_XXXX_TYPE
  * [9:0] : valid block count
  */

Fixed code: 	if (le32_to_cpu(raw_super->segment_count) > F2FS_MAX_SEGMENT) {
		f2fs_msg(sb, KERN_INFO,
			"Invalid segment count (%u)",
			le32_to_cpu(raw_super->segment_count));
		return 1;
	}

/*
 * F2FS uses 4 bytes to represent block address. As a result, supported size of
 * disk is 16 TB and it equals to 16 * 1024 * 1024 / 2 segments.
 */
#define F2FS_MAX_SEGMENT       ((16 * 1024 * 1024) / 2)
CVE-2013-4205: Resource Management Errors (CWE-399)
value: Memory leak in the unshare_userns function in kernel/user_namespace.c in the Linux kernel before 3.10.6 allows local users to cause a denial of service (memory consumption) via an invalid CLONE_NEWUSER unshare call.
CWE description: Weaknesses in this category are related to improper management of system resources.
Published: 2013-08-25T03:27Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: kernel/user_namespace.c
Commit date: 2013-08-06 13:13:24 -0700
Commit message: userns: unshare_userns(&cred) should not populate cred on failure

unshare_userns(new_cred) does *new_cred = prepare_creds() before
create_user_ns() which can fail. However, the caller expects that
it doesn't need to take care of new_cred if unshare_userns() fails.

We could change the single caller, sys_unshare(), but I think it
would be more clean to avoid the side effects on failure, so with
this patch unshare_userns() does put_cred() itself and initializes
*new_cred only if create_user_ns() succeeeds.

Cc: stable@vger.kernel.org
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Diff: diff --git a/kernel/user_namespace.c b/kernel/user_namespace.c
index d8c30db06c5b75..6e50a44610eedc 100644
--- a/kernel/user_namespace.c
+++ b/kernel/user_namespace.c
@@ -103,20 +103,25 @@ int create_user_ns(struct cred *new)
 }
 
 int unshare_userns(unsigned long unshare_flags, struct cred **new_cred)
 {
 	struct cred *cred;
+	int err = -ENOMEM;
 
 	if (!(unshare_flags & CLONE_NEWUSER))
 		return 0;
 
 	cred = prepare_creds();
-	if (!cred)
-		return -ENOMEM;
+	if (cred) {
+		err = create_user_ns(cred);
+		if (err)
+			put_cred(cred);
+		else
+			*new_cred = cred;
+	}
 
-	*new_cred = cred;
-	return create_user_ns(cred);
+	return err;
 }
 
 void free_user_ns(struct user_namespace *ns)
 {
 	struct user_namespace *parent;

Vulnerable code: 	if (!cred)
		return -ENOMEM;
	*new_cred = cred;
	return create_user_ns(cred);
Fixed code: 	int err = -ENOMEM;
	if (cred) {
		err = create_user_ns(cred);
		if (err)
			put_cred(cred);
		else
			*new_cred = cred;
	}
	return err;
CVE-2010-4250: Resource Management Errors (CWE-399)
value: Memory leak in the inotify_init1 function in fs/notify/inotify/inotify_user.c in the Linux kernel before 2.6.37 allows local users to cause a denial of service (memory consumption) via vectors involving failed attempts to create files.
CWE description: Weaknesses in this category are related to improper management of system resources.
Published: 2012-06-21T23:55Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: fs/notify/inotify/inotify_user.c
Commit date: 2010-12-07 16:14:22 -0500
Commit message: inotify: stop kernel memory leak on file creation failure

If inotify_init is unable to allocate a new file for the new inotify
group we leak the new group.  This patch drops the reference on the
group on file allocation failure.

Reported-by: Vegard Nossum <vegard.nossum@gmail.com>
cc: stable@kernel.org
Signed-off-by: Eric Paris <eparis@redhat.com>

Diff: diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 444c305a468..4cd5d5d78f9 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -750,10 +750,11 @@ SYSCALL_DEFINE1(inotify_init1, int, flags)
 	ret = anon_inode_getfd("inotify", &inotify_fops, group,
 				  O_RDONLY | flags);
 	if (ret >= 0)
 		return ret;
 
+	fsnotify_put_group(group);
 	atomic_dec(&user->inotify_devs);
 out_free_uid:
 	free_uid(user);
 	return ret;
 }

Fixed code: 	fsnotify_put_group(group);
CVE-2014-9888: Permissions, Privileges, and Access Controls (CWE-264)
value: arch/arm/mm/dma-mapping.c in the Linux kernel before 3.13 on ARM platforms, as used in Android before 2016-08-05 on Nexus 5 and 7 (2013) devices, does not prevent executable DMA mappings, which might allow local users to gain privileges via a crafted application, aka Android internal bug 28803642 and Qualcomm internal bug CR642735.
CWE description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
CVSS v3 base score: 7.8
Published: 2016-08-06T10:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: arch/arm/mm/dma-mapping.c
Commit date: 2013-10-24 11:17:27 +0100
Commit message: ARM: dma-mapping: don't allow DMA mappings to be marked executable

DMA mapping permissions were being derived from pgprot_kernel directly
without using PAGE_KERNEL.  This causes them to be marked with executable
permission, which is not what we want.  Fix this.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

Diff: diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index f5e1a8471714cd..57438506d52461 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -685,11 +685,11 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
  * virtual and bus address for that space.
  */
 void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 		    gfp_t gfp, struct dma_attrs *attrs)
 {
-	pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
+	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	void *memory;
 
 	if (dma_alloc_from_coherent(dev, size, handle, &memory))
 		return memory;
 
@@ -698,11 +698,11 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
 }
 
 static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
 	dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
 {
-	pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
+	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
 	void *memory;
 
 	if (dma_alloc_from_coherent(dev, size, handle, &memory))
 		return memory;
 

Vulnerable code: 	pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
	pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
Fixed code: 	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
	pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
CVE-2014-1738: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: The raw_cmd_copyout function in drivers/block/floppy.c in the Linux kernel through 3.14.3 does not properly restrict access to certain pointers during processing of an FDRAWCMD ioctl call, which allows local users to obtain sensitive information from kernel heap memory by leveraging write access to a /dev/fd device.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Published: 2014-05-11T21:55Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/block/floppy.c
Commit date: 2014-05-05 07:46:56 -0700
Commit message: floppy: don't write kernel-only members to FDRAWCMD ioctl output

Do not leak kernel-only floppy_raw_cmd structure members to userspace.
This includes the linked-list pointer and the pointer to the allocated
DMA space.

Signed-off-by: Matthew Daley <mattd@bugfuzz.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Diff: diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 12251a68887197..fa9bb742df6e0b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3065,11 +3065,14 @@ static int raw_cmd_copyout(int cmd, void __user *param,
 				  struct floppy_raw_cmd *ptr)
 {
 	int ret;
 
 	while (ptr) {
-		ret = copy_to_user(param, ptr, sizeof(*ptr));
+		struct floppy_raw_cmd cmd = *ptr;
+		cmd.next = NULL;
+		cmd.kernel_data = NULL;
+		ret = copy_to_user(param, &cmd, sizeof(cmd));
 		if (ret)
 			return -EFAULT;
 		param += sizeof(struct floppy_raw_cmd);
 		if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length) {
 			if (ptr->length >= 0 &&

Vulnerable code: 		ret = copy_to_user(param, ptr, sizeof(*ptr));
Fixed code: 		struct floppy_raw_cmd cmd = *ptr;
		cmd.next = NULL;
		cmd.kernel_data = NULL;
		ret = copy_to_user(param, &cmd, sizeof(cmd));
CVE-2014-3181: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: Multiple stack-based buffer overflows in the magicmouse_raw_event function in drivers/hid/hid-magicmouse.c in the Magic Mouse HID driver in the Linux kernel through 3.16.3 allow physically proximate attackers to cause a denial of service (system crash) or possibly execute arbitrary code via a crafted device that provides a large amount of (1) EHCI or (2) XHCI data associated with an event.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
Published: 2014-09-28T10:55Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/hid/hid-magicmouse.c
Commit date: 2014-08-27 09:14:39 +0200
Commit message: HID: magicmouse: sanity check report size in raw_event() callback

The report passed to us from transport driver could potentially be
arbitrarily large, therefore we better sanity-check it so that
magicmouse_emit_touch() gets only valid values of raw_id.

Cc: stable@vger.kernel.org
Reported-by: Steven Vittitoe <scvitti@google.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>

Diff: diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c
index ecc2cbf300cc39..29a74c1efcb85f 100644
--- a/drivers/hid/hid-magicmouse.c
+++ b/drivers/hid/hid-magicmouse.c
@@ -288,10 +288,15 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 	case TRACKPAD_REPORT_ID:
 		/* Expect four bytes of prefix, and N*9 bytes of touch data. */
 		if (size < 4 || ((size - 4) % 9) != 0)
 			return 0;
 		npoints = (size - 4) / 9;
+		if (npoints > 15) {
+			hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
+					size);
+			return 0;
+		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 9 + 4);
 
 		clicks = data[1];
@@ -305,10 +310,15 @@ static int magicmouse_raw_event(struct hid_device *hdev,
 	case MOUSE_REPORT_ID:
 		/* Expect six bytes of prefix, and N*8 bytes of touch data. */
 		if (size < 6 || ((size - 6) % 8) != 0)
 			return 0;
 		npoints = (size - 6) / 8;
+		if (npoints > 15) {
+			hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n",
+					size);
+			return 0;
+		}
 		msc->ntouches = 0;
 		for (ii = 0; ii < npoints; ii++)
 			magicmouse_emit_touch(msc, ii, data + ii * 8 + 6);
 
 		/* When emulating three-button mode, it is important

Fixed code: 		if (npoints > 15) {
			hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n",
					size);
			return 0;
		}
		if (npoints > 15) {
			hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n",
					size);
			return 0;
		}
CVE-2014-1446: Resource Management Errors (CWE-399)
value: The yam_ioctl function in drivers/net/hamradio/yam.c in the Linux kernel before 3.12.8 does not initialize a certain structure member, which allows local users to obtain sensitive information from kernel memory by leveraging the CAP_NET_ADMIN capability for an SIOCYAMGCFG ioctl call.
CWE description: Weaknesses in this category are related to improper management of system resources.
Published: 2014-01-18T22:55Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/net/hamradio/yam.c
Commit date: 2013-12-19 15:09:38 -0500
Commit message: hamradio/yam: fix info leak in ioctl

The yam_ioctl() code fails to initialise the cmd field
of the struct yamdrv_ioctl_cfg. Add an explicit memset(0)
before filling the structure to avoid the 4-byte info leak.

Signed-off-by: Salva Peiró <speiro@ai2.upv.es>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 1971411574db1c..61dd2447e1bb4e 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -1055,10 +1055,11 @@ static int yam_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 			yp->slotcnt = yp->slot / 10;
 		}
 		break;
 
 	case SIOCYAMGCFG:
+		memset(&yi, 0, sizeof(yi));
 		yi.cfg.mask = 0xffffffff;
 		yi.cfg.iobase = yp->iobase;
 		yi.cfg.irq = yp->irq;
 		yi.cfg.bitrate = yp->bitrate;
 		yi.cfg.baudrate = yp->baudrate;

Fixed code: 		memset(&yi, 0, sizeof(yi));
CVE-2015-4176: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: fs/namespace.c in the Linux kernel before 4.0.2 does not properly support mount connectivity, which allows local users to read arbitrary files by leveraging user-namespace root access for deletion of a file or directory.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
CVSS v3 base score: 5.5
Published: 2016-05-02T10:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: fs/namespace.c
Commit date: 2015-04-09 11:39:57 -0500
Commit message: mnt: Update detach_mounts to leave mounts connected

Now that it is possible to lazily unmount an entire mount tree and
leave the individual mounts connected to each other add a new flag
UMOUNT_CONNECTED to umount_tree to force this behavior and use
this flag in detach_mounts.

This closes a bug where the deletion of a file or directory could
trigger an unmount and reveal data under a mount point.

Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>

Diff: diff --git a/fs/namespace.c b/fs/namespace.c
index e8f7f8c58c3c64..1f4f9dac6e5af8 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -1346,10 +1346,11 @@ static inline void namespace_lock(void)
 }
 
 enum umount_tree_flags {
 	UMOUNT_SYNC = 1,
 	UMOUNT_PROPAGATE = 2,
+	UMOUNT_CONNECTED = 4,
 };
 /*
  * mount_lock must be held
  * namespace_sem must be held for write
  */
@@ -1384,11 +1385,14 @@ static void umount_tree(struct mount *mnt, enum umount_tree_flags how)
 		__touch_mnt_namespace(p->mnt_ns);
 		p->mnt_ns = NULL;
 		if (how & UMOUNT_SYNC)
 			p->mnt.mnt_flags |= MNT_SYNC_UMOUNT;
 
-		disconnect = !IS_MNT_LOCKED_AND_LAZY(p);
+		disconnect = !(((how & UMOUNT_CONNECTED) &&
+				mnt_has_parent(p) &&
+				(p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) ||
+			       IS_MNT_LOCKED_AND_LAZY(p));
 
 		pin_insert_group(&p->mnt_umount, &p->mnt_parent->mnt,
 				 disconnect ? &unmounted : NULL);
 		if (mnt_has_parent(p)) {
 			mnt_add_count(p->mnt_parent, -1);
@@ -1527,11 +1531,11 @@ void __detach_mounts(struct dentry *dentry)
 			list_for_each_entry_safe(p, tmp, &mnt->mnt_mounts,  mnt_child) {
 				hlist_add_head(&p->mnt_umount.s_list, &unmounted);
 				umount_mnt(p);
 			}
 		}
-		else umount_tree(mnt, 0);
+		else umount_tree(mnt, UMOUNT_CONNECTED);
 	}
 	unlock_mount_hash();
 	put_mountpoint(mp);
 out_unlock:
 	namespace_unlock();

Vulnerable code: 		disconnect = !IS_MNT_LOCKED_AND_LAZY(p);
		else umount_tree(mnt, 0);
Fixed code: 	UMOUNT_CONNECTED = 4,
		disconnect = !(((how & UMOUNT_CONNECTED) &&
				mnt_has_parent(p) &&
				(p->mnt_parent->mnt.mnt_flags & MNT_UMOUNT)) ||
			       IS_MNT_LOCKED_AND_LAZY(p));
		else umount_tree(mnt, UMOUNT_CONNECTED);
CVE-2012-2123: Permissions, Privileges, and Access Controls (CWE-264)
value: The cap_bprm_set_creds function in security/commoncap.c in the Linux kernel before 3.3.3 does not properly handle the use of file system capabilities (aka fcaps) for implementing a privileged executable file, which allows local users to bypass intended personality restrictions via a crafted application, as demonstrated by an attack that uses a parent process to disable ASLR.
CWE description: Weaknesses in this category are related to the management of permissions, privileges, and other security features that are used to perform access control.
Published: 2012-05-17T11:00Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: security/commoncap.c
Commit date: 2012-04-18 12:37:56 +1000
Commit message: fcaps: clear the same personality flags as suid when fcaps are used

If a process increases permissions using fcaps all of the dangerous
personality flags which are cleared for suid apps should also be cleared.
Thus programs given priviledge with fcaps will continue to have address space
randomization enabled even if the parent tried to disable it to make it
easier to attack.

Signed-off-by: Eric Paris <eparis@redhat.com>
Reviewed-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>

Diff: diff --git a/security/commoncap.c b/security/commoncap.c
index 0cf4b53480a77..0ecf4ba321cbe 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -503,10 +503,15 @@ int cap_bprm_set_creds(struct linux_binprm *bprm)
 		if (new->euid == 0)
 			effective = true;
 	}
 skip:
 
+	/* if we have fs caps, clear dangerous personality flags */
+	if (!cap_issubset(new->cap_permitted, old->cap_permitted))
+		bprm->per_clear |= PER_CLEAR_ON_SETID;
+
+
 	/* Don't let someone trace a set[ug]id/setpcap binary with the revised
 	 * credentials unless they have the appropriate permit
 	 */
 	if ((new->euid != old->uid ||
 	     new->egid != old->gid ||

Fixed code: 	/* if we have fs caps, clear dangerous personality flags */
	if (!cap_issubset(new->cap_permitted, old->cap_permitted))
		bprm->per_clear |= PER_CLEAR_ON_SETID;
CVE-2016-2188: Other (NVD-CWE-Other)
value: The iowarrior_probe function in drivers/usb/misc/iowarrior.c in the Linux kernel before 4.5.1 allows physically proximate attackers to cause a denial of service (NULL pointer dereference and system crash) via a crafted endpoints value in a USB device descriptor.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
CVSS v3 base score: 4.6
Published: 2016-05-02T10:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/usb/misc/iowarrior.c
Commit date: 2016-03-18 09:19:02 -0700
Commit message: USB: iowarrior: fix oops with malicious USB descriptors

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 <ralf@spenneberg.net>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Diff: diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index c6bfd13f6c92f..1950e87b42190 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -785,10 +785,16 @@ static int iowarrior_probe(struct usb_interface *interface,
 	dev->interface = interface;
 
 	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;
 
 		if (usb_endpoint_is_int_in(endpoint))

Fixed code: 	if (iface_desc->desc.bNumEndpoints < 1) {
		dev_err(&interface->dev, "Invalid number of endpoints\n");
		retval = -EINVAL;
		goto error;
	}
CVE-2013-1928: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: The do_video_set_spu_palette function in fs/compat_ioctl.c in the Linux kernel before 3.6.5 on unspecified architectures lacks a certain error check, which might allow local users to obtain sensitive information from kernel stack memory via a crafted VIDEO_SET_SPU_PALETTE ioctl call on a /dev/dvb device.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
Published: 2013-04-29T14:55Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: fs/compat_ioctl.c
Commit date: 2012-10-25 14:37:53 -0700
Commit message: fs/compat_ioctl.c: VIDEO_SET_SPU_PALETTE missing error check

The compat ioctl for VIDEO_SET_SPU_PALETTE was missing an error check
while converting ioctl arguments.  This could lead to leaking kernel
stack contents into userspace.

Patch extracted from existing fix in grsecurity.

Signed-off-by: Kees Cook <keescook@chromium.org>
Cc: David Miller <davem@davemloft.net>
Cc: Brad Spengler <spender@grsecurity.net>
Cc: PaX Team <pageexec@freemail.hu>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Diff: diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index f5054025f9da7c..4c6285fff598e1 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -208,10 +208,12 @@ static int do_video_set_spu_palette(unsigned int fd, unsigned int cmd,
 	compat_uptr_t palp;
 	int length, err;
 
 	err  = get_user(palp, &up->palette);
 	err |= get_user(length, &up->length);
+	if (err)
+		return -EFAULT;
 
 	up_native = compat_alloc_user_space(sizeof(struct video_spu_palette));
 	err  = put_user(compat_ptr(palp), &up_native->palette);
 	err |= put_user(length, &up_native->length);
 	if (err)

Fixed code: 	if (err)
		return -EFAULT;
CVE-2014-7843: DEPRECATED: Code (CWE-17)
value: The __clear_user function in arch/arm64/lib/clear_user.S in the Linux kernel before 3.17.4 on the ARM64 platform allows local users to cause a denial of service (system crash) by reading one byte beyond a /dev/zero page boundary.
CWE description: This entry has been deprecated.  It was originally used for organizing the Development View (CWE-699) and some other views, but it introduced unnecessary complexity and depth to the resulting tree.
Published: 2014-11-30T01:59Z
Repository: https://github.com/torvalds/linux
Language: Other
Files changed: arch/arm64/lib/clear_user.S
Commit date: 2014-11-13 15:21:26 +0000
Commit message: arm64: __clear_user: handle exceptions on strb

ARM64 currently doesn't fix up faults on the single-byte (strb) case of
__clear_user... which means that we can cause a nasty kernel panic as an
ordinary user with any multiple PAGE_SIZE+1 read from /dev/zero.
i.e.: dd if=/dev/zero of=foo ibs=1 count=1 (or ibs=65537, etc.)

This is a pretty obscure bug in the general case since we'll only
__do_kernel_fault (since there's no extable entry for pc) if the
mmap_sem is contended. However, with CONFIG_DEBUG_VM enabled, we'll
always fault.

if (!down_read_trylock(&mm->mmap_sem)) {
	if (!user_mode(regs) && !search_exception_tables(regs->pc))
		goto no_context;
retry:
	down_read(&mm->mmap_sem);
} else {
	/*
	 * The above down_read_trylock() might have succeeded in
	 * which
	 * case, we'll have missed the might_sleep() from
	 * down_read().
	 */
	might_sleep();
	if (!user_mode(regs) && !search_exception_tables(regs->pc))
		goto no_context;
}

Fix that by adding an extable entry for the strb instruction, since it
touches user memory, similar to the other stores in __clear_user.

Signed-off-by: Kyle McMartin <kyle@redhat.com>
Reported-by: Miloš Prchlík <mprchlik@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

Diff: diff --git a/arch/arm64/lib/clear_user.S b/arch/arm64/lib/clear_user.S
index 6e0ed93d51fe18..c17967fdf5f600 100644
--- a/arch/arm64/lib/clear_user.S
+++ b/arch/arm64/lib/clear_user.S
@@ -44,11 +44,11 @@ USER(9f, str	wzr, [x0], #4	)
 	b.mi	4f
 USER(9f, strh	wzr, [x0], #2	)
 	sub	x1, x1, #2
 4:	adds	x1, x1, #1
 	b.mi	5f
-	strb	wzr, [x0]
+USER(9f, strb	wzr, [x0]	)
 5:	mov	x0, #0
 	ret
 ENDPROC(__clear_user)
 
 	.section .fixup,"ax"

Vulnerable code: 	strb	wzr, [x0]
Fixed code: USER(9f, strb	wzr, [x0]	)
CVE-2016-9793: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: The sock_setsockopt function in net/core/sock.c in the Linux kernel before 4.8.14 mishandles negative values of sk_sndbuf and sk_rcvbuf, which allows local users to cause a denial of service (memory corruption and system crash) or possibly have unspecified other impact by leveraging the CAP_NET_ADMIN capability for a crafted setsockopt system call with the (1) SO_SNDBUFFORCE or (2) SO_RCVBUFFORCE option.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
CVSS v3 base score: 7.8
Published: 2016-12-28T07:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: net/core/sock.c
Commit date: 2016-12-02 14:10:14 -0500
Commit message: net: avoid signed overflows for SO_{SND|RCV}BUFFORCE

CAP_NET_ADMIN users should not be allowed to set negative
sk_sndbuf or sk_rcvbuf values, as it can lead to various memory
corruptions, crashes, OOM...

Note that before commit 82981930125a ("net: cleanups in
sock_setsockopt()"), the bug was even more serious, since SO_SNDBUF
and SO_RCVBUF were vulnerable.

This needs to be backported to all known linux kernels.

Again, many thanks to syzkaller team for discovering this gem.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Andrey Konovalov <andreyknvl@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/net/core/sock.c b/net/core/sock.c
index 5e3ca414357e24..00a074dbfe9bf1 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -713,11 +713,11 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 		 * are treated in BSD as hints
 		 */
 		val = min_t(u32, val, sysctl_wmem_max);
 set_sndbuf:
 		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
-		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
+		sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
 		/* Wake up sending tasks if we upped the value. */
 		sk->sk_write_space(sk);
 		break;
 
 	case SO_SNDBUFFORCE:
@@ -749,11 +749,11 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
 		 *
 		 * And after considering the possible alternatives,
 		 * returning the value we actually used in getsockopt
 		 * is the most desirable behavior.
 		 */
-		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
+		sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
 		break;
 
 	case SO_RCVBUFFORCE:
 		if (!capable(CAP_NET_ADMIN)) {
 			ret = -EPERM;

Vulnerable code: 		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
Fixed code: 		sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
		sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
CVE-2014-8173: Other (NVD-CWE-Other)
value: The pmd_none_or_trans_huge_or_clear_bad function in include/asm-generic/pgtable.h in the Linux kernel before 3.13 on NUMA systems does not properly determine whether a Page Middle Directory (PMD) entry is a transparent huge-table entry, which allows local users to cause a denial of service (NULL pointer dereference and system crash) or possibly have unspecified other impact via a crafted MADV_WILLNEED madvise system call that leverages the absence of a page-table lock.
CWE description: NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.
Published: 2015-03-16T10:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: include/asm-generic/pgtable.h
Commit date: 2013-12-20 12:17:03 -0800
Commit message: mm: Fix NULL pointer dereference in madvise(MADV_WILLNEED) support

Sasha Levin found a NULL pointer dereference that is due to a missing
page table lock, which in turn is due to the pmd entry in question being
a transparent huge-table entry.

The code - introduced in commit 1998cc048901 ("mm: make
madvise(MADV_WILLNEED) support swap file prefetch") - correctly checks
for this situation using pmd_none_or_trans_huge_or_clear_bad(), but it
turns out that that function doesn't work correctly.

pmd_none_or_trans_huge_or_clear_bad() expected that pmd_bad() would
trigger if the transparent hugepage bit was set, but it doesn't do that
if pmd_numa() is also set. Note that the NUMA bit only gets set on real
NUMA machines, so people trying to reproduce this on most normal
development systems would never actually trigger this.

Fix it by removing the very subtle (and subtly incorrect) expectation,
and instead just checking pmd_trans_huge() explicitly.

Reported-by: Sasha Levin <sasha.levin@oracle.com>
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
[ Additionally remove the now stale test for pmd_trans_huge() inside the
  pmd_bad() case - Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Diff: diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index b12079afbd5f27..db092345894097 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -597,15 +597,14 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
 	 * confused.
 	 */
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 	barrier();
 #endif
-	if (pmd_none(pmdval))
+	if (pmd_none(pmdval) || pmd_trans_huge(pmdval))
 		return 1;
 	if (unlikely(pmd_bad(pmdval))) {
-		if (!pmd_trans_huge(pmdval))
-			pmd_clear_bad(pmd);
+		pmd_clear_bad(pmd);
 		return 1;
 	}
 	return 0;
 }
 

Vulnerable code: 	if (pmd_none(pmdval))
		if (!pmd_trans_huge(pmdval))
			pmd_clear_bad(pmd);
Fixed code: 	if (pmd_none(pmdval) || pmd_trans_huge(pmdval))
		pmd_clear_bad(pmd);
CVE-2015-8569: Exposure of Sensitive Information to an Unauthorized Actor (CWE-200)
value: The (1) pptp_bind and (2) pptp_connect functions in drivers/net/ppp/pptp.c in the Linux kernel through 4.3.3 do not verify an address length, which allows local users to obtain sensitive information from kernel memory and bypass the KASLR protection mechanism via a crafted application.
CWE description: The product exposes sensitive information to an actor that is not explicitly authorized to have access to that information.
CVSS v3 base score: 2.3
Published: 2015-12-28T11:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/net/ppp/pptp.c
Commit date: 2015-12-15 00:29:34 -0500
Commit message: pptp: verify sockaddr_len in pptp_bind() and pptp_connect()

Reported-by: Dmitry Vyukov <dvyukov@gmail.com>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
index fc69e41d09506e..597c53e0a2ecce 100644
--- a/drivers/net/ppp/pptp.c
+++ b/drivers/net/ppp/pptp.c
@@ -417,10 +417,13 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
 	struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
 	struct pppox_sock *po = pppox_sk(sk);
 	struct pptp_opt *opt = &po->proto.pptp;
 	int error = 0;
 
+	if (sockaddr_len < sizeof(struct sockaddr_pppox))
+		return -EINVAL;
+
 	lock_sock(sk);
 
 	opt->src_addr = sp->sa_addr.pptp;
 	if (add_chan(po))
 		error = -EBUSY;
@@ -438,10 +441,13 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
 	struct pptp_opt *opt = &po->proto.pptp;
 	struct rtable *rt;
 	struct flowi4 fl4;
 	int error = 0;
 
+	if (sockaddr_len < sizeof(struct sockaddr_pppox))
+		return -EINVAL;
+
 	if (sp->sa_protocol != PX_PROTO_PPTP)
 		return -EINVAL;
 
 	if (lookup_chan_dst(sp->sa_addr.pptp.call_id, sp->sa_addr.pptp.sin_addr.s_addr))
 		return -EALREADY;

Fixed code: 	if (sockaddr_len < sizeof(struct sockaddr_pppox))
		return -EINVAL;

	if (sockaddr_len < sizeof(struct sockaddr_pppox))
		return -EINVAL;
CVE-2015-2922: DEPRECATED: Code (CWE-17)
value: The ndisc_router_discovery function in net/ipv6/ndisc.c in the Neighbor Discovery (ND) protocol implementation in the IPv6 stack in the Linux kernel before 3.19.6 allows remote attackers to reconfigure a hop-limit setting via a small hop_limit value in a Router Advertisement (RA) message.
CWE description: This entry has been deprecated.  It was originally used for organizing the Development View (CWE-699) and some other views, but it introduced unnecessary complexity and depth to the resulting tree.
Published: 2015-05-27T10:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: net/ipv6/ndisc.c
Commit date: 2015-03-25 11:41:08 -0400
Commit message: ipv6: Don't reduce hop limit for an interface

A local route may have a lower hop_limit set than global routes do.

RFC 3756, Section 4.2.7, "Parameter Spoofing"

>   1.  The attacker includes a Current Hop Limit of one or another small
>       number which the attacker knows will cause legitimate packets to
>       be dropped before they reach their destination.

>   As an example, one possible approach to mitigate this threat is to
>   ignore very small hop limits.  The nodes could implement a
>   configurable minimum hop limit, and ignore attempts to set it below
>   said limit.

Signed-off-by: D.S. Ljungmark <ljungmark@modio.se>
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 471ed24aabaec4..14ecdaf06bf749 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1216,11 +1216,18 @@ static void ndisc_router_discovery(struct sk_buff *skb)
 	}
 
 	if (rt)
 		rt6_set_expires(rt, jiffies + (HZ * lifetime));
 	if (ra_msg->icmph.icmp6_hop_limit) {
-		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+		/* Only set hop_limit on the interface if it is higher than
+		 * the current hop_limit.
+		 */
+		if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) {
+			in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
+		} else {
+			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n");
+		}
 		if (rt)
 			dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
 				       ra_msg->icmph.icmp6_hop_limit);
 	}
 

Vulnerable code: 		in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
Fixed code: 		/* Only set hop_limit on the interface if it is higher than
		 * the current hop_limit.
		 */
		if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) {
			in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
		} else {
			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n");
		}
CVE-2014-7842: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition') (CWE-362)
value: Race condition in arch/x86/kvm/x86.c in the Linux kernel before 3.17.4 allows guest OS users to cause a denial of service (guest OS crash) via a crafted application that performs an MMIO transaction or a PIO transaction to trigger a guest userspace emulation error report, a similar issue to CVE-2010-5313.
CWE description: The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.
Published: 2014-11-30T01:59Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: arch/x86/kvm/x86.c
Commit date: 2014-09-24 14:07:49 +0200
Commit message: KVM: x86: Don't report guest userspace emulation error to userspace

Commit fc3a9157d314 ("KVM: X86: Don't report L2 emulation failures to
user-space") disabled the reporting of L2 (nested guest) emulation failures to
userspace due to race-condition between a vmexit and the instruction emulator.
The same rational applies also to userspace applications that are permitted by
the guest OS to access MMIO area or perform PIO.

This patch extends the current behavior - of injecting a #UD instead of
reporting it to userspace - also for guest userspace code.

Signed-off-by: Nadav Amit <namit@cs.technion.ac.il>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Diff: diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2d7f65daa8d098..e46da50e2cec51 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4998,11 +4998,11 @@ static int handle_emulation_failure(struct kvm_vcpu *vcpu)
 {
 	int r = EMULATE_DONE;
 
 	++vcpu->stat.insn_emulation_fail;
 	trace_kvm_emulate_insn_failed(vcpu);
-	if (!is_guest_mode(vcpu)) {
+	if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
 		vcpu->run->exit_reason = KVM_EXIT_INTERNAL_ERROR;
 		vcpu->run->internal.suberror = KVM_INTERNAL_ERROR_EMULATION;
 		vcpu->run->internal.ndata = 0;
 		r = EMULATE_FAIL;
 	}

Vulnerable code: 	if (!is_guest_mode(vcpu)) {
Fixed code: 	if (!is_guest_mode(vcpu) && kvm_x86_ops->get_cpl(vcpu) == 0) {
CVE-2013-2128: Uncontrolled Resource Consumption (CWE-400)
value: The tcp_read_sock function in net/ipv4/tcp.c in the Linux kernel before 2.6.34 does not properly manage skb consumption, which allows local users to cause a denial of service (system crash) via a crafted splice system call for a TCP socket.
CWE description: The product does not properly control the allocation and maintenance of a limited resource, thereby enabling an actor to influence the amount of resources consumed, eventually leading to the exhaustion of available resources.
CVSS v3 base score: 5.5
Published: 2013-06-07T14:03Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: net/ipv4/tcp.c
Commit date: 2010-03-30 13:56:01 -0700
Commit message: net: Fix oops from tcp_collapse() when using splice()

tcp_read_sock() can have a eat skbs without immediately advancing copied_seq.
This can cause a panic in tcp_collapse() if it is called as a result
of the recv_actor dropping the socket lock.

A userspace program that splices data from a socket to either another
socket or to a file can trigger this bug.

Signed-off-by: Steven J. Magnani <steve@digidescorp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 6afb6d8662b2ce..2c75f891914e83 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1366,10 +1366,11 @@ int tcp_read_sock(struct sock *sk, read_descriptor_t *desc,
 			break;
 		}
 		sk_eat_skb(sk, skb, 0);
 		if (!desc->count)
 			break;
+		tp->copied_seq = seq;
 	}
 	tp->copied_seq = seq;
 
 	tcp_rcv_space_adjust(sk);
 

Fixed code: 		tp->copied_seq = seq;
CVE-2013-1929: Improper Restriction of Operations within the Bounds of a Memory Buffer (CWE-119)
value: Heap-based buffer overflow in the tg3_read_vpd function in drivers/net/ethernet/broadcom/tg3.c in the Linux kernel before 3.8.6 allows physically proximate attackers to cause a denial of service (system crash) or possibly execute arbitrary code via crafted firmware that specifies a long string in the Vital Product Data (VPD) data structure.
CWE description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
Published: 2013-06-07T14:03Z
Repository: https://github.com/torvalds/linux
Language: C
Files changed: drivers/net/ethernet/broadcom/tg3.c
Commit date: 2013-03-27 14:06:41 -0400
Commit message: tg3: fix length overflow in VPD firmware parsing

Commit 184b89044fb6e2a74611dafa69b1dce0d98612c6 ("tg3: Use VPD fw version
when present") introduced VPD parsing that contained a potential length
overflow.

Limit the hardware's reported firmware string length (max 255 bytes) to
stay inside the driver's firmware string length (32 bytes). On overflow,
truncate the formatted firmware string instead of potentially overwriting
portions of the tg3 struct.

http://cansecwest.com/slides/2013/PrivateCore%20CSW%202013.pdf

Signed-off-by: Kees Cook <keescook@chromium.org>
Reported-by: Oded Horovitz <oded@privatecore.com>
Reported-by: Brad Spengler <spender@grsecurity.net>
Cc: stable@vger.kernel.org
Cc: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Diff: diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 67d2663b3974ae..17a972734ba746 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -14602,12 +14602,15 @@ static void tg3_read_vpd(struct tg3 *tp)
 
 		j += PCI_VPD_INFO_FLD_HDR_SIZE;
 		if (j + len > block_end)
 			goto partno;
 
-		memcpy(tp->fw_ver, &vpd_data[j], len);
-		strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
+		if (len >= sizeof(tp->fw_ver))
+			len = sizeof(tp->fw_ver) - 1;
+		memset(tp->fw_ver, 0, sizeof(tp->fw_ver));
+		snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len,
+			 &vpd_data[j]);
 	}
 
 partno:
 	i = pci_vpd_find_info_keyword(vpd_data, i, rosize,
 				      PCI_VPD_RO_KEYWORD_PARTNO);

Vulnerable code: 		memcpy(tp->fw_ver, &vpd_data[j], len);
		strncat(tp->fw_ver, " bc ", vpdlen - len - 1);
Fixed code: 		if (len >= sizeof(tp->fw_ver))
			len = sizeof(tp->fw_ver) - 1;
		memset(tp->fw_ver, 0, sizeof(tp->fw_ver));
		snprintf(tp->fw_ver, sizeof(tp->fw_ver), "%.*s bc ", len,
			 &vpd_data[j]);