Release linux (4.2.6-2).

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIVAwUAVmHQq+e/yOyVhhEJAQoKGw/+L3omCHQc+jEfre5v9KaKEFfDn/5wh2fF
 C1U2n9tW3Dje//k1t5IalN2bxugjg86lvyobnNo+fP3GxbEftr0OJFKspWDlREcT
 epebhVQwzIY5ilNaayIqU8+wO6N/Ocy7kDspDjT7aqKFs5ZxmKReR6mvqZzYtJX5
 W6lrinX03bcBLaFGgHOFJeI/6JapVC8LxQPiek2NYuEAnMsGdN0CDpZRqsmgNtjn
 PBYbfsfk/JMubr+2ddksZcQTPKoK5fcbbgHRgN76eKDEGZ9XychWlhA8VANw+dhx
 I572cypGXxfV6AoLky7VcP8WKmWQVNWsXTMaFd8j0703xF/ands/Ic8mZOiftfh9
 9Qg6yhDt16zBPk+6Ct2ce04TAEdaY6Zr4WZdYphgVrkoZQrMc1PUVJkg6cPC7bKZ
 XANEWus39vJmHIM82ETY2BpZ8+kdFqehWpo0PM8kCfL06fAm3inIsKDa7iyrpLbJ
 DSdrQiRPeGr9jjB6mOuAIw/Otlq+M8kHfBGD1lgf7luLWOuP7z67mj2kjhNUP+pI
 yKZI6+xbwZ79+Sr6ZFQBPDVH400zbvinV0B3xV+ZUU/3ze6j3QVFEuA9KsqAVqN6
 R9CiQJ3lP3SL64P9FMQDfQL75HD0CZnEULlqDIYAzBmtz2B/H0lhrODoO2oZHHKT
 jmxxrVLxbPg=
 =jlfq
 -----END PGP SIGNATURE-----

Merge tag 'debian/4.2.6-2'

Exclude one new patch that's already in 4.3, and the ABI stuff.

Remove items from the open changelog entry that are now redundant.
This commit is contained in:
Ben Hutchings 2015-12-04 18:03:02 +00:00
commit 12dc87aa9c
11 changed files with 1006 additions and 20 deletions

54
debian/changelog vendored
View File

