]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - pending-4.14/alsa-seq-fix-race-of-get-subscription-call-vs-port-d.patch
move existing queues out of the way for the moment...
[thirdparty/kernel/stable-queue.git] / pending-4.14 / alsa-seq-fix-race-of-get-subscription-call-vs-port-d.patch
CommitLineData
1cd4ef76
SL
1From 97f213d5b8850731c3bb1cd42c27a229748c8057 Mon Sep 17 00:00:00 2001
2From: Takashi Iwai <tiwai@suse.de>
3Date: Tue, 9 Apr 2019 18:04:17 +0200
4Subject: ALSA: seq: Fix race of get-subscription call vs port-delete ioctls
5
6[ Upstream commit 2eabc5ec8ab4d4748a82050dfcb994119b983750 ]
7
8The snd_seq_ioctl_get_subscription() retrieves the port subscriber
9information as a pointer, while the object isn't protected, hence it
10may be deleted before the actual reference. This race was spotted by
11syzkaller and may lead to a UAF.
12
13The fix is simply copying the data in the lookup function that
14performs in the rwsem to protect against the deletion.
15
16Reported-by: syzbot+9437020c82413d00222d@syzkaller.appspotmail.com
17Signed-off-by: Takashi Iwai <tiwai@suse.de>
18Signed-off-by: Sasha Levin <sashal@kernel.org>
19---
20 sound/core/seq/seq_clientmgr.c | 10 ++--------
21 sound/core/seq/seq_ports.c | 13 ++++++++-----
22 sound/core/seq/seq_ports.h | 5 +++--
23 3 files changed, 13 insertions(+), 15 deletions(-)
24
25diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
26index 692631bd4a35..068880ac47b5 100644
27--- a/sound/core/seq/seq_clientmgr.c
28+++ b/sound/core/seq/seq_clientmgr.c
29@@ -1904,20 +1904,14 @@ static int snd_seq_ioctl_get_subscription(struct snd_seq_client *client,
30 int result;
31 struct snd_seq_client *sender = NULL;
32 struct snd_seq_client_port *sport = NULL;
33- struct snd_seq_subscribers *p;
34
35 result = -EINVAL;
36 if ((sender = snd_seq_client_use_ptr(subs->sender.client)) == NULL)
37 goto __end;
38 if ((sport = snd_seq_port_use_ptr(sender, subs->sender.port)) == NULL)
39 goto __end;
40- p = snd_seq_port_get_subscription(&sport->c_src, &subs->dest);
41- if (p) {
42- result = 0;
43- *subs = p->info;
44- } else
45- result = -ENOENT;
46-
47+ result = snd_seq_port_get_subscription(&sport->c_src, &subs->dest,
48+ subs);
49 __end:
50 if (sport)
51 snd_seq_port_unlock(sport);
52diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
53index d3fc73ac230b..c8fa4336bccd 100644
54--- a/sound/core/seq/seq_ports.c
55+++ b/sound/core/seq/seq_ports.c
56@@ -635,20 +635,23 @@ int snd_seq_port_disconnect(struct snd_seq_client *connector,
57
58
59 /* get matched subscriber */
60-struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
61- struct snd_seq_addr *dest_addr)
62+int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
63+ struct snd_seq_addr *dest_addr,
64+ struct snd_seq_port_subscribe *subs)
65 {
66- struct snd_seq_subscribers *s, *found = NULL;
67+ struct snd_seq_subscribers *s;
68+ int err = -ENOENT;
69
70 down_read(&src_grp->list_mutex);
71 list_for_each_entry(s, &src_grp->list_head, src_list) {
72 if (addr_match(dest_addr, &s->info.dest)) {
73- found = s;
74+ *subs = s->info;
75+ err = 0;
76 break;
77 }
78 }
79 up_read(&src_grp->list_mutex);
80- return found;
81+ return err;
82 }
83
84 /*
85diff --git a/sound/core/seq/seq_ports.h b/sound/core/seq/seq_ports.h
86index 26bd71f36c41..06003b36652e 100644
87--- a/sound/core/seq/seq_ports.h
88+++ b/sound/core/seq/seq_ports.h
89@@ -135,7 +135,8 @@ int snd_seq_port_subscribe(struct snd_seq_client_port *port,
90 struct snd_seq_port_subscribe *info);
91
92 /* get matched subscriber */
93-struct snd_seq_subscribers *snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
94- struct snd_seq_addr *dest_addr);
95+int snd_seq_port_get_subscription(struct snd_seq_port_subs_info *src_grp,
96+ struct snd_seq_addr *dest_addr,
97+ struct snd_seq_port_subscribe *subs);
98
99 #endif
100--
1012.20.1
102