Linux 3.16.67

From: Ben Hutchings
Date: Sun May 12 2019 - 08:30:54 EST


I'm announcing the release of the 3.16.67 kernel.

All users of the 3.16 kernel series should upgrade.

The updated 3.16.y git tree can be found at:
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git linux-3.16.y
and can be browsed at the normal kernel.org git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git

The diff from 3.16.66 is attached to this message.

Ben.

------------

Makefile | 2 +-
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, 48 insertions(+), 28 deletions(-)

Amit Klein (1):
inet: update the IP ID generation algorithm to higher standards.

Arend Van Spriel (1):
brcmfmac: add length checks in scheduled scan result handler

Ben Hutchings (4):
Revert "brcmfmac: assure SSID length from firmware is limited"
vxlan: Fix big-endian declaration of VNI
timer/debug: Change /proc/timer_stats from 0644 to 0600
Linux 3.16.67

David Herrmann (1):
fork: record start_time late

Eric Dumazet (1):
ipv4: fix a race in update_or_create_fnhe()

Joerg Roedel (1):
KVM: VMX: Fix x2apic check in vmx_msr_bitmap_mode()

Matteo Croce (1):
percpu: stop printing kernel addresses

Nick Krause (1):
spi: omap-100k: Remove unused definitions

diff --git a/Makefile b/Makefile
index 7387b85870f2..33a54d0451a3 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
VERSION = 3
PATCHLEVEL = 16
-SUBLEVEL = 66
+SUBLEVEL = 67
EXTRAVERSION =
NAME = Museum of Fishiegoodies

diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index bc3dc38fa486..bd6b883f3075 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -4224,7 +4224,9 @@ static u8 vmx_msr_bitmap_mode(struct kvm_vcpu *vcpu)
{
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;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 31abf2e7b199..d7e4f83f8bf3 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -706,7 +706,7 @@ static struct vxlan_fdb *vxlan_fdb_alloc(struct vxlan_dev *vxlan,
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;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index e6e2c5afec06..1a0a62219eed 100644
--- 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 brcmf_if *ifp,
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 brcmf_if *ifp,
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 brcmf_if *ifp,
}

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,10 +3086,10 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
goto out_err;
}

- 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;
+ brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
+ netinfo->SSID, netinfo->channel);
memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
ssid[i].ssid_len = netinfo->SSID_len;
request->n_ssids++;
diff --git a/drivers/spi/spi-omap-100k.c b/drivers/spi/spi-omap-100k.c
index e7ffcded4e14..75a5b1913807 100644
--- 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.
*/
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 68d6df7bc85a..928bf612f6ff 100644
--- 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;
};

/*
diff --git a/kernel/fork.c b/kernel/fork.c
index 27f6a67f692e..7dc86b50f925 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1265,9 +1265,6 @@ static struct task_struct *copy_process(unsigned long clone_flags,

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)
@@ -1422,6 +1419,18 @@ static struct task_struct *copy_process(unsigned long clone_flags,
INIT_LIST_HEAD(&p->thread_group);
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!
diff --git a/kernel/time/timer_stats.c b/kernel/time/timer_stats.c
index 1fb08f21302e..0334899f1d3e 100644
--- a/kernel/time/timer_stats.c
+++ b/kernel/time/timer_stats.c
@@ -417,7 +417,7 @@ static int __init init_tstats_procfs(void)
{
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;
diff --git a/mm/percpu.c b/mm/percpu.c
index 2ddf9a990dbd..7fae38984a21 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1716,8 +1716,8 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
#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 reserved_size,
}

/* 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);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 6f44569623ae..83656bdb00e2 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -157,9 +157,12 @@ static void rt_fibinfo_free(struct rtable __rcu **rtp)

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_head *head)
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);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 4f7c378c841d..e0d59ff394b2 100644
--- 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);
@@ -633,12 +635,12 @@ static void update_or_create_fnhe(struct fib_nh *nh, __be32 daddr, __be32 gw,

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;
@@ -1291,7 +1293,7 @@ static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)

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;

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index e59b30054b0f..bb98cde51476 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -541,12 +541,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
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);

Attachment: signature.asc
Description: PGP signature