@ -1,7 +1,6 @@
linux (4.3-1~exp2) UNRELEASED; urgency=medium
[ Ben Hutchings ]
* qxl: Enable by default (Closes: #779515)
* mv643xx_eth: Re-enable TSO, fixed upstream in 4.3
* debian/control: Move patchutils from Build-Depends to Build-Depends-Indep,
as we only use filterdiff when building linux-source-<version>
@ -9,24 +8,10 @@ linux (4.3-1~exp2) UNRELEASED; urgency=medium
builds only linux-libc-dev (Closes: #695243)
* debian/control: Add ':any' to Build-Depends on python3, to support cross-
bootstrap
* [s390*] Update linux-compiler metapackage to gcc-4.9
* firmware_class: Fix condition in directory search loop (Closes: #804862)
* [x86] input: Enable MOUSE_ELAN_I2C as module, MOUSE_ELAN_I2C_I2C and
MOUSE_ELAN_I2C_SMBUS (Closes: #791631)
* [armhf] hsi: Enable CMT_SPEECH as module (Closes: #791819)
* [armhf] power: Enable BATTERY_RX51 as module (Closes: #791820)
* [x86] psmouse: Enable MOUSE_PS2_VMMOUSE (Closes: #802929)
- linux-image: Add versioned Breaks on xserver-xorg-input-vmmouse to
avoid driver conflicts
* [armhf] Enable new drivers for Allwinner chips (Closes: #804856)
- crypto: Enable CRYPTO_DEV_SUN4I_SS as module
- musb: Enable USB_MUSB_SUNXI as module
* [armhf] udeb: Add stmmac platform modules dwmac-generic, dwmac-socfpga
and dwmac-sunxi to nic-modules (Closes: #805098)
* aufs: Update support patches to aufs4.3-20151116
* wireless: Enable WL_MEDIATEK, MT7601U as module
* [x86] drm/i915: shut up gen8+ SDE irq dmesg noise (Closes: #806304)
* [armhf] regulator: Enable REGULATOR_PFUZE100 as module (Closes: #806284)
* [armhf] USB: Change USB, USB_GADGET, and various drivers from built-in to
modules
- musb: Enable USB_MUSB_DUAL_ROLE
@ -93,6 +78,45 @@ linux (4.3~rc3-1~exp1) experimental; urgency=medium
-- Ben Hutchings <ben@decadent.org.uk> Sun, 27 Sep 2015 21:02:54 +0100
linux (4.2.6-2) unstable; urgency=medium
[ Salvatore Bonaccorso ]
* [x86] KVM: svm: unconditionally intercept #DB (CVE-2015-8104)
* [x86] KVM: rename update_db_bp_intercept to update_bp_intercept
[ Ian Campbell ]
* [x86] Xen: expose a more realistic max p2m size in the shared info, fixes
migration (Closes: #797205)
[ Ben Hutchings ]
* media: usbvision: fix crash on detecting device with invalid configuration
(CVE-2015-7833, partly fixed in 4.2.6-1)
* udeb: Add dm-service-time to multipath-modules (Closes: #806131)
* unix: avoid use-after-free in ep_remove_wait_queue (CVE-2013-7446)
* isdn_ppp: Add checks for allocation failure in isdn_ppp_open()
* ppp, slip: Validate VJ compression slot parameters completely
(CVE-2015-7799)
* Btrfs: fix truncation of compressed and inlined extents (CVE-2015-8374)
* netfilter: Enable NFT_DUP_IPV4, NFT_DUP_IPV6 as modules (Closes: #803370)
* [x86] Enable PINCTRL_BAYTRAIL (Closes: #797949)
* qxl: Enable by default (Closes: #779515)
* [s390*] Update linux-compiler metapackage to gcc-4.9
* firmware_class: Fix condition in directory search loop (Closes: #804862)
* [x86] input: Enable MOUSE_ELAN_I2C as module, MOUSE_ELAN_I2C_I2C and
MOUSE_ELAN_I2C_SMBUS (Closes: #791631)
* [armhf] hsi: Enable CMT_SPEECH as module (Closes: #791819)
* [armhf] power: Enable BATTERY_RX51 as module (Closes: #791820)
* [x86] psmouse: Enable MOUSE_PS2_VMMOUSE (Closes: #802929)
- linux-image: Add versioned Breaks on xserver-xorg-input-vmmouse to
avoid driver conflicts
* [armhf] udeb: Add stmmac platform modules dwmac-generic, dwmac-socfpga
and dwmac-sunxi to nic-modules (Closes: #805098)
* wireless: Enable WL_MEDIATEK, MT7601U as module
* [x86] drm/i915: shut up gen8+ SDE irq dmesg noise (Closes: #806304)
* [armhf] regulator: Enable REGULATOR_PFUZE100 as module (Closes: #806284)
-- Ben Hutchings <ben@decadent.org.uk> Fri, 04 Dec 2015 02:26:51 +0000
linux (4.2.6-1) unstable; urgency=medium
* New upstream stable update:

View File

@ -1,2 +1,3 @@
dm-multipath
dm-round-robin
dm-service-time

View File

@ -0,0 +1,283 @@
From: Filipe Manana <fdmanana@suse.com>
Date: Fri, 16 Oct 2015 12:34:25 +0100
Subject: Btrfs: fix truncation of compressed and inlined extents
Origin: https://git.kernel.org/linus/0305cd5f7fca85dae392b9ba85b116896eb7c1c7
When truncating a file to a smaller size which consists of an inline
extent that is compressed, we did not discard (or made unusable) the
data between the new file size and the old file size, wasting metadata
space and allowing for the truncated data to be leaked and the data
corruption/loss mentioned below.
We were also not correctly decrementing the number of bytes used by the
inode, we were setting it to zero, giving a wrong report for callers of
the stat(2) syscall. The fsck tool also reported an error about a mismatch
between the nbytes of the file versus the real space used by the file.
Now because we weren't discarding the truncated region of the file, it
was possible for a caller of the clone ioctl to actually read the data
that was truncated, allowing for a security breach without requiring root
access to the system, using only standard filesystem operations. The
scenario is the following:
1) User A creates a file which consists of an inline and compressed
extent with a size of 2000 bytes - the file is not accessible to
any other users (no read, write or execution permission for anyone
else);
2) The user truncates the file to a size of 1000 bytes;
3) User A makes the file world readable;
4) User B creates a file consisting of an inline extent of 2000 bytes;
5) User B issues a clone operation from user A's file into its own
file (using a length argument of 0, clone the whole range);
6) User B now gets to see the 1000 bytes that user A truncated from
its file before it made its file world readbale. User B also lost
the bytes in the range [1000, 2000[ bytes from its own file, but
that might be ok if his/her intention was reading stale data from
user A that was never supposed to be public.
Note that this contrasts with the case where we truncate a file from 2000
bytes to 1000 bytes and then truncate it back from 1000 to 2000 bytes. In
this case reading any byte from the range [1000, 2000[ will return a value
of 0x00, instead of the original data.
This problem exists since the clone ioctl was added and happens both with
and without my recent data loss and file corruption fixes for the clone
ioctl (patch "Btrfs: fix file corruption and data loss after cloning
inline extents").
So fix this by truncating the compressed inline extents as we do for the
non-compressed case, which involves decompressing, if the data isn't already
in the page cache, compressing the truncated version of the extent, writing
the compressed content into the inline extent and then truncate it.
The following test case for fstests reproduces the problem. In order for
the test to pass both this fix and my previous fix for the clone ioctl
that forbids cloning a smaller inline extent into a larger one,
which is titled "Btrfs: fix file corruption and data loss after cloning
inline extents", are needed. Without that other fix the test fails in a
different way that does not leak the truncated data, instead part of
destination file gets replaced with zeroes (because the destination file
has a larger inline extent than the source).
seq=`basename $0`
seqres=$RESULT_DIR/$seq
echo "QA output created by $seq"
tmp=/tmp/$$
status=1 # failure is the default!
trap "_cleanup; exit \$status" 0 1 2 3 15
_cleanup()
{
rm -f $tmp.*
}
# get standard environment, filters and checks
. ./common/rc
. ./common/filter
# real QA test starts here
_need_to_be_root
_supported_fs btrfs
_supported_os Linux
_require_scratch
_require_cloner
rm -f $seqres.full
_scratch_mkfs >>$seqres.full 2>&1
_scratch_mount "-o compress"
# Create our test files. File foo is going to be the source of a clone operation
# and consists of a single inline extent with an uncompressed size of 512 bytes,
# while file bar consists of a single inline extent with an uncompressed size of
# 256 bytes. For our test's purpose, it's important that file bar has an inline
# extent with a size smaller than foo's inline extent.
$XFS_IO_PROG -f -c "pwrite -S 0xa1 0 128" \
-c "pwrite -S 0x2a 128 384" \
$SCRATCH_MNT/foo | _filter_xfs_io
$XFS_IO_PROG -f -c "pwrite -S 0xbb 0 256" $SCRATCH_MNT/bar | _filter_xfs_io
# Now durably persist all metadata and data. We do this to make sure that we get
# on disk an inline extent with a size of 512 bytes for file foo.
sync
# Now truncate our file foo to a smaller size. Because it consists of a
# compressed and inline extent, btrfs did not shrink the inline extent to the
# new size (if the extent was not compressed, btrfs would shrink it to 128
# bytes), it only updates the inode's i_size to 128 bytes.
$XFS_IO_PROG -c "truncate 128" $SCRATCH_MNT/foo
# Now clone foo's inline extent into bar.
# This clone operation should fail with errno EOPNOTSUPP because the source
# file consists only of an inline extent and the file's size is smaller than
# the inline extent of the destination (128 bytes < 256 bytes). However the
# clone ioctl was not prepared to deal with a file that has a size smaller
# than the size of its inline extent (something that happens only for compressed
# inline extents), resulting in copying the full inline extent from the source
# file into the destination file.
#
# Note that btrfs' clone operation for inline extents consists of removing the
# inline extent from the destination inode and copy the inline extent from the
# source inode into the destination inode, meaning that if the destination
# inode's inline extent is larger (N bytes) than the source inode's inline
# extent (M bytes), some bytes (N - M bytes) will be lost from the destination
# file. Btrfs could copy the source inline extent's data into the destination's
# inline extent so that we would not lose any data, but that's currently not
# done due to the complexity that would be needed to deal with such cases
# (specially when one or both extents are compressed), returning EOPNOTSUPP, as
# it's normally not a very common case to clone very small files (only case
# where we get inline extents) and copying inline extents does not save any
# space (unlike for normal, non-inlined extents).
$CLONER_PROG -s 0 -d 0 -l 0 $SCRATCH_MNT/foo $SCRATCH_MNT/bar
# Now because the above clone operation used to succeed, and due to foo's inline
# extent not being shinked by the truncate operation, our file bar got the whole
# inline extent copied from foo, making us lose the last 128 bytes from bar
# which got replaced by the bytes in range [128, 256[ from foo before foo was
# truncated - in other words, data loss from bar and being able to read old and
# stale data from foo that should not be possible to read anymore through normal
# filesystem operations. Contrast with the case where we truncate a file from a
# size N to a smaller size M, truncate it back to size N and then read the range
# [M, N[, we should always get the value 0x00 for all the bytes in that range.
# We expected the clone operation to fail with errno EOPNOTSUPP and therefore
# not modify our file's bar data/metadata. So its content should be 256 bytes
# long with all bytes having the value 0xbb.
#
# Without the btrfs bug fix, the clone operation succeeded and resulted in
# leaking truncated data from foo, the bytes that belonged to its range
# [128, 256[, and losing data from bar in that same range. So reading the
# file gave us the following content:
#
# 0000000 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1 a1
# *
# 0000200 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a
# *
# 0000400
echo "File bar's content after the clone operation:"
od -t x1 $SCRATCH_MNT/bar
# Also because the foo's inline extent was not shrunk by the truncate
# operation, btrfs' fsck, which is run by the fstests framework everytime a
# test completes, failed reporting the following error:
#
# root 5 inode 257 errors 400, nbytes wrong
status=0
exit
Cc: stable@vger.kernel.org
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
fs/btrfs/inode.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 68 insertions(+), 14 deletions(-)
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4184,6 +4184,47 @@ static int truncate_space_check(struct b
}
+static int truncate_inline_extent(struct inode *inode,
+ struct btrfs_path *path,
+ struct btrfs_key *found_key,
+ const u64 item_end,
+ const u64 new_size)
+{
+ struct extent_buffer *leaf = path->nodes[0];
+ int slot = path->slots[0];
+ struct btrfs_file_extent_item *fi;
+ u32 size = (u32)(new_size - found_key->offset);
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+
+ fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
+
+ if (btrfs_file_extent_compression(leaf, fi) != BTRFS_COMPRESS_NONE) {
+ loff_t offset = new_size;
+ loff_t page_end = ALIGN(offset, PAGE_CACHE_SIZE);
+
+ /*
+ * Zero out the remaining of the last page of our inline extent,
+ * instead of directly truncating our inline extent here - that
+ * would be much more complex (decompressing all the data, then
+ * compressing the truncated data, which might be bigger than
+ * the size of the inline extent, resize the extent, etc).
+ * We release the path because to get the page we might need to
+ * read the extent item from disk (data not in the page cache).
+ */
+ btrfs_release_path(path);
+ return btrfs_truncate_page(inode, offset, page_end - offset, 0);
+ }
+
+ btrfs_set_file_extent_ram_bytes(leaf, fi, size);
+ size = btrfs_file_extent_calc_inline_size(size);
+ btrfs_truncate_item(root, path, size, 1);
+
+ if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
+ inode_sub_bytes(inode, item_end + 1 - new_size);
+
+ return 0;
+}
+
/*
* this can truncate away extent items, csum items and directory items.
* It starts at a high offset and removes keys until it can't find
@@ -4378,27 +4419,40 @@ search_again:
* special encodings
*/
if (!del_item &&
- btrfs_file_extent_compression(leaf, fi) == 0 &&
btrfs_file_extent_encryption(leaf, fi) == 0 &&
btrfs_file_extent_other_encoding(leaf, fi) == 0) {
- u32 size = new_size - found_key.offset;
-
- if (test_bit(BTRFS_ROOT_REF_COWS, &root->state))
- inode_sub_bytes(inode, item_end + 1 -
- new_size);
/*
- * update the ram bytes to properly reflect
- * the new size of our item
+ * Need to release path in order to truncate a
+ * compressed extent. So delete any accumulated
+ * extent items so far.
*/
- btrfs_set_file_extent_ram_bytes(leaf, fi, size);
- size =
- btrfs_file_extent_calc_inline_size(size);
- btrfs_truncate_item(root, path, size, 1);
+ if (btrfs_file_extent_compression(leaf, fi) !=
+ BTRFS_COMPRESS_NONE && pending_del_nr) {
+ err = btrfs_del_items(trans, root, path,
+ pending_del_slot,
+ pending_del_nr);
+ if (err) {
+ btrfs_abort_transaction(trans,
+ root,
+ err);
+ goto error;
+ }
+ pending_del_nr = 0;
+ }
+
+ err = truncate_inline_extent(inode, path,
+ &found_key,
+ item_end,
+ new_size);
+ if (err) {
+ btrfs_abort_transaction(trans,
+ root, err);
+ goto error;
+ }
} else if (test_bit(BTRFS_ROOT_REF_COWS,
&root->state)) {
- inode_sub_bytes(inode, item_end + 1 -
- found_key.offset);
+ inode_sub_bytes(inode, item_end + 1 - new_size);
}
}
delete:

View File

@ -0,0 +1,37 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 1 Nov 2015 16:21:24 +0000
Subject: isdn_ppp: Add checks for allocation failure in isdn_ppp_open()
Origin: https://git.kernel.org/linus/0baa57d8dc32db78369d8b5176ef56c5e2e18ab3
Compile-tested only.
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/isdn/i4l/isdn_ppp.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/isdn/i4l/isdn_ppp.c b/drivers/isdn/i4l/isdn_ppp.c
index c4198fa..86f9abe 100644
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -301,6 +301,8 @@ isdn_ppp_open(int min, struct file *file)
is->compflags = 0;
is->reset = isdn_ppp_ccp_reset_alloc(is);
+ if (!is->reset)
+ return -ENOMEM;
is->lp = NULL;
is->mp_seqno = 0; /* MP sequence number */
@@ -320,6 +322,10 @@ isdn_ppp_open(int min, struct file *file)
* VJ header compression init
*/
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
+ if (!is->slcomp) {
+ isdn_ppp_ccp_reset_free(is);
+ return -ENOMEM;
+ }
#endif
#ifdef CONFIG_IPPP_FILTER
is->pass_filter = NULL;

View File

@ -0,0 +1,44 @@
From: Vladis Dronov <vdronov@redhat.com>
Date: Mon, 16 Nov 2015 15:55:11 -0200
Subject: [media] usbvision: fix crash on detecting device with invalid
configuration
Origin: http://git.linuxtv.org/cgit.cgi/media_tree.git/commit?id=fa52bd506f274b7619955917abfde355e3d19ffe
The usbvision driver crashes when a specially crafted usb device with invalid
number of interfaces or endpoints is detected. This fix adds checks that the
device has proper configuration expected by the driver.
Reported-by: Ralf Spenneberg <ralf@spenneberg.net>
Signed-off-by: Vladis Dronov <vdronov@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
---
drivers/media/usb/usbvision/usbvision-video.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/media/usb/usbvision/usbvision-video.c
+++ b/drivers/media/usb/usbvision/usbvision-video.c
@@ -1542,9 +1542,23 @@ static int usbvision_probe(struct usb_in
if (usbvision_device_data[model].interface >= 0)
interface = &dev->actconfig->interface[usbvision_device_data[model].interface]->altsetting[0];
- else
+ else if (ifnum < dev->actconfig->desc.bNumInterfaces)
interface = &dev->actconfig->interface[ifnum]->altsetting[0];
+ else {
+ dev_err(&intf->dev, "interface %d is invalid, max is %d\n",
+ ifnum, dev->actconfig->desc.bNumInterfaces - 1);
+ ret = -ENODEV;
+ goto err_usb;
+ }
+
+ if (interface->desc.bNumEndpoints < 2) {
+ dev_err(&intf->dev, "interface %d has %d endpoints, but must"
+ " have minimum 2\n", ifnum, interface->desc.bNumEndpoints);
+ ret = -ENODEV;
+ goto err_usb;
+ }
endpoint = &interface->endpoint[1].desc;
+
if (!usb_endpoint_xfer_isoc(endpoint)) {
dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);

View File

@ -0,0 +1,128 @@
From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 1 Nov 2015 16:22:53 +0000
Subject: ppp, slip: Validate VJ compression slot parameters completely
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Origin: https://git.kernel.org/linus/4ab42d78e37a294ac7bc56901d563c642e03c4ae
Currently slhc_init() treats out-of-range values of rslots and tslots
as equivalent to 0, except that if tslots is too large it will
dereference a null pointer (CVE-2015-7799).
Add a range-check at the top of the function and make it return an
ERR_PTR() on error instead of NULL. Change the callers accordingly.
Compile-tested only.
Reported-by: 郭永刚 <guoyonggang@360.cn>
References: http://article.gmane.org/gmane.comp.security.oss.general/17908
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/isdn/i4l/isdn_ppp.c | 10 ++++------
drivers/net/ppp/ppp_generic.c | 6 ++----
drivers/net/slip/slhc.c | 12 ++++++++----
drivers/net/slip/slip.c | 2 +-
4 files changed, 15 insertions(+), 15 deletions(-)
--- a/drivers/isdn/i4l/isdn_ppp.c
+++ b/drivers/isdn/i4l/isdn_ppp.c
@@ -322,9 +322,9 @@ isdn_ppp_open(int min, struct file *file
* VJ header compression init
*/
is->slcomp = slhc_init(16, 16); /* not necessary for 2. link in bundle */
- if (!is->slcomp) {
+ if (IS_ERR(is->slcomp)) {
isdn_ppp_ccp_reset_free(is);
- return -ENOMEM;
+ return PTR_ERR(is->slcomp);
}
#endif
#ifdef CONFIG_IPPP_FILTER
@@ -573,10 +573,8 @@ isdn_ppp_ioctl(int min, struct file *fil
is->maxcid = val;
#ifdef CONFIG_ISDN_PPP_VJ
sltmp = slhc_init(16, val);
- if (!sltmp) {
- printk(KERN_ERR "ippp, can't realloc slhc struct\n");
- return -ENOMEM;
- }
+ if (IS_ERR(sltmp))
+ return PTR_ERR(sltmp);
if (is->slcomp)
slhc_free(is->slcomp);
is->slcomp = sltmp;
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -719,10 +719,8 @@ static long ppp_ioctl(struct file *file,
val &= 0xffff;
}
vj = slhc_init(val2+1, val+1);
- if (!vj) {
- netdev_err(ppp->dev,
- "PPP: no memory (VJ compressor)\n");
- err = -ENOMEM;
+ if (IS_ERR(vj)) {
+ err = PTR_ERR(vj);
break;
}
ppp_lock(ppp);
--- a/drivers/net/slip/slhc.c
+++ b/drivers/net/slip/slhc.c
@@ -84,8 +84,9 @@ static long decode(unsigned char **cpp);
static unsigned char * put16(unsigned char *cp, unsigned short x);
static unsigned short pull16(unsigned char **cpp);
-/* Initialize compression data structure
+/* Allocate compression data structure
* slots must be in range 0 to 255 (zero meaning no compression)
+ * Returns pointer to structure or ERR_PTR() on error.
*/
struct slcompress *
slhc_init(int rslots, int tslots)
@@ -94,11 +95,14 @@ slhc_init(int rslots, int tslots)
register struct cstate *ts;
struct slcompress *comp;
+ if (rslots < 0 || rslots > 255 || tslots < 0 || tslots > 255)
+ return ERR_PTR(-EINVAL);
+
comp = kzalloc(sizeof(struct slcompress), GFP_KERNEL);
if (! comp)
goto out_fail;
- if ( rslots > 0 && rslots < 256 ) {
+ if (rslots > 0) {
size_t rsize = rslots * sizeof(struct cstate);
comp->rstate = kzalloc(rsize, GFP_KERNEL);
if (! comp->rstate)
@@ -106,7 +110,7 @@ slhc_init(int rslots, int tslots)
comp->rslot_limit = rslots - 1;
}
- if ( tslots > 0 && tslots < 256 ) {
+ if (tslots > 0) {
size_t tsize = tslots * sizeof(struct cstate);
comp->tstate = kzalloc(tsize, GFP_KERNEL);
if (! comp->tstate)
@@ -141,7 +145,7 @@ out_free2:
out_free:
kfree(comp);
out_fail:
- return NULL;
+ return ERR_PTR(-ENOMEM);
}
--- a/drivers/net/slip/slip.c
+++ b/drivers/net/slip/slip.c
@@ -164,7 +164,7 @@ static int sl_alloc_bufs(struct slip *sl
if (cbuff == NULL)
goto err_exit;
slcomp = slhc_init(16, 16);
- if (slcomp == NULL)
+ if (IS_ERR(slcomp))
goto err_exit;
#endif
spin_lock_bh(&sl->lock);

View File

@ -0,0 +1,325 @@
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Date: Fri, 20 Nov 2015 22:07:23 +0000
Subject: unix: avoid use-after-free in ep_remove_wait_queue
Origin: https://git.kernel.org/cgit/linux/kernel/git/davem/net.git//commit?id=7d267278a9ece963d77eefec61630223fce08c6c
Rainer Weikusat <rweikusat@mobileactivedefense.com> writes:
An AF_UNIX datagram socket being the client in an n:1 association with
some server socket is only allowed to send messages to the server if the
receive queue of this socket contains at most sk_max_ack_backlog
datagrams. This implies that prospective writers might be forced to go
to sleep despite none of the message presently enqueued on the server
receive queue were sent by them. In order to ensure that these will be
woken up once space becomes again available, the present unix_dgram_poll
routine does a second sock_poll_wait call with the peer_wait wait queue
of the server socket as queue argument (unix_dgram_recvmsg does a wake
up on this queue after a datagram was received). This is inherently
problematic because the server socket is only guaranteed to remain alive
for as long as the client still holds a reference to it. In case the
connection is dissolved via connect or by the dead peer detection logic
in unix_dgram_sendmsg, the server socket may be freed despite "the
polling mechanism" (in particular, epoll) still has a pointer to the
corresponding peer_wait queue. There's no way to forcibly deregister a
wait queue with epoll.
Based on an idea by Jason Baron, the patch below changes the code such
that a wait_queue_t belonging to the client socket is enqueued on the
peer_wait queue of the server whenever the peer receive queue full
condition is detected by either a sendmsg or a poll. A wake up on the
peer queue is then relayed to the ordinary wait queue of the client
socket via wake function. The connection to the peer wait queue is again
dissolved if either a wake up is about to be relayed or the client
socket reconnects or a dead peer is detected or the client socket is
itself closed. This enables removing the second sock_poll_wait from
unix_dgram_poll, thus avoiding the use-after-free, while still ensuring
that no blocked writer sleeps forever.
Signed-off-by: Rainer Weikusat <rweikusat@mobileactivedefense.com>
Fixes: ec0d215f9420 ("af_unix: fix 'poll for write'/connected DGRAM sockets")
Reviewed-by: Jason Baron <jbaron@akamai.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
[bwh: Backported to 4.2: adjust context]
---
include/net/af_unix.h | 1 +
net/unix/af_unix.c | 183 ++++++++++++++++++++++++++++++++++++++++++++------
2 files changed, 165 insertions(+), 19 deletions(-)
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -62,6 +62,7 @@ struct unix_sock {
#define UNIX_GC_CANDIDATE 0
#define UNIX_GC_MAYBE_CYCLE 1
struct socket_wq peer_wq;
+ wait_queue_t peer_wake;
};
static inline struct unix_sock *unix_sk(const struct sock *sk)
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -326,6 +326,118 @@ found:
return s;
}
+/* Support code for asymmetrically connected dgram sockets
+ *
+ * If a datagram socket is connected to a socket not itself connected
+ * to the first socket (eg, /dev/log), clients may only enqueue more
+ * messages if the present receive queue of the server socket is not
+ * "too large". This means there's a second writeability condition
+ * poll and sendmsg need to test. The dgram recv code will do a wake
+ * up on the peer_wait wait queue of a socket upon reception of a
+ * datagram which needs to be propagated to sleeping would-be writers
+ * since these might not have sent anything so far. This can't be
+ * accomplished via poll_wait because the lifetime of the server
+ * socket might be less than that of its clients if these break their
+ * association with it or if the server socket is closed while clients
+ * are still connected to it and there's no way to inform "a polling
+ * implementation" that it should let go of a certain wait queue
+ *
+ * In order to propagate a wake up, a wait_queue_t of the client
+ * socket is enqueued on the peer_wait queue of the server socket
+ * whose wake function does a wake_up on the ordinary client socket
+ * wait queue. This connection is established whenever a write (or
+ * poll for write) hit the flow control condition and broken when the
+ * association to the server socket is dissolved or after a wake up
+ * was relayed.
+ */
+
+static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
+ void *key)
+{
+ struct unix_sock *u;
+ wait_queue_head_t *u_sleep;
+
+ u = container_of(q, struct unix_sock, peer_wake);
+
+ __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
+ q);
+ u->peer_wake.private = NULL;
+
+ /* relaying can only happen while the wq still exists */
+ u_sleep = sk_sleep(&u->sk);
+ if (u_sleep)
+ wake_up_interruptible_poll(u_sleep, key);
+
+ return 0;
+}
+
+static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
+{
+ struct unix_sock *u, *u_other;
+ int rc;
+
+ u = unix_sk(sk);
+ u_other = unix_sk(other);
+ rc = 0;
+ spin_lock(&u_other->peer_wait.lock);
+
+ if (!u->peer_wake.private) {
+ u->peer_wake.private = other;
+ __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
+
+ rc = 1;
+ }
+
+ spin_unlock(&u_other->peer_wait.lock);
+ return rc;
+}
+
+static void unix_dgram_peer_wake_disconnect(struct sock *sk,
+ struct sock *other)
+{
+ struct unix_sock *u, *u_other;
+
+ u = unix_sk(sk);
+ u_other = unix_sk(other);
+ spin_lock(&u_other->peer_wait.lock);
+
+ if (u->peer_wake.private == other) {
+ __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
+ u->peer_wake.private = NULL;
+ }
+
+ spin_unlock(&u_other->peer_wait.lock);
+}
+
+static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
+ struct sock *other)
+{
+ unix_dgram_peer_wake_disconnect(sk, other);
+ wake_up_interruptible_poll(sk_sleep(sk),
+ POLLOUT |
+ POLLWRNORM |
+ POLLWRBAND);
+}
+
+/* preconditions:
+ * - unix_peer(sk) == other
+ * - association is stable
+ */
+static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
+{
+ int connected;
+
+ connected = unix_dgram_peer_wake_connect(sk, other);
+
+ if (unix_recvq_full(other))
+ return 1;
+
+ if (connected)
+ unix_dgram_peer_wake_disconnect(sk, other);
+
+ return 0;
+}
+
static inline int unix_writable(struct sock *sk)
{
return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
@@ -430,6 +542,8 @@ static void unix_release_sock(struct soc
skpair->sk_state_change(skpair);
sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
}
+
+ unix_dgram_peer_wake_disconnect(sk, skpair);
sock_put(skpair); /* It may now die */
unix_peer(sk) = NULL;
}
@@ -664,6 +778,7 @@ static struct sock *unix_create1(struct
INIT_LIST_HEAD(&u->link);
mutex_init(&u->readlock); /* single task reading lock */
init_waitqueue_head(&u->peer_wait);
+ init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
unix_insert_socket(unix_sockets_unbound(sk), sk);
out:
if (sk == NULL)
@@ -1031,6 +1146,8 @@ restart:
if (unix_peer(sk)) {
struct sock *old_peer = unix_peer(sk);
unix_peer(sk) = other;
+ unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
+
unix_state_double_unlock(sk, other);
if (other != old_peer)
@@ -1470,6 +1587,7 @@ static int unix_dgram_sendmsg(struct soc
struct scm_cookie scm;
int max_level;
int data_len = 0;
+ int sk_locked;
wait_for_unix_gc();
err = scm_send(sock, msg, &scm, false);
@@ -1548,12 +1666,14 @@ restart:
goto out_free;
}
+ sk_locked = 0;
unix_state_lock(other);
+restart_locked:
err = -EPERM;
if (!unix_may_send(sk, other))
goto out_unlock;
- if (sock_flag(other, SOCK_DEAD)) {
+ if (unlikely(sock_flag(other, SOCK_DEAD))) {
/*
* Check with 1003.1g - what should
* datagram error
@@ -1561,10 +1681,14 @@ restart:
unix_state_unlock(other);
sock_put(other);
+ if (!sk_locked)
+ unix_state_lock(sk);
+
err = 0;
- unix_state_lock(sk);
if (unix_peer(sk) == other) {
unix_peer(sk) = NULL;
+ unix_dgram_peer_wake_disconnect_wakeup(sk, other);
+
unix_state_unlock(sk);
unix_dgram_disconnected(sk, other);
@@ -1590,21 +1714,38 @@ restart:
goto out_unlock;
}
- if (unix_peer(other) != sk && unix_recvq_full(other)) {
- if (!timeo) {
- err = -EAGAIN;
- goto out_unlock;
+ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+ if (timeo) {
+ timeo = unix_wait_for_peer(other, timeo);
+
+ err = sock_intr_errno(timeo);
+ if (signal_pending(current))
+ goto out_free;
+
+ goto restart;
}
- timeo = unix_wait_for_peer(other, timeo);
+ if (!sk_locked) {
+ unix_state_unlock(other);
+ unix_state_double_lock(sk, other);
+ }
- err = sock_intr_errno(timeo);
- if (signal_pending(current))
- goto out_free;
+ if (unix_peer(sk) != other ||
+ unix_dgram_peer_wake_me(sk, other)) {
+ err = -EAGAIN;
+ sk_locked = 1;
+ goto out_unlock;
+ }
- goto restart;
+ if (!sk_locked) {
+ sk_locked = 1;
+ goto restart_locked;
+ }
}
+ if (unlikely(sk_locked))
+ unix_state_unlock(sk);
+
if (sock_flag(other, SOCK_RCVTSTAMP))
__net_timestamp(skb);
maybe_add_creds(skb, sock, other);
@@ -1618,6 +1759,8 @@ restart:
return len;
out_unlock:
+ if (sk_locked)
+ unix_state_unlock(sk);
unix_state_unlock(other);
out_free:
kfree_skb(skb);
@@ -2453,14 +2596,16 @@ static unsigned int unix_dgram_poll(stru
return mask;
writable = unix_writable(sk);
- other = unix_peer_get(sk);
- if (other) {
- if (unix_peer(other) != sk) {
- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
- if (unix_recvq_full(other))
- writable = 0;
- }
- sock_put(other);
+ if (writable) {
+ unix_state_lock(sk);
+
+ other = unix_peer(sk);
+ if (other && unix_peer(other) != sk &&
+ unix_recvq_full(other) &&
+ unix_dgram_peer_wake_me(sk, other))
+ writable = 0;
+
+ unix_state_unlock(sk);
}
if (writable)

View File

@ -1,14 +1,16 @@
From: Oliver Neukum <oneukum@suse.com>
Date: Tue, 27 Oct 2015 12:42:38 +0100
Subject: usbvision fix overflow of interfaces array
Origin: https://bugzilla.novell.com/attachment.cgi?id=653350
Date: Tue, 27 Oct 2015 09:51:34 -0200
Subject: [media] usbvision fix overflow of interfaces array
Origin: http://git.linuxtv.org/cgit.cgi/media_tree.git/commit?id=588afcc1c0e45358159090d95bf7b246fb67565f
This fixes the crash reported in:
http://seclists.org/bugtraq/2015/Oct/35
The interface number needs a sanity check.
Signed-off-by: Oliver Neukum <oneukum@suse.com>
[bwh: Backported to 4.2: adjust context]
Cc: Vladis Dronov <vdronov@redhat.com>
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
---
drivers/media/usb/usbvision/usbvision-video.c | 7 +++++++
1 file changed, 7 insertions(+)

View File

@ -0,0 +1,75 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 10 Nov 2015 09:14:39 +0100
Subject: KVM: svm: unconditionally intercept #DB
Origin: https://git.kernel.org/linus/cbdb967af3d54993f5814f1cee0ed311a055377d
This is needed to avoid the possibility that the guest triggers
an infinite stream of #DB exceptions (CVE-2015-8104).
VMX is not affected: because it does not save DR6 in the VMCS,
it already intercepts #DB unconditionally.
Reported-by: Jan Beulich <jbeulich@suse.com>
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/svm.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -1107,6 +1107,7 @@ static void init_vmcb(struct vcpu_svm *s
set_exception_intercept(svm, UD_VECTOR);
set_exception_intercept(svm, MC_VECTOR);
set_exception_intercept(svm, AC_VECTOR);
+ set_exception_intercept(svm, DB_VECTOR);
set_intercept(svm, INTERCEPT_INTR);
set_intercept(svm, INTERCEPT_NMI);
@@ -1642,20 +1643,13 @@ static void svm_set_segment(struct kvm_v
mark_dirty(svm->vmcb, VMCB_SEG);
}
-static void update_db_bp_intercept(struct kvm_vcpu *vcpu)
+static void update_bp_intercept(struct kvm_vcpu *vcpu)
{
struct vcpu_svm *svm = to_svm(vcpu);
- clr_exception_intercept(svm, DB_VECTOR);
clr_exception_intercept(svm, BP_VECTOR);
- if (svm->nmi_singlestep)
- set_exception_intercept(svm, DB_VECTOR);
-
if (vcpu->guest_debug & KVM_GUESTDBG_ENABLE) {
- if (vcpu->guest_debug &
- (KVM_GUESTDBG_SINGLESTEP | KVM_GUESTDBG_USE_HW_BP))
- set_exception_intercept(svm, DB_VECTOR);
if (vcpu->guest_debug & KVM_GUESTDBG_USE_SW_BP)
set_exception_intercept(svm, BP_VECTOR);
} else
@@ -1761,7 +1755,6 @@ static int db_interception(struct vcpu_s
if (!(svm->vcpu.guest_debug & KVM_GUESTDBG_SINGLESTEP))
svm->vmcb->save.rflags &=
~(X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_bp_intercept(&svm->vcpu);
}
if (svm->vcpu.guest_debug &
@@ -3760,7 +3753,6 @@ static void enable_nmi_window(struct kvm
*/
svm->nmi_singlestep = true;
svm->vmcb->save.rflags |= (X86_EFLAGS_TF | X86_EFLAGS_RF);
- update_db_bp_intercept(vcpu);
}
static int svm_set_tss_addr(struct kvm *kvm, unsigned int addr)
@@ -4382,7 +4374,7 @@ static struct kvm_x86_ops svm_x86_ops =
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
- .update_db_bp_intercept = update_db_bp_intercept,
+ .update_db_bp_intercept = update_bp_intercept,
.get_msr = svm_get_msr,
.set_msr = svm_set_msr,
.get_segment_base = svm_get_segment_base,

View File

@ -0,0 +1,60 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 10 Nov 2015 11:55:36 +0100
Subject: KVM: x86: rename update_db_bp_intercept to update_bp_intercept
Origin: https://git.kernel.org/linus/a96036b8ef7df9f10cd575c0d78359bd33188e8e
Because #DB is now intercepted unconditionally, this callback
only operates on #BP for both VMX and SVM.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/include/asm/kvm_host.h | 2 +-
arch/x86/kvm/svm.c | 2 +-
arch/x86/kvm/vmx.c | 2 +-
arch/x86/kvm/x86.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -739,7 +739,7 @@ struct kvm_x86_ops {
void (*vcpu_load)(struct kvm_vcpu *vcpu, int cpu);
void (*vcpu_put)(struct kvm_vcpu *vcpu);
- void (*update_db_bp_intercept)(struct kvm_vcpu *vcpu);
+ void (*update_bp_intercept)(struct kvm_vcpu *vcpu);
int (*get_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
int (*set_msr)(struct kvm_vcpu *vcpu, struct msr_data *msr);
u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4374,7 +4374,7 @@ static struct kvm_x86_ops svm_x86_ops =
.vcpu_load = svm_vcpu_load,
.vcpu_put = svm_vcpu_put,
- .update_db_bp_intercept = update_bp_intercept,
+ .update_bp_intercept = update_bp_intercept,
.get_msr = svm_get_msr,
.set_msr = svm_set_msr,
.get_segment_base = svm_get_segment_base,
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -10335,7 +10335,7 @@ static struct kvm_x86_ops vmx_x86_ops =
.vcpu_load = vmx_vcpu_load,
.vcpu_put = vmx_vcpu_put,
- .update_db_bp_intercept = update_exception_bitmap,
+ .update_bp_intercept = update_exception_bitmap,
.get_msr = vmx_get_msr,
.set_msr = vmx_set_msr,
.get_segment_base = vmx_get_segment_base,
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -7184,7 +7184,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(
*/
kvm_set_rflags(vcpu, rflags);
- kvm_x86_ops->update_db_bp_intercept(vcpu);
+ kvm_x86_ops->update_bp_intercept(vcpu);
r = 0;

View File

@ -85,9 +85,16 @@ bugfix/all/selftests-kprobe-choose-an-always-defined-function-t.patch
bugfix/all/selftests-make-scripts-executable.patch
bugfix/all/selftests-vm-try-harder-to-allocate-huge-pages.patch
bugfix/all/selftests-breakpoints-actually-build-it.patch
bugfix/all/usbvision-fix-overflow-of-interfaces-array.patch
bugfix/all/rds-fix-race-condition-when-sending-a-message-on-unbound-socket.patch
bugfix/all/media-media-vivid-osd-fix-info-leak-in-ioctl.patch
bugfix/x86/kvm-x86-vmx-avoid-guest-host-dos-by-intercepting-ac.patch
bugfix/x86/kvm-x86-svm-intercept-ac-to-avoid-guest-host-exploit.patch
bugfix/x86/kvm-svm-unconditionally-intercept-DB.patch
bugfix/x86/kvm-x86-rename-update_db_bp_intercept-to-update_bp_i.patch
bugfix/all/usbvision-fix-overflow-of-interfaces-array.patch
bugfix/all/media-usbvision-fix-crash-on-detecting-device-with-i.patch
bugfix/all/unix-avoid-use-after-free-in-ep_remove_wait_queue.patch
bugfix/all/isdn_ppp-add-checks-for-allocation-failure-in-isdn_p.patch
bugfix/all/ppp-slip-validate-vj-compression-slot-parameters-com.patch
bugfix/all/btrfs-fix-truncation-of-compressed-and-inlined-exten.patch
bugfix/x86/drm-i915-shut-up-gen8-sde-irq-dmesg-noise.patch