This is the start of the stable review cycle for the 3.16.67 release. There are 10 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Sat May 11 14:08:16 UTC 2019. Anything received after that time might be too late.
All the patches have also been committed to the linux-3.16.y-rc branch of https://git.kernel.org/pub/scm/linux/kernel/git/bwh/linux-stable-rc.git . A shortlog and diffstat can be found below.
Ben.
-------------
Amit Klein (1): inet: update the IP ID generation algorithm to higher standards. [355b98553789b646ed97ad801a619ff898471b92]
Arend Van Spriel (1): brcmfmac: add length checks in scheduled scan result handler [4835f37e3bafc138f8bfa3cbed2920dd56fed283]
Ben Hutchings (3): Revert "brcmfmac: assure SSID length from firmware is limited" [not upstream; reverts incorrect backport] timer/debug: Change /proc/timer_stats from 0644 to 0600 [not upstream; code was removed upstream] vxlan: Fix big-endian declaration of VNI [54bfd872bf16d40b61bd0cd9b769b2fef67dd272]
David Herrmann (1): fork: record start_time late [7b55851367136b1efd84d98fea81ba57a98304cf]
Eric Dumazet (1): ipv4: fix a race in update_or_create_fnhe() [caa415270c732505240bb60171c44a7838c555e8]
Joerg Roedel (1): KVM: VMX: Fix x2apic check in vmx_msr_bitmap_mode() [not upstream; fixes incorrect backport]
Matteo Croce (1): percpu: stop printing kernel addresses [00206a69ee32f03e6f40837684dcbe475ea02266]
Nick Krause (1): spi: omap-100k: Remove unused definitions [9f5b8b4f56dd194fd33021810636879036d2acdd]
Makefile | 4 ++-- arch/x86/kvm/vmx.c | 4 +++- drivers/net/vxlan.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 16 +++++++++++----- drivers/spi/spi-omap-100k.c | 4 ---- include/net/ip_fib.h | 2 +- kernel/fork.c | 15 ++++++++++++--- kernel/time/timer_stats.c | 2 +- mm/percpu.c | 8 ++++---- net/ipv4/fib_semantics.c | 8 +++++--- net/ipv4/route.c | 10 ++++++---- net/ipv6/ip6_output.c | 3 +++ 12 files changed, 49 insertions(+), 29 deletions(-)
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings ben@decadent.org.uk
The timer_stats facility should filter and translate PIDs if opened from a non-initial PID namespace, to avoid leaking information about the wider system. It should also not show kernel virtual addresses. Unfortunately it has now been removed upstream (as redundant) instead of being fixed.
For stable, fix the leak by restricting access to root only. A similar change was already made for the /proc/timer_list file.
Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/kernel/time/timer_stats.c +++ b/kernel/time/timer_stats.c @@ -417,7 +417,7 @@ static int __init init_tstats_procfs(voi { struct proc_dir_entry *pe;
- pe = proc_create("timer_stats", 0644, NULL, &tstats_fops); + pe = proc_create("timer_stats", 0600, NULL, &tstats_fops); if (!pe) return -ENOMEM; return 0;
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings ben@decadent.org.uk
In this version of the driver, VNIs are consistently kept in host order. However vxlan_fdb_create() erroneously declares its vni parameter as __be32, which sparse warns about. Change it to __u32.
This was resolved upstream by commit 54bfd872bf16 "vxlan: keep flags and vni in network byte order".
Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -706,7 +706,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc static int vxlan_fdb_create(struct vxlan_dev *vxlan, const u8 *mac, union vxlan_addr *ip, __u16 state, __be16 port, - __be32 vni, __u32 ifindex, __u8 ndm_flags, + __u32 vni, __u32 ifindex, __u8 ndm_flags, struct vxlan_fdb **fdb) { struct vxlan_rdst *rd = NULL;
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: David Herrmann dh.herrmann@gmail.com
commit 7b55851367136b1efd84d98fea81ba57a98304cf upstream.
This changes the fork(2) syscall to record the process start_time after initializing the basic task structure but still before making the new process visible to user-space.
Technically, we could record the start_time anytime during fork(2). But this might lead to scenarios where a start_time is recorded long before a process becomes visible to user-space. For instance, with userfaultfd(2) and TLS, user-space can delay the execution of fork(2) for an indefinite amount of time (and will, if this causes network access, or similar).
By recording the start_time late, it much closer reflects the point in time where the process becomes live and can be observed by other processes.
Lastly, this makes it much harder for user-space to predict and control the start_time they get assigned. Previously, user-space could fork a process and stall it in copy_thread_tls() before its pid is allocated, but after its start_time is recorded. This can be misused to later-on cycle through PIDs and resume the stalled fork(2) yielding a process that has the same pid and start_time as a process that existed before. This can be used to circumvent security systems that identify processes by their pid+start_time combination.
Even though user-space was always aware that start_time recording is flaky (but several projects are known to still rely on start_time-based identification), changing the start_time to be recorded late will help mitigate existing attacks and make it much harder for user-space to control the start_time a process gets assigned.
Reported-by: Jann Horn jannh@google.com Signed-off-by: Tom Gundersen teg@jklm.no Signed-off-by: David Herrmann dh.herrmann@gmail.com Signed-off-by: Linus Torvalds torvalds@linux-foundation.org [bwh: Backported to 3.16: start_time initialisation code is different] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- kernel/fork.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/kernel/fork.c +++ b/kernel/fork.c @@ -1265,9 +1265,6 @@ static struct task_struct *copy_process(
posix_cpu_timers_init(p);
- do_posix_clock_monotonic_gettime(&p->start_time); - p->real_start_time = p->start_time; - monotonic_to_bootbased(&p->real_start_time); p->io_context = NULL; p->audit_context = NULL; if (clone_flags & CLONE_THREAD) @@ -1423,6 +1420,18 @@ static struct task_struct *copy_process( p->task_works = NULL;
/* + * From this point on we must avoid any synchronous user-space + * communication until we take the tasklist-lock. In particular, we do + * not want user-space to be able to predict the process start-time by + * stalling fork(2) after we recorded the start_time but before it is + * visible to the system. + */ + + do_posix_clock_monotonic_gettime(&p->start_time); + p->real_start_time = p->start_time; + monotonic_to_bootbased(&p->real_start_time); + + /* * Make it visible to the rest of the system, but dont wake it up yet. * Need tasklist lock for parent etc handling! */
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings ben@decadent.org.uk
This reverts commit 9657f3abd17772d3290a3545dfb4811d945e84e1, which was similar to commit 1b5e2423164b3670e8bc9174e4762d297990deff upstream. The function fixed upstream doesn't exist in 3.16 and the similar bug that does exist here needs a different fix.
Signed-off-by: Ben Hutchings ben@decadent.org.uk --- --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3082,8 +3082,6 @@ brcmf_notify_sched_scan_results(struct b
brcmf_dbg(SCAN, "SSID:%s Channel:%d\n", netinfo->SSID, netinfo->channel); - if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN) - netinfo->SSID_len = IEEE80211_MAX_SSID_LEN; memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len); ssid[i].ssid_len = netinfo->SSID_len; request->n_ssids++;
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arend Van Spriel arend.vanspriel@broadcom.com
commit 4835f37e3bafc138f8bfa3cbed2920dd56fed283 upstream.
Assure the event data buffer is long enough to hold the array of netinfo items and that SSID length does not exceed the maximum of 32 characters as per 802.11 spec.
Reviewed-by: Hante Meuleman hante.meuleman@broadcom.com Reviewed-by: Pieter-Paul Giesberts pieter-paul.giesberts@broadcom.com Reviewed-by: Franky Lin franky.lin@broadcom.com Signed-off-by: Arend van Spriel arend.vanspriel@broadcom.com Signed-off-by: Kalle Valo kvalo@codeaurora.org [bwh: Backported to 3.16: - Move the assignment to "data" along with the assignment to "netinfo_start" that depends on it - Adjust filename, context, indentation] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -3033,6 +3033,7 @@ brcmf_notify_sched_scan_results(struct b struct brcmf_pno_scanresults_le *pfn_result; u32 result_count; u32 status; + u32 datalen;
brcmf_dbg(SCAN, "Enter\n");
@@ -3059,6 +3060,14 @@ brcmf_notify_sched_scan_results(struct b if (result_count > 0) { int i;
+ data += sizeof(struct brcmf_pno_scanresults_le); + netinfo_start = (struct brcmf_pno_net_info_le *)data; + datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result); + if (datalen < result_count * sizeof(*netinfo)) { + brcmf_err("insufficient event data\n"); + goto out_err; + } + request = kzalloc(sizeof(*request), GFP_KERNEL); ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL); channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL); @@ -3068,9 +3077,6 @@ brcmf_notify_sched_scan_results(struct b }
request->wiphy = wiphy; - data += sizeof(struct brcmf_pno_scanresults_le); - netinfo_start = (struct brcmf_pno_net_info_le *)data; - for (i = 0; i < result_count; i++) { netinfo = &netinfo_start[i]; if (!netinfo) { @@ -3080,6 +3086,8 @@ brcmf_notify_sched_scan_results(struct b goto out_err; }
+ if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN) + netinfo->SSID_len = IEEE80211_MAX_SSID_LEN; brcmf_dbg(SCAN, "SSID:%s Channel:%d\n", netinfo->SSID, netinfo->channel); memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nick Krause xerofoiffy@gmail.com
commit 9f5b8b4f56dd194fd33021810636879036d2acdd upstream.
Remove unused definition which cause the following warnings
drivers/spi/spi-omap-100k.c:73:0: warning: "WRITE" redefined [enabled by default] include/linux/fs.h:193:0: note: this is the location of the previous definition drivers/spi/spi-omap-100k.c:74:0: warning: "READ" redefined [enabled by default] include/linux/fs.h:192:0: note: this is the location of the previous definition
Signed-off-by: Nick Krause xerofoiffy@gmail.com Acked-by: Geert Uytterhoeven geert@linux-m68k.org Signed-off-by: Mark Brown broonie@linaro.org Signed-off-by: Ben Hutchings ben@decadent.org.uk --- drivers/spi/spi-omap-100k.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/spi/spi-omap-100k.c +++ b/drivers/spi/spi-omap-100k.c @@ -70,10 +70,6 @@ #define SPI_STATUS_WE (1UL << 1) #define SPI_STATUS_RD (1UL << 0)
-#define WRITE 0 -#define READ 1 - - /* use PIO for small transfers, avoiding DMA setup/teardown overhead and * cache operations; better heuristics consider wordsize and bitrate. */
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
commit caa415270c732505240bb60171c44a7838c555e8 upstream.
nh_exceptions is effectively used under rcu, but lacks proper barriers. Between kzalloc() and setting of nh->nh_exceptions(), we need a proper memory barrier.
Signed-off-by: Eric Dumazet edumazet@google.com Fixes: 4895c771c7f00 ("ipv4: Add FIB nexthop exceptions.") Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Ben Hutchings ben@decadent.org.uk --- include/net/ip_fib.h | 2 +- net/ipv4/fib_semantics.c | 8 +++++--- net/ipv4/route.c | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-)
--- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -89,7 +89,7 @@ struct fib_nh { int nh_saddr_genid; struct rtable __rcu * __percpu *nh_pcpu_rth_output; struct rtable __rcu *nh_rth_input; - struct fnhe_hash_bucket *nh_exceptions; + struct fnhe_hash_bucket __rcu *nh_exceptions; };
/* --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c @@ -157,9 +157,12 @@ static void rt_fibinfo_free(struct rtabl
static void free_nh_exceptions(struct fib_nh *nh) { - struct fnhe_hash_bucket *hash = nh->nh_exceptions; + struct fnhe_hash_bucket *hash; int i;
+ hash = rcu_dereference_protected(nh->nh_exceptions, 1); + if (!hash) + return; for (i = 0; i < FNHE_HASH_SIZE; i++) { struct fib_nh_exception *fnhe;
@@ -206,8 +209,7 @@ static void free_fib_info_rcu(struct rcu change_nexthops(fi) { if (nexthop_nh->nh_dev) dev_put(nexthop_nh->nh_dev); - if (nexthop_nh->nh_exceptions) - free_nh_exceptions(nexthop_nh); + free_nh_exceptions(nexthop_nh); rt_fibinfo_free_cpus(nexthop_nh->nh_pcpu_rth_output); rt_fibinfo_free(&nexthop_nh->nh_rth_input); } endfor_nexthops(fi); --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -635,12 +635,12 @@ static void update_or_create_fnhe(struct
spin_lock_bh(&fnhe_lock);
- hash = nh->nh_exceptions; + hash = rcu_dereference(nh->nh_exceptions); if (!hash) { hash = kzalloc(FNHE_HASH_SIZE * sizeof(*hash), GFP_ATOMIC); if (!hash) goto out_unlock; - nh->nh_exceptions = hash; + rcu_assign_pointer(nh->nh_exceptions, hash); }
hash += hval; @@ -1293,7 +1293,7 @@ static void ip_del_fnhe(struct fib_nh *n
static struct fib_nh_exception *find_exception(struct fib_nh *nh, __be32 daddr) { - struct fnhe_hash_bucket *hash = nh->nh_exceptions; + struct fnhe_hash_bucket *hash = rcu_dereference(nh->nh_exceptions); struct fib_nh_exception *fnhe; u32 hval;
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Matteo Croce mcroce@redhat.com
commit 00206a69ee32f03e6f40837684dcbe475ea02266 upstream.
Since commit ad67b74d2469d9b8 ("printk: hash addresses printed with %p"), at boot "____ptrval____" is printed instead of actual addresses:
percpu: Embedded 38 pages/cpu @(____ptrval____) s124376 r0 d31272 u524288
Instead of changing the print to "%px", and leaking kernel addresses, just remove the print completely, cfr. e.g. commit 071929dbdd865f77 ("arm64: Stop printing the virtual memory layout").
Signed-off-by: Matteo Croce mcroce@redhat.com Signed-off-by: Dennis Zhou dennis@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org [bwh: Backported to 3.16: adjust context] Signed-off-by: Ben Hutchings ben@decadent.org.uk --- mm/percpu.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/mm/percpu.c +++ b/mm/percpu.c @@ -1716,8 +1716,8 @@ int __init pcpu_embed_first_chunk(size_t #endif }
- pr_info("PERCPU: Embedded %zu pages/cpu @%p s%zu r%zu d%zu u%zu\n", - PFN_DOWN(size_sum), base, ai->static_size, ai->reserved_size, + pr_info("PERCPU: Embedded %zu pages/cpu s%zu r%zu d%zu u%zu\n", + PFN_DOWN(size_sum), ai->static_size, ai->reserved_size, ai->dyn_size, ai->unit_size);
rc = pcpu_setup_first_chunk(ai, base); @@ -1830,8 +1830,8 @@ int __init pcpu_page_first_chunk(size_t }
/* we're ready, commit */ - pr_info("PERCPU: %d %s pages/cpu @%p s%zu r%zu d%zu\n", - unit_pages, psize_str, vm.addr, ai->static_size, + pr_info("PERCPU: %d %s pages/cpu s%zu r%zu d%zu\n", + unit_pages, psize_str, ai->static_size, ai->reserved_size, ai->dyn_size);
rc = pcpu_setup_first_chunk(ai, vm.addr);
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Joerg Roedel jroedel@suse.de
The stable backport of upstream commit
904e14fb7cb96 KVM: VMX: make MSR bitmaps per-VCPU
has a bug in vmx_msr_bitmap_mode(). It enables the x2apic MSR-bitmap when the kernel emulates x2apic for the guest in software. The upstream version of the commit checkes whether the hardware has virtualization enabled for x2apic emulation.
Since KVM emulates x2apic for guests even when the host does not support x2apic in hardware, this causes the intercept of at least the X2APIC_TASKPRI MSR to be disabled on machines not supporting that MSR. The result is undefined behavior, on some machines (Intel Westmere based) it causes a crash of the guest kernel when it tries to access that MSR.
Change the check in vmx_msr_bitmap_mode() to match the upstream code. This fixes the guest crashes observed with stable kernels starting with v4.4.168 through v4.4.175.
Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Ben Hutchings ben@decadent.org.uk --- arch/x86/kvm/vmx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c @@ -4224,7 +4224,9 @@ static u8 vmx_msr_bitmap_mode(struct kvm { u8 mode = 0;
- if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { + if (cpu_has_secondary_exec_ctrls() && + (vmcs_read32(SECONDARY_VM_EXEC_CONTROL) & + SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE)) { mode |= MSR_BITMAP_MODE_X2APIC; if (enable_apicv) mode |= MSR_BITMAP_MODE_X2APIC_APICV;
3.16.67-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Amit Klein aksecurity@gmail.com
Commit 355b98553789 ("netns: provide pure entropy for net_hash_mix()") makes net_hash_mix() return a true 32 bits of entropy. When used in the IP ID generation algorithm, this has the effect of extending the IP ID generation key from 32 bits to 64 bits.
However, net_hash_mix() is only used for IP ID generation starting with kernel version 4.1. Therefore, earlier kernels remain with 32-bit key no matter what the net_hash_mix() return value is.
This change addresses the issue by explicitly extending the key to 64 bits for kernels older than 4.1.
Signed-off-by: Amit Klein aksecurity@gmail.com Signed-off-by: Ben Hutchings ben@decadent.org.uk --- net/ipv4/route.c | 4 +++- net/ipv6/ip6_output.c | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-)
--- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -487,13 +487,15 @@ EXPORT_SYMBOL(ip_idents_reserve); void __ip_select_ident(struct iphdr *iph, int segs) { static u32 ip_idents_hashrnd __read_mostly; + static u32 ip_idents_hashrnd_extra __read_mostly; u32 hash, id;
net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); + net_get_random_once(&ip_idents_hashrnd_extra, sizeof(ip_idents_hashrnd_extra));
hash = jhash_3words((__force u32)iph->daddr, (__force u32)iph->saddr, - iph->protocol, + iph->protocol ^ ip_idents_hashrnd_extra, ip_idents_hashrnd); id = ip_idents_reserve(hash, segs); iph->id = htons(id); --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -541,12 +541,15 @@ static void ip6_copy_metadata(struct sk_ static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) { static u32 ip6_idents_hashrnd __read_mostly; + static u32 ip6_idents_hashrnd_extra __read_mostly; u32 hash, id;
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); + net_get_random_once(&ip6_idents_hashrnd_extra, sizeof(ip6_idents_hashrnd_extra));
hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash); + hash = jhash_1word(hash, ip6_idents_hashrnd_extra);
id = ip_idents_reserve(hash, 1); fhdr->identification = htonl(id);
linux-stable-mirror@lists.linaro.org