summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Lehmer <alehmer@google.com>2017-09-28 15:28:11 -0700
committerAndrew Lehmer <alehmer@google.com>2017-09-28 15:28:25 -0700
commit0fdd4faef3aa46beb89c8a03be3ae1da42d61346 (patch)
treed44b7edd7efceeafecafca43a5c21d4c88a41896
parent8ac3b7cbf14fa5d328213b1592efce6ae16f1167 (diff)
parentf2807be44c420478c7afc7cc296217521d5e623c (diff)
downloadx86_64-android-x86_64-fugu-3.10-oreo-r2.tar.gz
Merge branch 'android-x86_64-fugu-3.10-nyc-mr1' into android-x86_64-fugu-3.10-ocandroid-8.0.0_r0.23android-x86_64-fugu-3.10-oreo-r2
November 2017.1 Bug: 65558954 Change-Id: I3ccc21349b7ac04252c274663a04317a27597cb1 Signed-off-by: Andrew Lehmer <alehmer@google.com>
-rw-r--r--drivers/input/misc/keychord.c4
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c5
-rw-r--r--drivers/video/it8566_hdmi_cec/it8566_hdmi_cec.c2
-rw-r--r--include/linux/pid.h4
-rw-r--r--include/linux/sched.h17
-rw-r--r--kernel/events/core.c61
-rw-r--r--kernel/pid.c11
-rw-r--r--net/wireless/nl80211.c4
-rw-r--r--sound/core/pcm.c2
9 files changed, 87 insertions, 23 deletions
diff --git a/drivers/input/misc/keychord.c b/drivers/input/misc/keychord.c
index a5ea27ad0e16..f580edf1c87c 100644
--- a/drivers/input/misc/keychord.c
+++ b/drivers/input/misc/keychord.c
@@ -300,8 +300,10 @@ static ssize_t keychord_write(struct file *file, const char __user *buffer,
ret = input_register_handler(&kdev->input_handler);
if (ret) {
- kfree(keychords);
+ spin_lock_irqsave(&kdev->lock, flags);
+ kfree(kdev->keychords);
kdev->keychords = 0;
+ spin_unlock_irqrestore(&kdev->lock, flags);
return ret;
}
kdev->registered = 1;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 301e572e8923..3bc0413eca5a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -4019,6 +4019,11 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
GFP_KERNEL);
} else if (ieee80211_is_action(mgmt->frame_control)) {
+ if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
+ brcmf_err("invalid action frame length\n");
+ err = -EINVAL;
+ goto exit;
+ }
af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
if (af_params == NULL) {
brcmf_err("unable to allocate frame\n");
diff --git a/drivers/video/it8566_hdmi_cec/it8566_hdmi_cec.c b/drivers/video/it8566_hdmi_cec/it8566_hdmi_cec.c
index 13fd5c79800c..245f23e7d74c 100644
--- a/drivers/video/it8566_hdmi_cec/it8566_hdmi_cec.c
+++ b/drivers/video/it8566_hdmi_cec/it8566_hdmi_cec.c
@@ -361,7 +361,7 @@ static ssize_t dbg_cec_tx_write(struct file *file,
buf[buf_size] = 0;
b = buf;
- while (sscanf(b, "%x%n", &d, &offset) == 1) {
+ while (i < sizeof(user_data) && sscanf(b, "%x%n", &d, &offset) == 1) {
b += offset;
user_data[i] = (unsigned char)d;
i++;
diff --git a/include/linux/pid.h b/include/linux/pid.h
index a089a3c447fc..ed7b1f731923 100644
--- a/include/linux/pid.h
+++ b/include/linux/pid.h
@@ -8,7 +8,9 @@ enum pid_type
PIDTYPE_PID,
PIDTYPE_PGID,
PIDTYPE_SID,
- PIDTYPE_MAX
+ PIDTYPE_MAX,
+ /* only valid to __task_pid_nr_ns() */
+ __PIDTYPE_TGID
};
/*
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 742d87c5831b..c0b447aa4401 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1517,13 +1517,6 @@ static inline pid_t task_tgid_nr(struct task_struct *tsk)
return tsk->tgid;
}
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns);
-
-static inline pid_t task_tgid_vnr(struct task_struct *tsk)
-{
- return pid_vnr(task_tgid(tsk));
-}
-
static inline pid_t task_pgrp_nr_ns(struct task_struct *tsk,
struct pid_namespace *ns)
@@ -1548,6 +1541,16 @@ static inline pid_t task_session_vnr(struct task_struct *tsk)
return __task_pid_nr_ns(tsk, PIDTYPE_SID, NULL);
}
+static inline pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
+{
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, ns);
+}
+
+static inline pid_t task_tgid_vnr(struct task_struct *tsk)
+{
+ return __task_pid_nr_ns(tsk, __PIDTYPE_TGID, NULL);
+}
+
/* obsolete, do not use */
static inline pid_t task_pgrp_nr(struct task_struct *tsk)
{
diff --git a/kernel/events/core.c b/kernel/events/core.c
index cdbf5b5e69d7..75499f5c0d15 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6709,6 +6709,37 @@ static void mutex_lock_double(struct mutex *a, struct mutex *b)
mutex_lock_nested(b, SINGLE_DEPTH_NESTING);
}
+/*
+ * Variation on perf_event_ctx_lock_nested(), except we take two context
+ * mutexes.
+ */
+static struct perf_event_context *
+__perf_event_ctx_lock_double(struct perf_event *group_leader,
+ struct perf_event_context *ctx)
+{
+ struct perf_event_context *gctx;
+
+again:
+ rcu_read_lock();
+ gctx = ACCESS_ONCE(group_leader->ctx);
+ if (!atomic_inc_not_zero(&gctx->refcount)) {
+ rcu_read_unlock();
+ goto again;
+ }
+ rcu_read_unlock();
+
+ mutex_lock_double(&gctx->mutex, &ctx->mutex);
+
+ if (group_leader->ctx != gctx) {
+ mutex_unlock(&ctx->mutex);
+ mutex_unlock(&gctx->mutex);
+ put_ctx(gctx);
+ goto again;
+ }
+
+ return gctx;
+}
+
/**
* sys_perf_event_open - open a performance event, associate it to a task/cpu
*
@@ -6920,14 +6951,31 @@ SYSCALL_DEFINE5(perf_event_open,
}
if (move_group) {
- gctx = group_leader->ctx;
+ gctx = __perf_event_ctx_lock_double(group_leader, ctx);
+
+ /*
+ * Check if we raced against another sys_perf_event_open() call
+ * moving the software group underneath us.
+ */
+ if (!(group_leader->group_flags & PERF_GROUP_SOFTWARE)) {
+ /*
+ * If someone moved the group out from under us, check
+ * if this new event wound up on the same ctx, if so
+ * its the regular !move_group case, otherwise fail.
+ */
+ if (gctx != ctx) {
+ err = -EINVAL;
+ goto err_locked;
+ } else {
+ perf_event_ctx_unlock(group_leader, gctx);
+ move_group = 0;
+ }
+ }
/*
* See perf_event_ctx_lock() for comments on the details
* of swizzling perf_event::ctx.
*/
- mutex_lock_double(&gctx->mutex, &ctx->mutex);
-
perf_remove_from_context(group_leader);
/*
@@ -6969,7 +7017,7 @@ SYSCALL_DEFINE5(perf_event_open,
perf_unpin_context(ctx);
if (move_group) {
- mutex_unlock(&gctx->mutex);
+ perf_event_ctx_unlock(group_leader, gctx);
put_ctx(gctx);
}
mutex_unlock(&ctx->mutex);
@@ -7000,6 +7048,11 @@ SYSCALL_DEFINE5(perf_event_open,
fd_install(event_fd, event_file);
return event_fd;
+err_locked:
+ if (move_group)
+ perf_event_ctx_unlock(group_leader, gctx);
+ mutex_unlock(&ctx->mutex);
+ fput(event_file);
err_context:
perf_unpin_context(ctx);
put_ctx(ctx);
diff --git a/kernel/pid.c b/kernel/pid.c
index 0eb6d8e8b1da..1d6400df0c4c 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -519,8 +519,11 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
if (!ns)
ns = task_active_pid_ns(current);
if (likely(pid_alive(task))) {
- if (type != PIDTYPE_PID)
+ if (type != PIDTYPE_PID) {
+ if (type == __PIDTYPE_TGID)
+ type = PIDTYPE_PID;
task = task->group_leader;
+ }
nr = pid_nr_ns(task->pids[type].pid, ns);
}
rcu_read_unlock();
@@ -529,12 +532,6 @@ pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type,
}
EXPORT_SYMBOL(__task_pid_nr_ns);
-pid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns)
-{
- return pid_nr_ns(task_tgid(tsk), ns);
-}
-EXPORT_SYMBOL(task_tgid_nr_ns);
-
struct pid_namespace *task_active_pid_ns(struct task_struct *tsk)
{
return ns_of_pid(task_pid(tsk));
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5cefcc8aa8d6..5ce738bf74f8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -310,8 +310,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
[NL80211_ATTR_PID] = { .type = NLA_U32 },
[NL80211_ATTR_4ADDR] = { .type = NLA_U8 },
- [NL80211_ATTR_PMKID] = { .type = NLA_BINARY,
- .len = WLAN_PMKID_LEN },
+ [NL80211_ATTR_PMKID] = { .len = WLAN_PMKID_LEN },
[NL80211_ATTR_DURATION] = { .type = NLA_U32 },
[NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
[NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
@@ -366,6 +365,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 },
[NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 },
[NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 },
+ [NL80211_ATTR_LOCAL_MESH_POWER_MODE] = {. type = NLA_U32 },
[NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 },
[NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED },
[NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 },
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index e1e9e0c999fe..5e95bc66f817 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -150,7 +150,9 @@ static int snd_pcm_control_ioctl(struct snd_card *card,
err = -ENXIO;
goto _error;
}
+ mutex_lock(&pcm->open_mutex);
err = snd_pcm_info_user(substream, info);
+ mutex_unlock(&pcm->open_mutex);
_error:
mutex_unlock(&register_mutex);
return err;