Merge branch 'android-x86_64-fugu-3.10-security-next' into android-x86_64-fugu-3.10
Security February 2017.1
diff --git a/drivers/net/wireless/bcmdhd/dhd_pno.c b/drivers/net/wireless/bcmdhd/dhd_pno.c
index 3e3e3a5..5e75c10 100644
--- a/drivers/net/wireless/bcmdhd/dhd_pno.c
+++ b/drivers/net/wireless/bcmdhd/dhd_pno.c
@@ -2844,9 +2844,10 @@
list_del(&pscan_results->list);
MFREE(dhd->osh, pscan_results, SCAN_RESULTS_SIZE);
_params->params_batch.get_batch.top_node_cnt--;
+ } else {
+ /* increase total scan count using current scan count */
+ _params->params_batch.get_batch.tot_scan_cnt += pscan_results->cnt_header;
}
- /* increase total scan count using current scan count */
- _params->params_batch.get_batch.tot_scan_cnt += pscan_results->cnt_header;
if (buf && bufsize) {
/* This is a first try to get batching results */
diff --git a/fs/aio.c b/fs/aio.c
index 109e896..6437935 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -35,6 +35,7 @@
#include <linux/eventfd.h>
#include <linux/blkdev.h>
#include <linux/compat.h>
+#include <linux/personality.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
@@ -153,6 +154,9 @@
unsigned long size, populate;
int nr_pages;
+ if (current->personality & READ_IMPLIES_EXEC)
+ return -EPERM;
+
/* Compensate for the ring buffer's head/tail overlap entry */
nr_events += 2; /* 1 is required, 2 for good luck */
diff --git a/fs/proc/array.c b/fs/proc/array.c
index cbd0f1b..05dff1c 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -168,16 +168,16 @@
int g;
struct fdtable *fdt = NULL;
const struct cred *cred;
- pid_t ppid, tpid;
+ pid_t ppid = 0, tpid = 0;
+ struct task_struct *leader = NULL;
rcu_read_lock();
- ppid = pid_alive(p) ?
- task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
- tpid = 0;
if (pid_alive(p)) {
struct task_struct *tracer = ptrace_parent(p);
if (tracer)
tpid = task_pid_nr_ns(tracer, ns);
+ ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
+ leader = p->group_leader;
}
cred = get_task_cred(p);
seq_printf(m,
@@ -189,7 +189,7 @@
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
- task_tgid_nr_ns(p, ns),
+ leader ? task_pid_nr_ns(leader, ns) : 0,
pid_nr_ns(pid, ns),
ppid, tpid,
from_kuid_munged(user_ns, cred->uid),
diff --git a/net/ipv4/datagram.c b/net/ipv4/datagram.c
index b28e863..093b571 100644
--- a/net/ipv4/datagram.c
+++ b/net/ipv4/datagram.c
@@ -86,18 +86,26 @@
}
EXPORT_SYMBOL(ip4_datagram_connect);
+/* Because UDP xmit path can manipulate sk_dst_cache without holding
+ * socket lock, we need to use sk_dst_set() here,
+ * even if we own the socket lock.
+ */
void ip4_datagram_release_cb(struct sock *sk)
{
const struct inet_sock *inet = inet_sk(sk);
const struct ip_options_rcu *inet_opt;
__be32 daddr = inet->inet_daddr;
+ struct dst_entry *dst;
struct flowi4 fl4;
struct rtable *rt;
- if (! __sk_dst_get(sk) || __sk_dst_check(sk, 0))
- return;
-
rcu_read_lock();
+
+ dst = __sk_dst_get(sk);
+ if (!dst || !dst->obsolete || dst->ops->check(dst, 0)) {
+ rcu_read_unlock();
+ return;
+ }
inet_opt = rcu_dereference(inet->inet_opt);
if (inet_opt && inet_opt->opt.srr)
daddr = inet_opt->opt.faddr;
@@ -105,8 +113,10 @@
inet->inet_saddr, inet->inet_dport,
inet->inet_sport, sk->sk_protocol,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if);
- if (!IS_ERR(rt))
- __sk_dst_set(sk, &rt->dst);
+
+ dst = !IS_ERR(rt) ? &rt->dst : NULL;
+ sk_dst_set(sk, dst);
+
rcu_read_unlock();
}
EXPORT_SYMBOL_GPL(ip4_datagram_release_cb);