diff --git a/debian/changelog b/debian/changelog index d448b5bf0..88349f0fd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium +linux (3.16.7-ckt4-1) UNRELEASED; urgency=medium * New upstream stable update: http://kernel.ubuntu.com/stable/ChangeLog-3.16.7-ckt3 @@ -83,6 +83,159 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium - bond: Check length of IFLA_BOND_ARP_IP_TARGET attributes - gre: Set inner mac header in gro complete (regression in 3.16.7-ckt1) - [mips*] bpf: Fix broken BPF_MOD + http://kernel.ubuntu.com/stable/ChangeLog-3.16.7-ckt4 + - [x86] drm/i915: don't warn if backlight unexpectedly enabled + (Closes: #757805) + - [x86] drm/i915/dp: only use training pattern 3 on platforms that + support it (regression in 3.15) + - btrfs: don't go readonly on existing qgroup items + - writeback: fix a subtle race condition in I_DIRTY clearing + - [s390*] KVM: flush CPU on load control + - UBI: Fix double free after do_sync_erase() + - [x86] Drivers: hv: util: make struct hv_do_fcopy match Hyper-V host + messages (regression for amd64 in 3.16.7) + - Drivers: hv: vmbus: Fix a race condition when unregistering a device + - misc: genwqe: check for error from get_user_pages_fast() + - drbd: merge_bvec_fn: properly remap bvm->bi_bdev + - PCI: Restore detection of read-only BARs + - scsi: correct return values for .eh_abort_handler implementations + - genhd: check for int overflow in disk_expand_part_tbl() + - Btrfs: make sure we wait on logged extents when fsycning two subvols + - Btrfs: make sure logged extents complete in the current transaction V3 + - Btrfs: do not move em to modified list when unpinning + - [armhf] mvebu: disable I/O coherency on non-SMP situations on + Armada 370/375/38x/XP + - nfs41: fix nfs4_proc_layoutget error handling + - USB: cdc-acm: check for valid interfaces + - HID: i2c-hid: fix race condition reading reports + - [armhf] mfd: twl4030-power: Fix regression with missing compatible flag + (regression in 3.16) + - [armhf] serial: samsung: wait for transfer completion before clock + disable + - n_tty: Fix read_buf race condition, increment read_head after pushing + data (regression in 3.12) + - dm cache: only use overwrite optimisation for promotion when in + writeback mode + - dm cache: dirty flag was mistakenly being cleared when promoting via + overwrite + - dm bufio: fix memleak when using a dm_buffer's inline bio + - iwlwifi: dvm: fix flush support for old firmware (regression in + 3.16.7-ckt1) + - iwlwifi: mvm: update values for Smart Fifo (regression in 3.14) + - iommu/vt-d: Fix an off-by-one bug in __domain_mapping() + - dm crypt: use memzero_explicit for on-stack buffer + - mnt: Implicitly add MNT_NODEV on remount when it was implicitly added by + mount (regression in 3.16.3) + - umount: Disallow unprivileged mount force + - md/raid5: fetch_block must fetch all the blocks handle_stripe_dirtying + wants. + - [x86] drm/i915: Only warn the first time we attempt to mmio whilst + suspended (regression in 3.15) + - drm/vmwgfx: Fix error printout on signals pending + - drm/radeon: check the right ring in radeon_evict_flags() + - swiotlb-xen: pass dev_addr to xen_dma_unmap_page and + xen_dma_sync_single_for_cpu + - [armhf/armmp] swiotlb-xen: remove BUG_ON in xen_bus_to_phys + - swiotlb-xen: call xen_dma_sync_single_for_device when appropriate + - swiotlb-xen: pass dev_addr to swiotlb_tbl_unmap_single + - [powerpc] book3s: Fix partial invalidation of TLBs in MCE code. + - [armhf] clocksource: arch_timer: Fix code to use physical timers when + requested (regression in 3.11) + - userns: Prevent evasion of group negative permissions through a userns + (CVE-2014-8989): + + Don't allow setgroups until a gid mapping has been setablished + + Don't allow unprivileged creation of gid mappings + + Add a knob to disable setgroups on a per user namespace basis + + Allow setting gid_maps without privilege when setgroups is disabled + - KEYS: Fix stale key registration at error path + - blk-mq: Fix a use-after-free + - blk-mq: Fix a race between bt_clear_tag() and bt_get() + - nfsd4: fix xdr4 count of server in fs_location4 (regression in 3.16) + - [x86] drm/i915: Don't complain about stolen conflicts on gen3 + (regression in 3.12) + - [x86] kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit + (CVE-2014-8134) + - blk-mq: Fix uninitialized kobject at CPU hotplugging + - ncpfs: return proper error from NCP_IOC_SETROOT ioctl + - [armhf] rtc: omap: fix clock-source configuration (regression in 3.16) + - exit: pidns: alloc_pid() leaks pid_namespace if child_reaper is exiting + - [amd64] switch_to(): Load TLS descriptors before switching DS and ES + (CVE-2014-9419) + - [x86] KVM: nVMX: Disable unrestricted mode if ept=0 (regression in 3.13) + - [x86] KVM: em_ret_far overrides cpl (follow-up to CVE-2014-3647 fix) + - pstore-ram: Fix hangs by using write-combine mappings + - HID: i2c-hid: prevent buffer overflow in early IRQ + - mac80211: fix multicast LED blinking and counter (regression in + 3.16.7-ckt2) + - cfg80211: avoid mem leak on driver hint set + - nl80211: check matches array length before acessing it + - cfg80211: don't WARN about two consecutive Country IE hint + (regression in 3.14) + - tracing/sched: Check preempt_count() for current when reading task->state + (regression in 3.13) + - [x86] tls: Validate TLS entries to protect espfix (CVE-2014-8133) + - [x86] tls: Disallow unusual TLS segments + - isofs: Fix infinite looping over CE entries (CVE-2014-9420) + - mac80211: free management frame keys when removing station + - ceph: do_sync is never initialized (regression in 3.12) + - mnt: Fix a memory stomp in umount (regression in 3.14) + - ocfs2: fix journal commit deadlock + - md/bitmap: always wait for writes on unplug. + - [armhf] mmc: omap_hsmmc: Fix UHS card with DDR50 support (regression in + 3.16) + - [x86] mmc: sdhci-pci-o2micro: Fix Dell E5440 issue (regression in 3.14) + - dm space map metadata: fix sm_bootstrap_get_nr_blocks() + - dm thin: fix a race in thin_dtr + - eCryptfs: Force RO mount when encrypted view is enabled + - eCryptfs: Remove buggy and unnecessary write in file name decode routine + - tcm_loop: Fix wrong I_T nexus association + - Btrfs: fix fs corruption on transaction abort if device supports discard + - [x86] perf/intel/uncore: Make sure only uncore events are collected + - perf: Fix events installation during moving group + - iscsi,iser-target: Initiate termination only once (regression in 3.16.4) + - iser-target: Fix flush + disconnect completion handling + - iser-target: Parallelize CM connection establishment + - iser-target: Fix connected_handler + teardown flow race + - iser-target: Handle ADDR_CHANGE event for listener cm_id + - iser-target: Fix implicit termination of connections + - iser-target: Allocate PI contexts dynamically + - iser-target: Fix NULL dereference in SW mode DIF + - iscsi,iser-target: Expose supported protection ops according to t10_pi + - genirq: Prevent proc race against freeing of irq descriptors + - [powerpc] powernv: Switch off MMU before entering nap/sleep/rvwinkle mode + - [x86] storvsc: ring buffer failures may result in I/O freeze + - iscsi-target: Fail connection on short sendmsg writes + - [x86] drm/i915: Invalidate media caches on gen7 + - [x86] drm/i915: Force the CS stall for invalidate flushes + - dm thin: fix inability to discard blocks when in out-of-data-space mode + - dm thin: fix missing out-of-data-space to write mode transition if blocks + are released + - dm: fix missed error code if .end_io isn't implemented by target_type + - [armhf] i2c: mv64xxx: rework offload support to fix several problems + (regression in 3.12) + - [x86] tls: Don't validate lm in set_thread_area() after all + - ALSA: usb-audio: extend KEF X300A FU 10 tweak to Arcam rPAC + - tick/powerclamp: Remove tick_nohz_idle abuse + - audit: don't attempt to lookup PIDs when changing PID filtering audit + rules (regression in 3.15) + - audit: use supplied gfp_mask from audit_buffer in + kauditd_send_multicast_skb (regression in 3.16) + - [arm64] kernel: fix __cpu_suspend mm switch on warm-boot + - audit: restore AUDIT_LOGINUID unset ABI (regression in 3.10) + - Btrfs: fix loop writing of async reclaim + - isofs: Fix unchecked printing of ER records (CVE-2014-9584) + - crypto: af_alg - fix backlog handling + - udf: Check path length when reading symlink + - udf: Verify i_size when loading inode + - udf: Verify symlink size before loading it + - udf: Check component length before reading it + - [x86] platform/chrome: chromeos_laptop - Add support for Acer C720 + (Closes: #774209) + - batman-adv: Calculate extra tail size based on queued fragments + (Closes: #774155) (CVE-2014-9428) + - vfs: move d_rcu from overlapping d_child to overlapping d_alias + - vfs: deal with deadlock in d_walk() (CVE-2014-8559) + - KEYS: close race between key lookup and freeing (CVE-2014-9529) [ Ben Hutchings ] * [sh4] Build with gcc-4.8 (Closes: #772602) @@ -93,13 +246,11 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium * PCI: Fix ABI change in 3.16.7-ckt3 * Ignore some ABI changes that don't appear to affect OOT modules: - Removal of __add_pages(), __remove_pages(), of_device_is_stdout_path(), - clk_divider_ro_ops + clk_divider_ro_ops, tick_nohz_idle_enter, tick_nohz_idle_exit - Changes to ASoC functions * [arm64] Enable PSTORE as built-in and EFI_VARS_PSTORE as module; ensure efivars and efi-pstore are loaded on EFI systems (Closes: #773309) * hwmon: Enable SENSORS_NCT6683 as module (Closes: #774372) - * [x86] platform/chrome: chromeos_laptop - Add support for Acer C720 - (Closes: #774209) * udeb: Add i2c-designware-{core,platform} to i2c-modules and i2c-hid to input-modules (Closes: #772578) * [x86] ACPI / video: Run _BCL before deciding registering backlight @@ -107,24 +258,13 @@ linux (3.16.7-ckt3-1) UNRELEASED; urgency=medium * [amd64] Enable EFI_MIXED to support Bay Trail systems * efi: Expose underlying UEFI firmware platform size to userland, to support installation on Bay Trail systems (Closes: #775191) - * [x86] tls: Validate TLS entries to protect espfix (CVE-2014-8133) - * [x86] kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit - (CVE-2014-8134) - * [amd64] switch_to(): Load TLS descriptors before switching DS and ES - (CVE-2014-9419) - * isofs: Fix infinite looping over CE entries (CVE-2014-9420) - * batman-adv: Calculate extra tail size based on queued fragments - (Closes: #774155) (CVE-2014-9428) - * KEYS: close race between key lookup and freeing (CVE-2014-9529) - * isofs: Fix unchecked printing of ER records (CVE-2014-9584) - * vfs: Fix potential deadlock in dcache (CVE-2014-8559) - - move d_rcu from overlapping d_child to overlapping d_alias + * vfs: Changes for compatibility with CVE-2014-8559 fix: - aufs: move d_rcu from overlapping d_child to overlapping d_alias - vfs: Avoid ABI change for dentry union changes - - deal with deadlock in d_walk() * [powerpc/powerpc{,-smp}] video/fb: Change FB_RADEON back to module (Closes: #748398) (thanks to John Paul Adrian Glaubitz for thoroughly testing this change) + * userns: Fix ABI change in 3.16.7-ckt4 [ Ian Campbell ] * [armhf] Enable support for support OMAP5432 uEVM by enabling: diff --git a/debian/config/config b/debian/config/config index 036c4a381..f75818fd4 100644 --- a/debian/config/config +++ b/debian/config/config @@ -3051,6 +3051,7 @@ CONFIG_IWLWIFI=m CONFIG_IWLDVM=m CONFIG_IWLMVM=m # CONFIG_IWLWIFI_BCAST_FILTERING is not set +# CONFIG_IWLWIFI_UAPSD is not set # CONFIG_IWLWIFI_DEBUG is not set # CONFIG_IWLWIFI_DEVICE_TRACING is not set diff --git a/debian/config/defines b/debian/config/defines index cbc95d2de..1e81d7559 100644 --- a/debian/config/defines +++ b/debian/config/defines @@ -12,6 +12,8 @@ ignore-changes: module:sound/soc/* # Not needed by modules at all clk_divider_ro_ops + tick_nohz_idle_enter + tick_nohz_idle_exit [base] arches: diff --git a/debian/patches/bugfix/all/batman-adv-calculate-extra-tail-size-based-on-queued.patch b/debian/patches/bugfix/all/batman-adv-calculate-extra-tail-size-based-on-queued.patch deleted file mode 100644 index 31486c9fe..000000000 --- a/debian/patches/bugfix/all/batman-adv-calculate-extra-tail-size-based-on-queued.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Sven Eckelmann -Date: Sat, 20 Dec 2014 13:48:55 +0100 -Subject: batman-adv: Calculate extra tail size based on queued fragments -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit -Origin: https://git.kernel.org/linus/5b6698b0e4a37053de35cc24ee695b98a7eb712b - -The fragmentation code was replaced in 610bfc6bc99bc83680d190ebc69359a05fc7f605 -("batman-adv: Receive fragmented packets and merge"). The new code provided a -mostly unused parameter skb for the merging function. It is used inside the -function to calculate the additionally needed skb tailroom. But instead of -increasing its own tailroom, it is only increasing the tailroom of the first -queued skb. This is not correct in some situations because the first queued -entry can be a different one than the parameter. - -An observed problem was: - -1. packet with size 104, total_size 1464, fragno 1 was received - - packet is queued -2. packet with size 1400, total_size 1464, fragno 0 was received - - packet is queued at the end of the list -3. enough data was received and can be given to the merge function - (1464 == (1400 - 20) + (104 - 20)) - - merge functions gets 1400 byte large packet as skb argument -4. merge function gets first entry in queue (104 byte) - - stored as skb_out -5. merge function calculates the required extra tail as total_size - skb->len - - pskb_expand_head tail of skb_out with 64 bytes -6. merge function tries to squeeze the extra 1380 bytes from the second queued - skb (1400 byte aka skb parameter) in the 64 extra tail bytes of skb_out - -Instead calculate the extra required tail bytes for skb_out also using skb_out -instead of using the parameter skb. The skb parameter is only used to get the -total_size from the last received packet. This is also the total_size used to -decide that all fragments were received. - -Reported-by: Philipp Psurek -Signed-off-by: Sven Eckelmann -Acked-by: Martin Hundebøll -Signed-off-by: David S. Miller ---- - net/batman-adv/fragmentation.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c -index fc1835c..8af3461 100644 ---- a/net/batman-adv/fragmentation.c -+++ b/net/batman-adv/fragmentation.c -@@ -251,7 +251,7 @@ batadv_frag_merge_packets(struct hlist_head *chain, struct sk_buff *skb) - kfree(entry); - - /* Make room for the rest of the fragments. */ -- if (pskb_expand_head(skb_out, 0, size - skb->len, GFP_ATOMIC) < 0) { -+ if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) { - kfree_skb(skb_out); - skb_out = NULL; - goto free; diff --git a/debian/patches/bugfix/all/deal-with-deadlock-in-d_walk.patch b/debian/patches/bugfix/all/deal-with-deadlock-in-d_walk.patch deleted file mode 100644 index 87c868341..000000000 --- a/debian/patches/bugfix/all/deal-with-deadlock-in-d_walk.patch +++ /dev/null @@ -1,82 +0,0 @@ -From: Al Viro -Date: Sun, 26 Oct 2014 19:31:10 -0400 -Subject: deal with deadlock in d_walk() -Origin: https://git.kernel.org/linus/ca5358ef75fc69fee5322a38a340f5739d997c10 - -... by not hitting rename_retry for reasons other than rename having -happened. In other words, do _not_ restart when finding that -between unlocking the child and locking the parent the former got -into __dentry_kill(). Skip the killed siblings instead... - -Signed-off-by: Al Viro ---- - fs/dcache.c | 31 ++++++++++++++++--------------- - 1 file changed, 16 insertions(+), 15 deletions(-) - ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -484,7 +484,7 @@ static void __dentry_kill(struct dentry - } - /* if it was on the hash then remove it */ - __d_drop(dentry); -- list_del(&dentry->d_child); -+ __list_del_entry(&dentry->d_child); - /* - * Inform d_walk() that we are no longer attached to the - * dentry tree -@@ -1138,33 +1138,31 @@ resume: - /* - * All done at this level ... ascend and resume the search. - */ -+ rcu_read_lock(); -+ascend: - if (this_parent != parent) { - struct dentry *child = this_parent; - this_parent = child->d_parent; - -- rcu_read_lock(); - spin_unlock(&child->d_lock); - spin_lock(&this_parent->d_lock); - -- /* -- * might go back up the wrong parent if we have had a rename -- * or deletion -- */ -- if (this_parent != child->d_parent || -- (child->d_flags & DCACHE_DENTRY_KILLED) || -- need_seqretry(&rename_lock, seq)) { -- spin_unlock(&this_parent->d_lock); -- rcu_read_unlock(); -+ /* might go back up the wrong parent if we have had a rename. */ -+ if (need_seqretry(&rename_lock, seq)) - goto rename_retry; -+ next = child->d_child.next; -+ while (unlikely(child->d_flags & DCACHE_DENTRY_KILLED)) { -+ if (next == &this_parent->d_subdirs) -+ goto ascend; -+ child = list_entry(next, struct dentry, d_child); -+ next = next->next; - } - rcu_read_unlock(); -- next = child->d_child.next; - goto resume; - } -- if (need_seqretry(&rename_lock, seq)) { -- spin_unlock(&this_parent->d_lock); -+ if (need_seqretry(&rename_lock, seq)) - goto rename_retry; -- } -+ rcu_read_unlock(); - if (finish) - finish(data); - -@@ -1174,6 +1172,9 @@ out_unlock: - return; - - rename_retry: -+ spin_unlock(&this_parent->d_lock); -+ rcu_read_unlock(); -+ BUG_ON(seq & 1); - if (!retry) - return; - seq = 1; diff --git a/debian/patches/bugfix/all/isofs-fix-infinite-looping-over-ce-entries.patch b/debian/patches/bugfix/all/isofs-fix-infinite-looping-over-ce-entries.patch deleted file mode 100644 index c9fbb27bc..000000000 --- a/debian/patches/bugfix/all/isofs-fix-infinite-looping-over-ce-entries.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Jan Kara -Date: Mon, 15 Dec 2014 14:22:46 +0100 -Subject: isofs: Fix infinite looping over CE entries -Origin: https://git.kernel.org/linus/f54e18f1b831c92f6512d2eedb224cd63d607d3d - -Rock Ridge extensions define so called Continuation Entries (CE) which -define where is further space with Rock Ridge data. Corrupted isofs -image can contain arbitrarily long chain of these, including a one -containing loop and thus causing kernel to end in an infinite loop when -traversing these entries. - -Limit the traversal to 32 entries which should be more than enough space -to store all the Rock Ridge data. - -Reported-by: P J P -CC: stable@vger.kernel.org -Signed-off-by: Jan Kara ---- - fs/isofs/rock.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c -index f488bba..bb63254 100644 ---- a/fs/isofs/rock.c -+++ b/fs/isofs/rock.c -@@ -30,6 +30,7 @@ struct rock_state { - int cont_size; - int cont_extent; - int cont_offset; -+ int cont_loops; - struct inode *inode; - }; - -@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode) - rs->inode = inode; - } - -+/* Maximum number of Rock Ridge continuation entries */ -+#define RR_MAX_CE_ENTRIES 32 -+ - /* - * Returns 0 if the caller should continue scanning, 1 if the scan must end - * and -ve on error. -@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs) - goto out; - } - ret = -EIO; -+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES) -+ goto out; - bh = sb_bread(rs->inode->i_sb, rs->cont_extent); - if (bh) { - memcpy(rs->buffer, bh->b_data + rs->cont_offset, diff --git a/debian/patches/bugfix/all/isofs-fix-unchecked-printing-of-er-records.patch b/debian/patches/bugfix/all/isofs-fix-unchecked-printing-of-er-records.patch deleted file mode 100644 index 125951e1a..000000000 --- a/debian/patches/bugfix/all/isofs-fix-unchecked-printing-of-er-records.patch +++ /dev/null @@ -1,30 +0,0 @@ -From: Jan Kara -Date: Thu, 18 Dec 2014 17:26:10 +0100 -Subject: isofs: Fix unchecked printing of ER records -Origin: https://git.kernel.org/linus/4e2024624e678f0ebb916e6192bd23c1f9fdf696 - -We didn't check length of rock ridge ER records before printing them. -Thus corrupted isofs image can cause us to access and print some memory -behind the buffer with obvious consequences. - -Reported-and-tested-by: Carl Henrik Lunde -CC: stable@vger.kernel.org -Signed-off-by: Jan Kara ---- - fs/isofs/rock.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c -index bb63254..735d752 100644 ---- a/fs/isofs/rock.c -+++ b/fs/isofs/rock.c -@@ -362,6 +362,9 @@ repeat: - rs.cont_size = isonum_733(rr->u.CE.size); - break; - case SIG('E', 'R'): -+ /* Invalid length of ER tag id? */ -+ if (rr->u.ER.len_id + offsetof(struct rock_ridge, u.ER.data) > rr->len) -+ goto out; - ISOFS_SB(inode->i_sb)->s_rock = 1; - printk(KERN_DEBUG "ISO 9660 Extensions: "); - { diff --git a/debian/patches/bugfix/all/keys-close-race-between-key-lookup-and-freeing.patch b/debian/patches/bugfix/all/keys-close-race-between-key-lookup-and-freeing.patch deleted file mode 100644 index ada785fef..000000000 --- a/debian/patches/bugfix/all/keys-close-race-between-key-lookup-and-freeing.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Sasha Levin -Date: Mon, 29 Dec 2014 09:39:01 -0500 -Subject: KEYS: close race between key lookup and freeing -Origin: https://git.kernel.org/linus/a3a8784454692dd72e5d5d34dcdab17b4420e74c - -When a key is being garbage collected, it's key->user would get put before -the ->destroy() callback is called, where the key is removed from it's -respective tracking structures. - -This leaves a key hanging in a semi-invalid state which leaves a window open -for a different task to try an access key->user. An example is -find_keyring_by_name() which would dereference key->user for a key that is -in the process of being garbage collected (where key->user was freed but -->destroy() wasn't called yet - so it's still present in the linked list). - -This would cause either a panic, or corrupt memory. - -Fixes CVE-2014-9529. - -Signed-off-by: Sasha Levin -Signed-off-by: David Howells ---- - security/keys/gc.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/security/keys/gc.c -+++ b/security/keys/gc.c -@@ -157,12 +157,12 @@ static noinline void key_gc_unused_keys( - if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) - atomic_dec(&key->user->nikeys); - -- key_user_put(key->user); -- - /* now throw away the key memory */ - if (key->type->destroy) - key->type->destroy(key); - -+ key_user_put(key->user); -+ - kfree(key->description); - - #ifdef KEY_DEBUGGING diff --git a/debian/patches/bugfix/all/move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch b/debian/patches/bugfix/all/move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch deleted file mode 100644 index f5957410e..000000000 --- a/debian/patches/bugfix/all/move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch +++ /dev/null @@ -1,714 +0,0 @@ -From: Al Viro -Date: Sun, 26 Oct 2014 19:19:16 -0400 -Subject: move d_rcu from overlapping d_child to overlapping d_alias -Origin: https://git.kernel.org/linus/946e51f2bf37f1656916eb75bd0742ba33983c28 - -Signed-off-by: Al Viro -[bwh: Backported to 3.16: - - Apply name changes in all the different places we use d_alias and d_child - - Adjust context] ---- - arch/powerpc/platforms/cell/spufs/inode.c | 2 +- - drivers/staging/lustre/lustre/llite/dcache.c | 2 +- - drivers/staging/lustre/lustre/llite/llite_lib.c | 2 +- - drivers/staging/lustre/lustre/llite/namei.c | 8 ++-- - fs/affs/amigaffs.c | 2 +- - fs/autofs4/expire.c | 12 +++--- - fs/autofs4/root.c | 2 +- - fs/ceph/dir.c | 8 ++-- - fs/ceph/inode.c | 2 +- - fs/cifs/inode.c | 2 +- - fs/coda/cache.c | 2 +- - fs/dcache.c | 53 ++++++++++++------------- - fs/debugfs/inode.c | 2 +- - fs/exportfs/expfs.c | 2 +- - fs/libfs.c | 12 +++--- - fs/ncpfs/dir.c | 2 +- - fs/ncpfs/ncplib_kernel.h | 4 +- - fs/nfs/getroot.c | 2 +- - fs/notify/fsnotify.c | 4 +- - fs/ocfs2/dcache.c | 2 +- - include/linux/dcache.h | 8 ++-- - kernel/trace/trace.c | 4 +- - kernel/trace/trace_events.c | 2 +- - security/selinux/selinuxfs.c | 6 +-- - 24 files changed, 73 insertions(+), 74 deletions(-) - ---- a/arch/powerpc/platforms/cell/spufs/inode.c -+++ b/arch/powerpc/platforms/cell/spufs/inode.c -@@ -164,7 +164,7 @@ static void spufs_prune_dir(struct dentr - struct dentry *dentry, *tmp; - - mutex_lock(&dir->d_inode->i_mutex); -- list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_u.d_child) { -+ list_for_each_entry_safe(dentry, tmp, &dir->d_subdirs, d_child) { - spin_lock(&dentry->d_lock); - if (!(d_unhashed(dentry)) && dentry->d_inode) { - dget_dlock(dentry); ---- a/drivers/staging/lustre/lustre/llite/dcache.c -+++ b/drivers/staging/lustre/lustre/llite/dcache.c -@@ -258,7 +258,7 @@ void ll_invalidate_aliases(struct inode - inode->i_ino, inode->i_generation, inode); - - ll_lock_dcache(inode); -- ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) { -+ ll_d_hlist_for_each_entry(dentry, p, &inode->i_dentry, d_u.d_alias) { - CDEBUG(D_DENTRY, "dentry in drop %.*s (%p) parent %p " - "inode %p flags %d\n", dentry->d_name.len, - dentry->d_name.name, dentry, dentry->d_parent, ---- a/drivers/staging/lustre/lustre/llite/llite_lib.c -+++ b/drivers/staging/lustre/lustre/llite/llite_lib.c -@@ -704,7 +704,7 @@ void lustre_dump_dentry(struct dentry *d - return; - - list_for_each(tmp, &dentry->d_subdirs) { -- struct dentry *d = list_entry(tmp, struct dentry, d_u.d_child); -+ struct dentry *d = list_entry(tmp, struct dentry, d_child); - lustre_dump_dentry(d, recur - 1); - } - } ---- a/drivers/staging/lustre/lustre/llite/namei.c -+++ b/drivers/staging/lustre/lustre/llite/namei.c -@@ -167,14 +167,14 @@ static void ll_invalidate_negative_child - struct ll_d_hlist_node *p; - - ll_lock_dcache(dir); -- ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_alias) { -+ ll_d_hlist_for_each_entry(dentry, p, &dir->i_dentry, d_u.d_alias) { - spin_lock(&dentry->d_lock); - if (!list_empty(&dentry->d_subdirs)) { - struct dentry *child; - - list_for_each_entry_safe(child, tmp_subdir, - &dentry->d_subdirs, -- d_u.d_child) { -+ d_child) { - if (child->d_inode == NULL) - d_lustre_invalidate(child, 1); - } -@@ -362,7 +362,7 @@ static struct dentry *ll_find_alias(stru - discon_alias = invalid_alias = NULL; - - ll_lock_dcache(inode); -- ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_alias) { -+ ll_d_hlist_for_each_entry(alias, p, &inode->i_dentry, d_u.d_alias) { - LASSERT(alias != dentry); - - spin_lock(&alias->d_lock); -@@ -943,7 +943,7 @@ static void ll_get_child_fid(struct inod - { - struct dentry *parent, *child; - -- parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_alias); -+ parent = ll_d_hlist_entry(dir->i_dentry, struct dentry, d_u.d_alias); - child = d_lookup(parent, name); - if (child) { - if (child->d_inode) ---- a/fs/affs/amigaffs.c -+++ b/fs/affs/amigaffs.c -@@ -127,7 +127,7 @@ affs_fix_dcache(struct inode *inode, u32 - { - struct dentry *dentry; - spin_lock(&inode->i_lock); -- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { - if (entry_ino == (u32)(long)dentry->d_fsdata) { - dentry->d_fsdata = (void *)inode->i_ino; - break; ---- a/fs/autofs4/expire.c -+++ b/fs/autofs4/expire.c -@@ -91,7 +91,7 @@ static struct dentry *get_next_positive_ - spin_lock(&root->d_lock); - - if (prev) -- next = prev->d_u.d_child.next; -+ next = prev->d_child.next; - else { - prev = dget_dlock(root); - next = prev->d_subdirs.next; -@@ -105,13 +105,13 @@ cont: - return NULL; - } - -- q = list_entry(next, struct dentry, d_u.d_child); -+ q = list_entry(next, struct dentry, d_child); - - spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); - /* Already gone or negative dentry (under construction) - try next */ - if (!d_count(q) || !simple_positive(q)) { - spin_unlock(&q->d_lock); -- next = q->d_u.d_child.next; -+ next = q->d_child.next; - goto cont; - } - dget_dlock(q); -@@ -161,13 +161,13 @@ again: - goto relock; - } - spin_unlock(&p->d_lock); -- next = p->d_u.d_child.next; -+ next = p->d_child.next; - p = parent; - if (next != &parent->d_subdirs) - break; - } - } -- ret = list_entry(next, struct dentry, d_u.d_child); -+ ret = list_entry(next, struct dentry, d_child); - - spin_lock_nested(&ret->d_lock, DENTRY_D_LOCK_NESTED); - /* Negative dentry - try next */ -@@ -461,7 +461,7 @@ found: - spin_lock(&sbi->lookup_lock); - spin_lock(&expired->d_parent->d_lock); - spin_lock_nested(&expired->d_lock, DENTRY_D_LOCK_NESTED); -- list_move(&expired->d_parent->d_subdirs, &expired->d_u.d_child); -+ list_move(&expired->d_parent->d_subdirs, &expired->d_child); - spin_unlock(&expired->d_lock); - spin_unlock(&expired->d_parent->d_lock); - spin_unlock(&sbi->lookup_lock); ---- a/fs/autofs4/root.c -+++ b/fs/autofs4/root.c -@@ -655,7 +655,7 @@ static void autofs_clear_leaf_automount_ - /* only consider parents below dentrys in the root */ - if (IS_ROOT(parent->d_parent)) - return; -- d_child = &dentry->d_u.d_child; -+ d_child = &dentry->d_child; - /* Set parent managed if it's becoming empty */ - if (d_child->next == &parent->d_subdirs && - d_child->prev == &parent->d_subdirs) ---- a/fs/ceph/dir.c -+++ b/fs/ceph/dir.c -@@ -111,7 +111,7 @@ static int fpos_cmp(loff_t l, loff_t r) - /* - * When possible, we try to satisfy a readdir by peeking at the - * dcache. We make this work by carefully ordering dentries on -- * d_u.d_child when we initially get results back from the MDS, and -+ * d_child when we initially get results back from the MDS, and - * falling back to a "normal" sync readdir if any dentries in the dir - * are dropped. - * -@@ -147,11 +147,11 @@ static int __dcache_readdir(struct file - p = parent->d_subdirs.prev; - dout(" initial p %p/%p\n", p->prev, p->next); - } else { -- p = last->d_u.d_child.prev; -+ p = last->d_child.prev; - } - - more: -- dentry = list_entry(p, struct dentry, d_u.d_child); -+ dentry = list_entry(p, struct dentry, d_child); - di = ceph_dentry(dentry); - while (1) { - dout(" p %p/%p %s d_subdirs %p/%p\n", p->prev, p->next, -@@ -174,7 +174,7 @@ more: - !dentry->d_inode ? " null" : ""); - spin_unlock(&dentry->d_lock); - p = p->prev; -- dentry = list_entry(p, struct dentry, d_u.d_child); -+ dentry = list_entry(p, struct dentry, d_child); - di = ceph_dentry(dentry); - } - ---- a/fs/ceph/inode.c -+++ b/fs/ceph/inode.c -@@ -1399,7 +1399,7 @@ retry_lookup: - /* reorder parent's d_subdirs */ - spin_lock(&parent->d_lock); - spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); -- list_move(&dn->d_u.d_child, &parent->d_subdirs); -+ list_move(&dn->d_child, &parent->d_subdirs); - spin_unlock(&dn->d_lock); - spin_unlock(&parent->d_lock); - } ---- a/fs/cifs/inode.c -+++ b/fs/cifs/inode.c -@@ -887,7 +887,7 @@ inode_has_hashed_dentries(struct inode * - struct dentry *dentry; - - spin_lock(&inode->i_lock); -- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { - if (!d_unhashed(dentry) || IS_ROOT(dentry)) { - spin_unlock(&inode->i_lock); - return true; ---- a/fs/coda/cache.c -+++ b/fs/coda/cache.c -@@ -92,7 +92,7 @@ static void coda_flag_children(struct de - struct dentry *de; - - spin_lock(&parent->d_lock); -- list_for_each_entry(de, &parent->d_subdirs, d_u.d_child) { -+ list_for_each_entry(de, &parent->d_subdirs, d_child) { - /* don't know what to do with negative dentries */ - if (de->d_inode ) - coda_flag_inode(de->d_inode, flag); ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -44,7 +44,7 @@ - /* - * Usage: - * dcache->d_inode->i_lock protects: -- * - i_dentry, d_alias, d_inode of aliases -+ * - i_dentry, d_u.d_alias, d_inode of aliases - * dcache_hash_bucket lock protects: - * - the dcache hash table - * s_anon bl list spinlock protects: -@@ -59,7 +59,7 @@ - * - d_unhashed() - * - d_parent and d_subdirs - * - childrens' d_child and d_parent -- * - d_alias, d_inode -+ * - d_u.d_alias, d_inode - * - * Ordering: - * dentry->d_inode->i_lock -@@ -239,7 +239,6 @@ static void __d_free(struct rcu_head *he - { - struct dentry *dentry = container_of(head, struct dentry, d_u.d_rcu); - -- WARN_ON(!hlist_unhashed(&dentry->d_alias)); - if (dname_external(dentry)) - kfree(dentry->d_name.name); - kmem_cache_free(dentry_cache, dentry); -@@ -247,6 +246,8 @@ static void __d_free(struct rcu_head *he - - static void dentry_free(struct dentry *dentry) - { -+ WARN_ON(!hlist_unhashed(&dentry->d_u.d_alias)); -+ - /* if dentry was never visible to RCU, immediate free is OK */ - if (!(dentry->d_flags & DCACHE_RCUACCESS)) - __d_free(&dentry->d_u.d_rcu); -@@ -280,7 +281,7 @@ static void dentry_iput(struct dentry * - struct inode *inode = dentry->d_inode; - if (inode) { - dentry->d_inode = NULL; -- hlist_del_init(&dentry->d_alias); -+ hlist_del_init(&dentry->d_u.d_alias); - spin_unlock(&dentry->d_lock); - spin_unlock(&inode->i_lock); - if (!inode->i_nlink) -@@ -305,7 +306,7 @@ static void dentry_unlink_inode(struct d - struct inode *inode = dentry->d_inode; - __d_clear_type(dentry); - dentry->d_inode = NULL; -- hlist_del_init(&dentry->d_alias); -+ hlist_del_init(&dentry->d_u.d_alias); - dentry_rcuwalk_barrier(dentry); - spin_unlock(&dentry->d_lock); - spin_unlock(&inode->i_lock); -@@ -465,7 +466,7 @@ static void __dentry_kill(struct dentry - } - /* if it was on the hash then remove it */ - __d_drop(dentry); -- list_del(&dentry->d_u.d_child); -+ list_del(&dentry->d_child); - /* - * Inform d_walk() that we are no longer attached to the - * dentry tree -@@ -749,7 +750,7 @@ static struct dentry *__d_find_alias(str - - again: - discon_alias = NULL; -- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { - spin_lock(&alias->d_lock); - if (S_ISDIR(inode->i_mode) || !d_unhashed(alias)) { - if (IS_ROOT(alias) && -@@ -802,7 +803,7 @@ void d_prune_aliases(struct inode *inode - struct dentry *dentry; - restart: - spin_lock(&inode->i_lock); -- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { - spin_lock(&dentry->d_lock); - if (!dentry->d_lockref.count) { - /* -@@ -1087,7 +1088,7 @@ repeat: - resume: - while (next != &this_parent->d_subdirs) { - struct list_head *tmp = next; -- struct dentry *dentry = list_entry(tmp, struct dentry, d_u.d_child); -+ struct dentry *dentry = list_entry(tmp, struct dentry, d_child); - next = tmp->next; - - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); -@@ -1139,7 +1140,7 @@ resume: - goto rename_retry; - } - rcu_read_unlock(); -- next = child->d_u.d_child.next; -+ next = child->d_child.next; - goto resume; - } - if (need_seqretry(&rename_lock, seq)) { -@@ -1474,8 +1475,8 @@ struct dentry *__d_alloc(struct super_bl - INIT_HLIST_BL_NODE(&dentry->d_hash); - INIT_LIST_HEAD(&dentry->d_lru); - INIT_LIST_HEAD(&dentry->d_subdirs); -- INIT_HLIST_NODE(&dentry->d_alias); -- INIT_LIST_HEAD(&dentry->d_u.d_child); -+ INIT_HLIST_NODE(&dentry->d_u.d_alias); -+ INIT_LIST_HEAD(&dentry->d_child); - d_set_d_op(dentry, dentry->d_sb->s_d_op); - - this_cpu_inc(nr_dentry); -@@ -1505,7 +1506,7 @@ struct dentry *d_alloc(struct dentry * p - */ - __dget_dlock(parent); - dentry->d_parent = parent; -- list_add(&dentry->d_u.d_child, &parent->d_subdirs); -+ list_add(&dentry->d_child, &parent->d_subdirs); - spin_unlock(&parent->d_lock); - - return dentry; -@@ -1598,7 +1599,7 @@ static void __d_instantiate(struct dentr - spin_lock(&dentry->d_lock); - __d_set_type(dentry, add_flags); - if (inode) -- hlist_add_head(&dentry->d_alias, &inode->i_dentry); -+ hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry); - dentry->d_inode = inode; - dentry_rcuwalk_barrier(dentry); - spin_unlock(&dentry->d_lock); -@@ -1622,7 +1623,7 @@ static void __d_instantiate(struct dentr - - void d_instantiate(struct dentry *entry, struct inode * inode) - { -- BUG_ON(!hlist_unhashed(&entry->d_alias)); -+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); - if (inode) - spin_lock(&inode->i_lock); - __d_instantiate(entry, inode); -@@ -1661,7 +1662,7 @@ static struct dentry *__d_instantiate_un - return NULL; - } - -- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { - /* - * Don't need alias->d_lock here, because aliases with - * d_parent == entry->d_parent are not subject to name or -@@ -1687,7 +1688,7 @@ struct dentry *d_instantiate_unique(stru - { - struct dentry *result; - -- BUG_ON(!hlist_unhashed(&entry->d_alias)); -+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); - - if (inode) - spin_lock(&inode->i_lock); -@@ -1718,7 +1719,7 @@ EXPORT_SYMBOL(d_instantiate_unique); - */ - int d_instantiate_no_diralias(struct dentry *entry, struct inode *inode) - { -- BUG_ON(!hlist_unhashed(&entry->d_alias)); -+ BUG_ON(!hlist_unhashed(&entry->d_u.d_alias)); - - spin_lock(&inode->i_lock); - if (S_ISDIR(inode->i_mode) && !hlist_empty(&inode->i_dentry)) { -@@ -1757,7 +1758,7 @@ static struct dentry * __d_find_any_alia - - if (hlist_empty(&inode->i_dentry)) - return NULL; -- alias = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); -+ alias = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - __dget(alias); - return alias; - } -@@ -1834,7 +1835,7 @@ struct dentry *d_obtain_alias(struct ino - spin_lock(&tmp->d_lock); - tmp->d_inode = inode; - tmp->d_flags |= add_flags; -- hlist_add_head(&tmp->d_alias, &inode->i_dentry); -+ hlist_add_head(&tmp->d_u.d_alias, &inode->i_dentry); - hlist_bl_lock(&tmp->d_sb->s_anon); - hlist_bl_add_head(&tmp->d_hash, &tmp->d_sb->s_anon); - hlist_bl_unlock(&tmp->d_sb->s_anon); -@@ -2277,7 +2278,7 @@ int d_validate(struct dentry *dentry, st - struct dentry *child; - - spin_lock(&dparent->d_lock); -- list_for_each_entry(child, &dparent->d_subdirs, d_u.d_child) { -+ list_for_each_entry(child, &dparent->d_subdirs, d_child) { - if (dentry == child) { - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); - __dget_dlock(dentry); -@@ -2545,8 +2546,8 @@ static void __d_move(struct dentry *dent - d_hash(dentry->d_parent, dentry->d_name.hash)); - } - -- list_del(&dentry->d_u.d_child); -- list_del(&target->d_u.d_child); -+ list_del(&dentry->d_child); -+ list_del(&target->d_child); - - /* Switch the names.. */ - switch_names(dentry, target, exchange); -@@ -2555,15 +2556,15 @@ static void __d_move(struct dentry *dent - if (IS_ROOT(dentry)) { - dentry->d_parent = target->d_parent; - target->d_parent = target; -- INIT_LIST_HEAD(&target->d_u.d_child); -+ INIT_LIST_HEAD(&target->d_child); - } else { - swap(dentry->d_parent, target->d_parent); - - /* And add them back to the (new) parent lists */ -- list_add(&target->d_u.d_child, &target->d_parent->d_subdirs); -+ list_add(&target->d_child, &target->d_parent->d_subdirs); - } - -- list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); -+ list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); - - write_seqcount_end(&target->d_seq); - write_seqcount_end(&dentry->d_seq); -@@ -2690,9 +2691,9 @@ static void __d_materialise_dentry(struc - switch_names(dentry, anon, false); - - dentry->d_parent = dentry; -- list_del_init(&dentry->d_u.d_child); -+ list_del_init(&dentry->d_child); - anon->d_parent = dparent; -- list_move(&anon->d_u.d_child, &dparent->d_subdirs); -+ list_move(&anon->d_child, &dparent->d_subdirs); - - write_seqcount_end(&dentry->d_seq); - write_seqcount_end(&anon->d_seq); -@@ -3324,7 +3325,7 @@ void d_tmpfile(struct dentry *dentry, st - { - inode_dec_link_count(inode); - BUG_ON(dentry->d_name.name != dentry->d_iname || -- !hlist_unhashed(&dentry->d_alias) || -+ !hlist_unhashed(&dentry->d_u.d_alias) || - !d_unlinked(dentry)); - spin_lock(&dentry->d_parent->d_lock); - spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); ---- a/fs/debugfs/inode.c -+++ b/fs/debugfs/inode.c -@@ -553,7 +553,7 @@ void debugfs_remove_recursive(struct den - * use the d_u.d_child as the rcu head and corrupt this list. - */ - spin_lock(&parent->d_lock); -- list_for_each_entry(child, &parent->d_subdirs, d_u.d_child) { -+ list_for_each_entry(child, &parent->d_subdirs, d_child) { - if (!debugfs_positive(child)) - continue; - ---- a/fs/exportfs/expfs.c -+++ b/fs/exportfs/expfs.c -@@ -50,7 +50,7 @@ find_acceptable_alias(struct dentry *res - - inode = result->d_inode; - spin_lock(&inode->i_lock); -- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { - dget(dentry); - spin_unlock(&inode->i_lock); - if (toput) ---- a/fs/libfs.c -+++ b/fs/libfs.c -@@ -114,18 +114,18 @@ loff_t dcache_dir_lseek(struct file *fil - - spin_lock(&dentry->d_lock); - /* d_lock not required for cursor */ -- list_del(&cursor->d_u.d_child); -+ list_del(&cursor->d_child); - p = dentry->d_subdirs.next; - while (n && p != &dentry->d_subdirs) { - struct dentry *next; -- next = list_entry(p, struct dentry, d_u.d_child); -+ next = list_entry(p, struct dentry, d_child); - spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); - if (simple_positive(next)) - n--; - spin_unlock(&next->d_lock); - p = p->next; - } -- list_add_tail(&cursor->d_u.d_child, p); -+ list_add_tail(&cursor->d_child, p); - spin_unlock(&dentry->d_lock); - } - } -@@ -150,7 +150,7 @@ int dcache_readdir(struct file *file, st - { - struct dentry *dentry = file->f_path.dentry; - struct dentry *cursor = file->private_data; -- struct list_head *p, *q = &cursor->d_u.d_child; -+ struct list_head *p, *q = &cursor->d_child; - - if (!dir_emit_dots(file, ctx)) - return 0; -@@ -159,7 +159,7 @@ int dcache_readdir(struct file *file, st - list_move(q, &dentry->d_subdirs); - - for (p = q->next; p != &dentry->d_subdirs; p = p->next) { -- struct dentry *next = list_entry(p, struct dentry, d_u.d_child); -+ struct dentry *next = list_entry(p, struct dentry, d_child); - spin_lock_nested(&next->d_lock, DENTRY_D_LOCK_NESTED); - if (!simple_positive(next)) { - spin_unlock(&next->d_lock); -@@ -287,7 +287,7 @@ int simple_empty(struct dentry *dentry) - int ret = 0; - - spin_lock(&dentry->d_lock); -- list_for_each_entry(child, &dentry->d_subdirs, d_u.d_child) { -+ list_for_each_entry(child, &dentry->d_subdirs, d_child) { - spin_lock_nested(&child->d_lock, DENTRY_D_LOCK_NESTED); - if (simple_positive(child)) { - spin_unlock(&child->d_lock); ---- a/fs/ncpfs/dir.c -+++ b/fs/ncpfs/dir.c -@@ -406,7 +406,7 @@ ncp_dget_fpos(struct dentry *dentry, str - spin_lock(&parent->d_lock); - next = parent->d_subdirs.next; - while (next != &parent->d_subdirs) { -- dent = list_entry(next, struct dentry, d_u.d_child); -+ dent = list_entry(next, struct dentry, d_child); - if ((unsigned long)dent->d_fsdata == fpos) { - if (dent->d_inode) - dget(dent); ---- a/fs/ncpfs/ncplib_kernel.h -+++ b/fs/ncpfs/ncplib_kernel.h -@@ -194,7 +194,7 @@ ncp_renew_dentries(struct dentry *parent - spin_lock(&parent->d_lock); - next = parent->d_subdirs.next; - while (next != &parent->d_subdirs) { -- dentry = list_entry(next, struct dentry, d_u.d_child); -+ dentry = list_entry(next, struct dentry, d_child); - - if (dentry->d_fsdata == NULL) - ncp_age_dentry(server, dentry); -@@ -216,7 +216,7 @@ ncp_invalidate_dircache_entries(struct d - spin_lock(&parent->d_lock); - next = parent->d_subdirs.next; - while (next != &parent->d_subdirs) { -- dentry = list_entry(next, struct dentry, d_u.d_child); -+ dentry = list_entry(next, struct dentry, d_child); - dentry->d_fsdata = NULL; - ncp_age_dentry(server, dentry); - next = next->next; ---- a/fs/nfs/getroot.c -+++ b/fs/nfs/getroot.c -@@ -58,7 +58,7 @@ static int nfs_superblock_set_dummy_root - */ - spin_lock(&sb->s_root->d_inode->i_lock); - spin_lock(&sb->s_root->d_lock); -- hlist_del_init(&sb->s_root->d_alias); -+ hlist_del_init(&sb->s_root->d_u.d_alias); - spin_unlock(&sb->s_root->d_lock); - spin_unlock(&sb->s_root->d_inode->i_lock); - } ---- a/fs/notify/fsnotify.c -+++ b/fs/notify/fsnotify.c -@@ -63,14 +63,14 @@ void __fsnotify_update_child_dentry_flag - spin_lock(&inode->i_lock); - /* run all of the dentries associated with this inode. Since this is a - * directory, there damn well better only be one item on this list */ -- hlist_for_each_entry(alias, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(alias, &inode->i_dentry, d_u.d_alias) { - struct dentry *child; - - /* run all of the children of the original inode and fix their - * d_flags to indicate parental interest (their parent is the - * original inode) */ - spin_lock(&alias->d_lock); -- list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { -+ list_for_each_entry(child, &alias->d_subdirs, d_child) { - if (!child->d_inode) - continue; - ---- a/fs/ocfs2/dcache.c -+++ b/fs/ocfs2/dcache.c -@@ -172,7 +172,7 @@ struct dentry *ocfs2_find_local_alias(st - struct dentry *dentry; - - spin_lock(&inode->i_lock); -- hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) { -+ hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { - spin_lock(&dentry->d_lock); - if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) { - trace_ocfs2_find_local_alias(dentry->d_name.len, ---- a/include/linux/dcache.h -+++ b/include/linux/dcache.h -@@ -124,15 +124,15 @@ struct dentry { - void *d_fsdata; /* fs-specific data */ - - struct list_head d_lru; /* LRU list */ -+ struct list_head d_child; /* child of parent list */ -+ struct list_head d_subdirs; /* our children */ - /* -- * d_child and d_rcu can share memory -+ * d_alias and d_rcu can share memory - */ - union { -- struct list_head d_child; /* child of parent list */ -+ struct hlist_node d_alias; /* inode alias list */ - struct rcu_head d_rcu; - } d_u; -- struct list_head d_subdirs; /* our children */ -- struct hlist_node d_alias; /* inode alias list */ - }; - - /* ---- a/kernel/trace/trace.c -+++ b/kernel/trace/trace.c -@@ -6384,7 +6384,7 @@ static int instance_mkdir (struct inode - int ret; - - /* Paranoid: Make sure the parent is the "instances" directory */ -- parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); -+ parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - if (WARN_ON_ONCE(parent != trace_instance_dir)) - return -ENOENT; - -@@ -6411,7 +6411,7 @@ static int instance_rmdir(struct inode * - int ret; - - /* Paranoid: Make sure the parent is the "instances" directory */ -- parent = hlist_entry(inode->i_dentry.first, struct dentry, d_alias); -+ parent = hlist_entry(inode->i_dentry.first, struct dentry, d_u.d_alias); - if (WARN_ON_ONCE(parent != trace_instance_dir)) - return -ENOENT; - ---- a/kernel/trace/trace_events.c -+++ b/kernel/trace/trace_events.c -@@ -459,7 +459,7 @@ static void remove_event_file_dir(struct - - if (dir) { - spin_lock(&dir->d_lock); /* probably unneeded */ -- list_for_each_entry(child, &dir->d_subdirs, d_u.d_child) { -+ list_for_each_entry(child, &dir->d_subdirs, d_child) { - if (child->d_inode) /* probably unneeded */ - child->d_inode->i_private = NULL; - } ---- a/security/selinux/selinuxfs.c -+++ b/security/selinux/selinuxfs.c -@@ -1200,7 +1200,7 @@ static void sel_remove_entries(struct de - spin_lock(&de->d_lock); - node = de->d_subdirs.next; - while (node != &de->d_subdirs) { -- struct dentry *d = list_entry(node, struct dentry, d_u.d_child); -+ struct dentry *d = list_entry(node, struct dentry, d_child); - - spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); - list_del_init(node); -@@ -1674,12 +1674,12 @@ static void sel_remove_classes(void) - - list_for_each(class_node, &class_dir->d_subdirs) { - struct dentry *class_subdir = list_entry(class_node, -- struct dentry, d_u.d_child); -+ struct dentry, d_child); - struct list_head *class_subdir_node; - - list_for_each(class_subdir_node, &class_subdir->d_subdirs) { - struct dentry *d = list_entry(class_subdir_node, -- struct dentry, d_u.d_child); -+ struct dentry, d_child); - - if (d->d_inode) - if (d->d_inode->i_mode & S_IFDIR) diff --git a/debian/patches/bugfix/s390/s390-3215-fix-hanging-console-issue.patch b/debian/patches/bugfix/s390/s390-3215-fix-hanging-console-issue.patch deleted file mode 100644 index b9e7f5435..000000000 --- a/debian/patches/bugfix/s390/s390-3215-fix-hanging-console-issue.patch +++ /dev/null @@ -1,69 +0,0 @@ -From: Martin Schwidefsky -Date: Tue, 15 Jul 2014 17:53:12 +0200 -Subject: s390/3215: fix hanging console issue -Origin: https://git.kernel.org/cgit/linux/kernel/git/s390/linux.git/commit?id=26d766c60f4ea08cd14f0f3435a6db3d6cc2ae96 -Bug-Debian: https://bugs.debian.org/747922 - -The ccw_device_start in raw3215_start_io can fail. raw3215_try_io -does not check if the request could be started and removes any -pending timer. This can leave the system in a hanging state. -Check for pending request after raw3215_start_io and start a -timer if necessary. - -Signed-off-by: Martin Schwidefsky ---- - drivers/s390/char/con3215.c | 32 +++++++++++++++++--------------- - 1 file changed, 17 insertions(+), 15 deletions(-) - -diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c -index 5af7f0b..a6d47e5 100644 ---- a/drivers/s390/char/con3215.c -+++ b/drivers/s390/char/con3215.c -@@ -288,12 +288,16 @@ static void raw3215_timeout(unsigned long __data) - unsigned long flags; - - spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags); -- if (raw->flags & RAW3215_TIMER_RUNS) { -- del_timer(&raw->timer); -- raw->flags &= ~RAW3215_TIMER_RUNS; -- if (!(raw->port.flags & ASYNC_SUSPENDED)) { -- raw3215_mk_write_req(raw); -- raw3215_start_io(raw); -+ raw->flags &= ~RAW3215_TIMER_RUNS; -+ if (!(raw->port.flags & ASYNC_SUSPENDED)) { -+ raw3215_mk_write_req(raw); -+ raw3215_start_io(raw); -+ if ((raw->queued_read || raw->queued_write) && -+ !(raw->flags & RAW3215_WORKING) && -+ !(raw->flags & RAW3215_TIMER_RUNS)) { -+ raw->timer.expires = RAW3215_TIMEOUT + jiffies; -+ add_timer(&raw->timer); -+ raw->flags |= RAW3215_TIMER_RUNS; - } - } - spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags); -@@ -317,17 +321,15 @@ static inline void raw3215_try_io(struct raw3215_info *raw) - (raw->flags & RAW3215_FLUSHING)) { - /* execute write requests bigger than minimum size */ - raw3215_start_io(raw); -- if (raw->flags & RAW3215_TIMER_RUNS) { -- del_timer(&raw->timer); -- raw->flags &= ~RAW3215_TIMER_RUNS; -- } -- } else if (!(raw->flags & RAW3215_TIMER_RUNS)) { -- /* delay small writes */ -- raw->timer.expires = RAW3215_TIMEOUT + jiffies; -- add_timer(&raw->timer); -- raw->flags |= RAW3215_TIMER_RUNS; - } - } -+ if ((raw->queued_read || raw->queued_write) && -+ !(raw->flags & RAW3215_WORKING) && -+ !(raw->flags & RAW3215_TIMER_RUNS)) { -+ raw->timer.expires = RAW3215_TIMEOUT + jiffies; -+ add_timer(&raw->timer); -+ raw->flags |= RAW3215_TIMER_RUNS; -+ } - } - - /* diff --git a/debian/patches/bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch b/debian/patches/bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch deleted file mode 100644 index cc6ac17dd..000000000 --- a/debian/patches/bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Martin Schwidefsky -Date: Wed, 13 Aug 2014 12:01:30 +0200 -Subject: s390/3215: fix tty output containing tabs -Origin: https://git.kernel.org/linus/e512d56c799517f33b301d81e9a5e0ebf30c2d1e - -git commit 37f81fa1f63ad38e16125526bb2769ae0ea8d332 -"n_tty: do O_ONLCR translation as a single write" -surfaced a bug in the 3215 device driver. In combination this -broke tab expansion for tty ouput. - -The cause is an asymmetry in the behaviour of tty3215_ops->write -vs tty3215_ops->put_char. The put_char function scans for '\t' -but the write function does not. - -As the driver has logic for the '\t' expansion remove XTABS -from c_oflag of the initial termios as well. - -Reported-by: Stephen Powell -Signed-off-by: Martin Schwidefsky ---- - drivers/s390/char/con3215.c | 20 +++++++++++++++++--- - 1 file changed, 17 insertions(+), 3 deletions(-) - -diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c -index a6d47e5..c43aca6 100644 ---- a/drivers/s390/char/con3215.c -+++ b/drivers/s390/char/con3215.c -@@ -1035,12 +1035,26 @@ static int tty3215_write(struct tty_struct * tty, - const unsigned char *buf, int count) - { - struct raw3215_info *raw; -+ int i, written; - - if (!tty) - return 0; - raw = (struct raw3215_info *) tty->driver_data; -- raw3215_write(raw, buf, count); -- return count; -+ written = count; -+ while (count > 0) { -+ for (i = 0; i < count; i++) -+ if (buf[i] == '\t' || buf[i] == '\n') -+ break; -+ raw3215_write(raw, buf, i); -+ count -= i; -+ buf += i; -+ if (count > 0) { -+ raw3215_putchar(raw, *buf); -+ count--; -+ buf++; -+ } -+ } -+ return written; - } - - /* -@@ -1188,7 +1202,7 @@ static int __init tty3215_init(void) - driver->subtype = SYSTEM_TYPE_TTY; - driver->init_termios = tty_std_termios; - driver->init_termios.c_iflag = IGNBRK | IGNPAR; -- driver->init_termios.c_oflag = ONLCR | XTABS; -+ driver->init_termios.c_oflag = ONLCR; - driver->init_termios.c_lflag = ISIG; - driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(driver, &tty3215_ops); diff --git a/debian/patches/bugfix/x86/x86-kvm-clear-paravirt_enabled-on-kvm-guests-for-esp.patch b/debian/patches/bugfix/x86/x86-kvm-clear-paravirt_enabled-on-kvm-guests-for-esp.patch deleted file mode 100644 index 372a7160a..000000000 --- a/debian/patches/bugfix/x86/x86-kvm-clear-paravirt_enabled-on-kvm-guests-for-esp.patch +++ /dev/null @@ -1,63 +0,0 @@ -From: Andy Lutomirski -Date: Fri, 5 Dec 2014 19:03:28 -0800 -Subject: x86, kvm: Clear paravirt_enabled on KVM guests for espfix32's benefit -Origin: https://git.kernel.org/linus/29fa6825463c97e5157284db80107d1bfac5d77b - -paravirt_enabled has the following effects: - - - Disables the F00F bug workaround warning. There is no F00F bug - workaround any more because Linux's standard IDT handling already - works around the F00F bug, but the warning still exists. This - is only cosmetic, and, in any event, there is no such thing as - KVM on a CPU with the F00F bug. - - - Disables 32-bit APM BIOS detection. On a KVM paravirt system, - there should be no APM BIOS anyway. - - - Disables tboot. I think that the tboot code should check the - CPUID hypervisor bit directly if it matters. - - - paravirt_enabled disables espfix32. espfix32 should *not* be - disabled under KVM paravirt. - -The last point is the purpose of this patch. It fixes a leak of the -high 16 bits of the kernel stack address on 32-bit KVM paravirt -guests. Fixes CVE-2014-8134. - -Cc: stable@vger.kernel.org -Suggested-by: Konrad Rzeszutek Wilk -Signed-off-by: Andy Lutomirski -Signed-off-by: Paolo Bonzini ---- - arch/x86/kernel/kvm.c | 9 ++++++++- - arch/x86/kernel/kvmclock.c | 1 - - 2 files changed, 8 insertions(+), 2 deletions(-) - ---- a/arch/x86/kernel/kvm.c -+++ b/arch/x86/kernel/kvm.c -@@ -282,7 +282,14 @@ NOKPROBE_SYMBOL(do_async_page_fault); - static void __init paravirt_ops_setup(void) - { - pv_info.name = "KVM"; -- pv_info.paravirt_enabled = 1; -+ -+ /* -+ * KVM isn't paravirt in the sense of paravirt_enabled. A KVM -+ * guest kernel works like a bare metal kernel with additional -+ * features, and paravirt_enabled is about features that are -+ * missing. -+ */ -+ pv_info.paravirt_enabled = 0; - - if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) - pv_cpu_ops.io_delay = kvm_io_delay; ---- a/arch/x86/kernel/kvmclock.c -+++ b/arch/x86/kernel/kvmclock.c -@@ -263,7 +263,6 @@ void __init kvmclock_init(void) - #endif - kvm_get_preset_lpj(); - clocksource_register_hz(&kvm_clock, NSEC_PER_SEC); -- pv_info.paravirt_enabled = 1; - pv_info.name = "KVM"; - - if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) diff --git a/debian/patches/bugfix/x86/x86-tls-validate-tls-entries-to-protect-espfix.patch b/debian/patches/bugfix/x86/x86-tls-validate-tls-entries-to-protect-espfix.patch deleted file mode 100644 index bf7690eec..000000000 --- a/debian/patches/bugfix/x86/x86-tls-validate-tls-entries-to-protect-espfix.patch +++ /dev/null @@ -1,75 +0,0 @@ -From: Andy Lutomirski -Date: Thu, 4 Dec 2014 16:48:16 -0800 -Subject: x86/tls: Validate TLS entries to protect espfix -Origin: https://git.kernel.org/linus/41bdc78544b8a93a9c6814b8bbbfef966272abbe - -Installing a 16-bit RW data segment into the GDT defeats espfix. -AFAICT this will not affect glibc, Wine, or dosemu at all. - -Signed-off-by: Andy Lutomirski -Acked-by: H. Peter Anvin -Cc: stable@vger.kernel.org -Cc: Konrad Rzeszutek Wilk -Cc: Linus Torvalds -Cc: security@kernel.org -Cc: Willy Tarreau -Signed-off-by: Ingo Molnar ---- - arch/x86/kernel/tls.c | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c -index f7fec09..e7650bd 100644 ---- a/arch/x86/kernel/tls.c -+++ b/arch/x86/kernel/tls.c -@@ -27,6 +27,21 @@ static int get_free_idx(void) - return -ESRCH; - } - -+static bool tls_desc_okay(const struct user_desc *info) -+{ -+ if (LDT_empty(info)) -+ return true; -+ -+ /* -+ * espfix is required for 16-bit data segments, but espfix -+ * only works for LDT segments. -+ */ -+ if (!info->seg_32bit) -+ return false; -+ -+ return true; -+} -+ - static void set_tls_desc(struct task_struct *p, int idx, - const struct user_desc *info, int n) - { -@@ -66,6 +81,9 @@ int do_set_thread_area(struct task_struct *p, int idx, - if (copy_from_user(&info, u_info, sizeof(info))) - return -EFAULT; - -+ if (!tls_desc_okay(&info)) -+ return -EINVAL; -+ - if (idx == -1) - idx = info.entry_number; - -@@ -192,6 +210,7 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, - { - struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES]; - const struct user_desc *info; -+ int i; - - if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || - (pos % sizeof(struct user_desc)) != 0 || -@@ -205,6 +224,10 @@ int regset_tls_set(struct task_struct *target, const struct user_regset *regset, - else - info = infobuf; - -+ for (i = 0; i < count / sizeof(struct user_desc); i++) -+ if (!tls_desc_okay(info + i)) -+ return -EINVAL; -+ - set_tls_desc(target, - GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)), - info, count / sizeof(struct user_desc)); diff --git a/debian/patches/bugfix/x86/x86_64-switch_to-load-tls-descriptors-before-switchi.patch b/debian/patches/bugfix/x86/x86_64-switch_to-load-tls-descriptors-before-switchi.patch deleted file mode 100644 index e426b726d..000000000 --- a/debian/patches/bugfix/x86/x86_64-switch_to-load-tls-descriptors-before-switchi.patch +++ /dev/null @@ -1,304 +0,0 @@ -From: Andy Lutomirski -Date: Mon, 8 Dec 2014 13:55:20 -0800 -Subject: x86_64, switch_to(): Load TLS descriptors before switching DS and ES -Origin: https://git.kernel.org/linus/f647d7c155f069c1a068030255c300663516420e - -Otherwise, if buggy user code points DS or ES into the TLS -array, they would be corrupted after a context switch. - -This also significantly improves the comments and documents some -gotchas in the code. - -Before this patch, the both tests below failed. With this -patch, the es test passes, although the gsbase test still fails. - - ----- begin es test ----- - -/* - * Copyright (c) 2014 Andy Lutomirski - * GPL v2 - */ - -static unsigned short GDT3(int idx) -{ - return (idx << 3) | 3; -} - -static int create_tls(int idx, unsigned int base) -{ - struct user_desc desc = { - .entry_number = idx, - .base_addr = base, - .limit = 0xfffff, - .seg_32bit = 1, - .contents = 0, /* Data, grow-up */ - .read_exec_only = 0, - .limit_in_pages = 1, - .seg_not_present = 0, - .useable = 0, - }; - - if (syscall(SYS_set_thread_area, &desc) != 0) - err(1, "set_thread_area"); - - return desc.entry_number; -} - -int main() -{ - int idx = create_tls(-1, 0); - printf("Allocated GDT index %d\n", idx); - - unsigned short orig_es; - asm volatile ("mov %%es,%0" : "=rm" (orig_es)); - - int errors = 0; - int total = 1000; - for (int i = 0; i < total; i++) { - asm volatile ("mov %0,%%es" : : "rm" (GDT3(idx))); - usleep(100); - - unsigned short es; - asm volatile ("mov %%es,%0" : "=rm" (es)); - asm volatile ("mov %0,%%es" : : "rm" (orig_es)); - if (es != GDT3(idx)) { - if (errors == 0) - printf("[FAIL]\tES changed from 0x%hx to 0x%hx\n", - GDT3(idx), es); - errors++; - } - } - - if (errors) { - printf("[FAIL]\tES was corrupted %d/%d times\n", errors, total); - return 1; - } else { - printf("[OK]\tES was preserved\n"); - return 0; - } -} - - ----- end es test ----- - - ----- begin gsbase test ----- - -/* - * gsbase.c, a gsbase test - * Copyright (c) 2014 Andy Lutomirski - * GPL v2 - */ - -static unsigned char *testptr, *testptr2; - -static unsigned char read_gs_testvals(void) -{ - unsigned char ret; - asm volatile ("movb %%gs:%1, %0" : "=r" (ret) : "m" (*testptr)); - return ret; -} - -int main() -{ - int errors = 0; - - testptr = mmap((void *)0x200000000UL, 1, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); - if (testptr == MAP_FAILED) - err(1, "mmap"); - - testptr2 = mmap((void *)0x300000000UL, 1, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0); - if (testptr2 == MAP_FAILED) - err(1, "mmap"); - - *testptr = 0; - *testptr2 = 1; - - if (syscall(SYS_arch_prctl, ARCH_SET_GS, - (unsigned long)testptr2 - (unsigned long)testptr) != 0) - err(1, "ARCH_SET_GS"); - - usleep(100); - - if (read_gs_testvals() == 1) { - printf("[OK]\tARCH_SET_GS worked\n"); - } else { - printf("[FAIL]\tARCH_SET_GS failed\n"); - errors++; - } - - asm volatile ("mov %0,%%gs" : : "r" (0)); - - if (read_gs_testvals() == 0) { - printf("[OK]\tWriting 0 to gs worked\n"); - } else { - printf("[FAIL]\tWriting 0 to gs failed\n"); - errors++; - } - - usleep(100); - - if (read_gs_testvals() == 0) { - printf("[OK]\tgsbase is still zero\n"); - } else { - printf("[FAIL]\tgsbase was corrupted\n"); - errors++; - } - - return errors == 0 ? 0 : 1; -} - - ----- end gsbase test ----- - -Signed-off-by: Andy Lutomirski -Cc: -Cc: Andi Kleen -Cc: Linus Torvalds -Link: http://lkml.kernel.org/r/509d27c9fec78217691c3dad91cec87e1006b34a.1418075657.git.luto@amacapital.net -Signed-off-by: Ingo Molnar ---- - arch/x86/kernel/process_64.c | 101 +++++++++++++++++++++++++++++++------------ - 1 file changed, 73 insertions(+), 28 deletions(-) - ---- a/arch/x86/kernel/process_64.c -+++ b/arch/x86/kernel/process_64.c -@@ -286,24 +286,9 @@ __switch_to(struct task_struct *prev_p, - - fpu = switch_fpu_prepare(prev_p, next_p, cpu); - -- /* -- * Reload esp0, LDT and the page table pointer: -- */ -+ /* Reload esp0 and ss1. */ - load_sp0(tss, next); - -- /* -- * Switch DS and ES. -- * This won't pick up thread selector changes, but I guess that is ok. -- */ -- savesegment(es, prev->es); -- if (unlikely(next->es | prev->es)) -- loadsegment(es, next->es); -- -- savesegment(ds, prev->ds); -- if (unlikely(next->ds | prev->ds)) -- loadsegment(ds, next->ds); -- -- - /* We must save %fs and %gs before load_TLS() because - * %fs and %gs may be cleared by load_TLS(). - * -@@ -312,41 +297,101 @@ __switch_to(struct task_struct *prev_p, - savesegment(fs, fsindex); - savesegment(gs, gsindex); - -+ /* -+ * Load TLS before restoring any segments so that segment loads -+ * reference the correct GDT entries. -+ */ - load_TLS(next, cpu); - - /* -- * Leave lazy mode, flushing any hypercalls made here. -- * This must be done before restoring TLS segments so -- * the GDT and LDT are properly updated, and must be -- * done before math_state_restore, so the TS bit is up -- * to date. -+ * Leave lazy mode, flushing any hypercalls made here. This -+ * must be done after loading TLS entries in the GDT but before -+ * loading segments that might reference them, and and it must -+ * be done before math_state_restore, so the TS bit is up to -+ * date. - */ - arch_end_context_switch(next_p); - -+ /* Switch DS and ES. -+ * -+ * Reading them only returns the selectors, but writing them (if -+ * nonzero) loads the full descriptor from the GDT or LDT. The -+ * LDT for next is loaded in switch_mm, and the GDT is loaded -+ * above. -+ * -+ * We therefore need to write new values to the segment -+ * registers on every context switch unless both the new and old -+ * values are zero. -+ * -+ * Note that we don't need to do anything for CS and SS, as -+ * those are saved and restored as part of pt_regs. -+ */ -+ savesegment(es, prev->es); -+ if (unlikely(next->es | prev->es)) -+ loadsegment(es, next->es); -+ -+ savesegment(ds, prev->ds); -+ if (unlikely(next->ds | prev->ds)) -+ loadsegment(ds, next->ds); -+ - /* - * Switch FS and GS. - * -- * Segment register != 0 always requires a reload. Also -- * reload when it has changed. When prev process used 64bit -- * base always reload to avoid an information leak. -+ * These are even more complicated than FS and GS: they have -+ * 64-bit bases are that controlled by arch_prctl. Those bases -+ * only differ from the values in the GDT or LDT if the selector -+ * is 0. -+ * -+ * Loading the segment register resets the hidden base part of -+ * the register to 0 or the value from the GDT / LDT. If the -+ * next base address zero, writing 0 to the segment register is -+ * much faster than using wrmsr to explicitly zero the base. -+ * -+ * The thread_struct.fs and thread_struct.gs values are 0 -+ * if the fs and gs bases respectively are not overridden -+ * from the values implied by fsindex and gsindex. They -+ * are nonzero, and store the nonzero base addresses, if -+ * the bases are overridden. -+ * -+ * (fs != 0 && fsindex != 0) || (gs != 0 && gsindex != 0) should -+ * be impossible. -+ * -+ * Therefore we need to reload the segment registers if either -+ * the old or new selector is nonzero, and we need to override -+ * the base address if next thread expects it to be overridden. -+ * -+ * This code is unnecessarily slow in the case where the old and -+ * new indexes are zero and the new base is nonzero -- it will -+ * unnecessarily write 0 to the selector before writing the new -+ * base address. -+ * -+ * Note: This all depends on arch_prctl being the only way that -+ * user code can override the segment base. Once wrfsbase and -+ * wrgsbase are enabled, most of this code will need to change. - */ - if (unlikely(fsindex | next->fsindex | prev->fs)) { - loadsegment(fs, next->fsindex); -+ - /* -- * Check if the user used a selector != 0; if yes -- * clear 64bit base, since overloaded base is always -- * mapped to the Null selector -+ * If user code wrote a nonzero value to FS, then it also -+ * cleared the overridden base address. -+ * -+ * XXX: if user code wrote 0 to FS and cleared the base -+ * address itself, we won't notice and we'll incorrectly -+ * restore the prior base address next time we reschdule -+ * the process. - */ - if (fsindex) - prev->fs = 0; - } -- /* when next process has a 64bit base use it */ - if (next->fs) - wrmsrl(MSR_FS_BASE, next->fs); - prev->fsindex = fsindex; - - if (unlikely(gsindex | next->gsindex | prev->gs)) { - load_gs_index(next->gsindex); -+ -+ /* This works (and fails) the same way as fsindex above. */ - if (gsindex) - prev->gs = 0; - } diff --git a/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch index 53f45b13d..568569418 100644 --- a/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch +++ b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch @@ -15,7 +15,7 @@ Signed-off-by: Serge Hallyn --- --- a/kernel/fork.c +++ b/kernel/fork.c -@@ -83,6 +83,11 @@ +@@ -86,6 +86,11 @@ #define CREATE_TRACE_POINTS #include @@ -27,7 +27,7 @@ Signed-off-by: Serge Hallyn /* * Protected counters by write_lock_irq(&tasklist_lock) -@@ -1144,6 +1149,10 @@ static struct task_struct *copy_process( +@@ -1149,6 +1154,10 @@ static struct task_struct *copy_process( if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) return ERR_PTR(-EINVAL); @@ -38,7 +38,7 @@ Signed-off-by: Serge Hallyn /* * Thread groups must share signals as well, and detached threads * can only be started up within the thread group. -@@ -1831,6 +1840,12 @@ SYSCALL_DEFINE1(unshare, unsigned long, +@@ -1843,6 +1852,12 @@ SYSCALL_DEFINE1(unshare, unsigned long, if (unshare_flags & CLONE_NEWNS) unshare_flags |= CLONE_FS; @@ -53,7 +53,7 @@ Signed-off-by: Serge Hallyn goto bad_unshare_out; --- a/kernel/sysctl.c +++ b/kernel/sysctl.c -@@ -104,6 +104,9 @@ extern int core_uses_pid; +@@ -103,6 +103,9 @@ extern int core_uses_pid; extern char core_pattern[]; extern unsigned int core_pipe_limit; #endif @@ -63,7 +63,7 @@ Signed-off-by: Serge Hallyn extern int pid_max; extern int pid_max_min, pid_max_max; extern int percpu_pagelist_fraction; -@@ -482,6 +485,15 @@ static struct ctl_table kern_table[] = { +@@ -489,6 +492,15 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, @@ -89,5 +89,5 @@ Signed-off-by: Serge Hallyn +int unprivileged_userns_clone; + static struct kmem_cache *user_ns_cachep __read_mostly; + static DEFINE_MUTEX(userns_state_mutex); - static bool new_idmap_permitted(const struct file *file, diff --git a/debian/patches/debian/userns-fix-abi-change-in-3.16.7-ckt4.patch b/debian/patches/debian/userns-fix-abi-change-in-3.16.7-ckt4.patch new file mode 100644 index 000000000..017392155 --- /dev/null +++ b/debian/patches/debian/userns-fix-abi-change-in-3.16.7-ckt4.patch @@ -0,0 +1,45 @@ +From: Ben Hutchings +Date: Thu, 15 Jan 2015 23:16:35 +0000 +Subject: userns: Fix ABI change in 3.16.7-ckt4 +Forwarded: not-needed + +The fix for CVE-2014-8989 added a new member to struct user_namespace. +This is always allocated, and the new member is always used, in +non-modular code. Move it to the end of the structure and hide it +from genksyms. + +Also hide the new #include in kernel/groups.c. + +--- +--- a/include/linux/user_namespace.h ++++ b/include/linux/user_namespace.h +@@ -31,13 +31,16 @@ struct user_namespace { + kuid_t owner; + kgid_t group; + unsigned int proc_inum; +- unsigned long flags; + + /* Register of per-UID persistent keyrings for this namespace */ + #ifdef CONFIG_PERSISTENT_KEYRINGS + struct key *persistent_keyring_register; + struct rw_semaphore persistent_keyring_register_sem; + #endif ++ ++#ifndef __GENKSYMS__ ++ unsigned long flags; ++#endif + }; + + extern struct user_namespace init_user_ns; +--- a/kernel/groups.c ++++ b/kernel/groups.c +@@ -6,7 +6,9 @@ + #include + #include + #include ++#ifndef __GENKSYMS__ + #include ++#endif + #include + + /* init to 2 - one for init_task, one to ensure it is never freed */ diff --git a/debian/patches/features/x86/platform-chrome-chromeos_laptop-add-support-for-acer.patch b/debian/patches/features/x86/platform-chrome-chromeos_laptop-add-support-for-acer.patch deleted file mode 100644 index 9caf443ea..000000000 --- a/debian/patches/features/x86/platform-chrome-chromeos_laptop-add-support-for-acer.patch +++ /dev/null @@ -1,124 +0,0 @@ -From: Mika Westerberg -Date: Tue, 17 Jun 2014 14:02:00 -0700 -Subject: platform/chrome: chromeos_laptop - Add support for Acer C720 -Origin: https://git.kernel.org/linus/da3b0ab75aadab63d1ffd5563100c9386e444dad - -Acer C720 has touchpad and light sensor connected to a separate I2C buses. -Since the designware I2C host controller driver has two instances on this -particular machine we need a way to match the correct instance. Add support -for this and then register both C720 touchpad and light sensor. - -This code is based on following patch from Benson Leung: - -https://patchwork.kernel.org/patch/3074411/ - -Signed-off-by: Mika Westerberg -Tested-by: Kirill A. Shutemov -Signed-off-by: Benson Leung -Reviewed-by: Mika Westerberg -Signed-off-by: Olof Johansson ---- - drivers/platform/chrome/chromeos_laptop.c | 45 ++++++++++++++++++++++++++----- - 1 file changed, 39 insertions(+), 6 deletions(-) - -diff --git a/drivers/platform/chrome/chromeos_laptop.c b/drivers/platform/chrome/chromeos_laptop.c -index 7f1a2e2..a241e5f 100644 ---- a/drivers/platform/chrome/chromeos_laptop.c -+++ b/drivers/platform/chrome/chromeos_laptop.c -@@ -45,6 +45,8 @@ static const char *i2c_adapter_names[] = { - "SMBus I801 adapter", - "i915 gmbus vga", - "i915 gmbus panel", -+ "i2c-designware-pci", -+ "i2c-designware-pci", - }; - - /* Keep this enum consistent with i2c_adapter_names */ -@@ -52,6 +54,8 @@ enum i2c_adapter_type { - I2C_ADAPTER_SMBUS = 0, - I2C_ADAPTER_VGADDC, - I2C_ADAPTER_PANEL, -+ I2C_ADAPTER_DESIGNWARE_0, -+ I2C_ADAPTER_DESIGNWARE_1, - }; - - struct i2c_peripheral { -@@ -172,29 +176,42 @@ static struct i2c_client *__add_probed_i2c_device( - return client; - } - -+struct i2c_lookup { -+ const char *name; -+ int instance; -+ int n; -+}; -+ - static int __find_i2c_adap(struct device *dev, void *data) - { -- const char *name = data; -+ struct i2c_lookup *lookup = data; - static const char *prefix = "i2c-"; - struct i2c_adapter *adapter; - if (strncmp(dev_name(dev), prefix, strlen(prefix)) != 0) - return 0; - adapter = to_i2c_adapter(dev); -- return (strncmp(adapter->name, name, strlen(name)) == 0); -+ if (strncmp(adapter->name, lookup->name, strlen(lookup->name)) == 0 && -+ lookup->n++ == lookup->instance) -+ return 1; -+ return 0; - } - - static int find_i2c_adapter_num(enum i2c_adapter_type type) - { - struct device *dev = NULL; - struct i2c_adapter *adapter; -- const char *name = i2c_adapter_names[type]; -+ struct i2c_lookup lookup; -+ -+ memset(&lookup, 0, sizeof(lookup)); -+ lookup.name = i2c_adapter_names[type]; -+ lookup.instance = (type == I2C_ADAPTER_DESIGNWARE_1) ? 1 : 0; -+ - /* find the adapter by name */ -- dev = bus_find_device(&i2c_bus_type, NULL, (void *)name, -- __find_i2c_adap); -+ dev = bus_find_device(&i2c_bus_type, NULL, &lookup, __find_i2c_adap); - if (!dev) { - /* Adapters may appear later. Deferred probing will retry */ - pr_notice("%s: i2c adapter %s not found on system.\n", __func__, -- name); -+ lookup.name); - return -ENODEV; - } - adapter = to_i2c_adapter(dev); -@@ -377,6 +394,15 @@ static struct chromeos_laptop acer_ac700 = { - }, - }; - -+static struct chromeos_laptop acer_c720 = { -+ .i2c_peripherals = { -+ /* Touchpad. */ -+ { .add = setup_cyapa_tp, I2C_ADAPTER_DESIGNWARE_0 }, -+ /* Light Sensor. */ -+ { .add = setup_isl29018_als, I2C_ADAPTER_DESIGNWARE_1 }, -+ }, -+}; -+ - static struct chromeos_laptop hp_pavilion_14_chromebook = { - .i2c_peripherals = { - /* Touchpad. */ -@@ -434,6 +460,13 @@ static struct dmi_system_id chromeos_laptop_dmi_table[] __initdata = { - _CBDD(acer_ac700), - }, - { -+ .ident = "Acer C720", -+ .matches = { -+ DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"), -+ }, -+ _CBDD(acer_c720), -+ }, -+ { - .ident = "HP Pavilion 14 Chromebook", - .matches = { - DMI_MATCH(DMI_PRODUCT_NAME, "Butterfly"), diff --git a/debian/patches/series b/debian/patches/series index 6dd2b6677..4dd02191d 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -51,17 +51,12 @@ bugfix/arm/omap-musb-choice.patch bugfix/mips/disable-advansys.patch bugfix/arm/ixp4xx_iobe.patch bugfix/m68k/ethernat-kconfig.patch -bugfix/s390/s390-3215-fix-hanging-console-issue.patch -bugfix/s390/s390-3215-fix-tty-output-containing-tabs.patch bugfix/x86/drm-i915-initialise-userptr-mmu_notifier-serial-to-1.patch bugfix/x86/drm-i915-Add-some-L3-registers-to-the-parser-whiteli.patch bugfix/parisc/parisc-reduce-sigrtmin-from-37-to-32-to-behave-like-.patch bugfix/arm64/arm64-add-missing-dts-entry-for-X-Gene-platform.patch bugfix/arm64/arm64-removed-using-of-the-mask-attribute-in-the-dts.patch bugfix/x86/acpi-video-run-_bcl-before-deciding-registering-back.patch -bugfix/x86/x86-tls-validate-tls-entries-to-protect-espfix.patch -bugfix/x86/x86-kvm-clear-paravirt_enabled-on-kvm-guests-for-esp.patch -bugfix/x86/x86_64-switch_to-load-tls-descriptors-before-switchi.patch # Arch features features/mips/MIPS-Support-hard-limit-of-cpu-count-nr_cpu_ids.patch @@ -128,7 +123,6 @@ features/arm64/drivers-net-xgene-fix-Use-separate-resources.patch features/arm64/dtb-Add-10GbE-node-to-APM-X-Gene-SoC-device-tree.patch features/arm64/dtb-Add-SGMII-based-1GbE-node-to-APM-X-Gene-SoC-devi.patch features/arm64/dtb-xgene-fix-Backward-compatibility-with-older-firm.patch -features/x86/platform-chrome-chromeos_laptop-add-support-for-acer.patch # Miscellaneous bug fixes bugfix/all/misc-bmp085-Enable-building-as-a-module.patch @@ -156,13 +150,7 @@ bugfix/all/xen-netback-Disable-NAPI-after-disabling-interrupts.patch bugfix/all/xen-netback-do-not-report-success-if-backend_create_.patch bugfix/all/netback-don-t-store-invalid-vif-pointer.patch bugfix/all/xen-netback-support-frontends-without-feature-rx-not.patch -bugfix/all/isofs-fix-infinite-looping-over-ce-entries.patch -bugfix/all/batman-adv-calculate-extra-tail-size-based-on-queued.patch -bugfix/all/keys-close-race-between-key-lookup-and-freeing.patch -bugfix/all/isofs-fix-unchecked-printing-of-er-records.patch -bugfix/all/move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch bugfix/all/aufs-move-d_rcu-from-overlapping-d_child-to-overlapping-d.patch -bugfix/all/deal-with-deadlock-in-d_walk.patch bugfix/all/net-mv643xx-disable-tso-by-default.patch # memfd_create() & kdbus backport @@ -497,3 +485,4 @@ debian/perf-fix-abi-change-in-3.16.7-ckt2.patch debian/arm-thread_info-fix-abi-change-in-3.16.7-ckt3.patch debian/pci-fix-abi-change-in-3.16.7-ckt3.patch debian/vfs-avoid-abi-change-for-dentry-union-changes.patch +debian/userns-fix-abi-change-in-3.16.7-ckt4.patch