Skip to content

Commit 599160c

Browse files
mdouchametan-ucw
authored andcommitted
Add write()/ioctl() race variant to snd_seq01
CVE 2018-7566 has two different reproducers, this is the other one for the sake of completeness. Also fix licence, it should have been GPL-2.0-or-later from the beginning. Signed-off-by: Martin Doucha <[email protected]> Reviewed-by: Cyril Hrubis <[email protected]>
1 parent c3ec21f commit 599160c

File tree

1 file changed

+43
-17
lines changed

1 file changed

+43
-17
lines changed

testcases/kernel/sound/snd_seq01.c

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// SPDX-License-Identifier: GPL-2.0
1+
// SPDX-License-Identifier: GPL-2.0-or-later
22
/*
33
* Copyright (C) 2018 SUSE LLC <[email protected]>
44
* Copyright (C) 2020 SUSE LLC <[email protected]>
@@ -26,8 +26,40 @@
2626

2727
static int fd = -1;
2828
static int client_id;
29+
static struct snd_seq_remove_events rminfo = {
30+
.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT
31+
};
32+
static struct snd_seq_event ssev = {
33+
.flags = SNDRV_SEQ_TIME_STAMP_TICK | SNDRV_SEQ_TIME_MODE_REL,
34+
.queue = 0,
35+
.type = SNDRV_SEQ_EVENT_USR0,
36+
.time = { .tick = 10 }
37+
};
38+
2939
static struct tst_fzsync_pair fzsync_pair;
3040

41+
static void reinit_pool(int pool_size)
42+
{
43+
struct snd_seq_client_pool pconf = {
44+
.output_pool = pool_size,
45+
.client = client_id
46+
};
47+
48+
ioctl(fd, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pconf);
49+
}
50+
51+
static void race_ioctl(void)
52+
{
53+
reinit_pool(512);
54+
}
55+
56+
static void race_write(void)
57+
{
58+
TEST(write(fd, &ssev, sizeof(ssev)));
59+
}
60+
61+
void (*testfunc_list[])(void) = {race_ioctl, race_write};
62+
3163
static void setup(void)
3264
{
3365
struct snd_seq_queue_info qconf = { .queue = 0 };
@@ -44,8 +76,9 @@ static void setup(void)
4476

4577
SAFE_IOCTL(fd, SNDRV_SEQ_IOCTL_CLIENT_ID, &client_id);
4678
SAFE_IOCTL(fd, SNDRV_SEQ_IOCTL_CREATE_QUEUE, &qconf);
79+
ssev.dest.client = client_id;
4780

48-
fzsync_pair.exec_loops = 100000;
81+
fzsync_pair.exec_loops = 1000000;
4982
tst_fzsync_pair_init(&fzsync_pair);
5083
}
5184

@@ -56,35 +89,26 @@ static void cleanup(void)
5689
tst_fzsync_pair_cleanup(&fzsync_pair);
5790
}
5891

59-
static void reinit_pool(int pool_size)
60-
{
61-
struct snd_seq_client_pool pconf = {
62-
.output_pool = pool_size,
63-
.client = client_id
64-
};
65-
66-
SAFE_IOCTL(fd, SNDRV_SEQ_IOCTL_SET_CLIENT_POOL, &pconf);
67-
}
68-
6992
static void *thread_run(void *arg)
7093
{
7194
while (tst_fzsync_run_b(&fzsync_pair)) {
7295
tst_fzsync_start_race_b(&fzsync_pair);
73-
reinit_pool(512);
96+
reinit_pool(10);
7497
tst_fzsync_end_race_b(&fzsync_pair);
7598
}
7699

77100
return arg;
78101
}
79102

80-
static void run(void)
103+
static void run(unsigned int n)
81104
{
82105
tst_fzsync_pair_reset(&fzsync_pair, thread_run);
83106

84107
while (tst_fzsync_run_a(&fzsync_pair)) {
85-
reinit_pool(1);
108+
reinit_pool(5);
109+
SAFE_IOCTL(fd, SNDRV_SEQ_IOCTL_REMOVE_EVENTS, &rminfo);
86110
tst_fzsync_start_race_a(&fzsync_pair);
87-
reinit_pool(2);
111+
testfunc_list[n]();
88112
tst_fzsync_end_race_a(&fzsync_pair);
89113

90114
if (tst_taint_check()) {
@@ -97,9 +121,11 @@ static void run(void)
97121
}
98122

99123
static struct tst_test test = {
100-
.test_all = run,
124+
.test = run,
125+
.tcnt = ARRAY_SIZE(testfunc_list),
101126
.setup = setup,
102127
.cleanup = cleanup,
128+
.timeout = 120,
103129
.tags = (const struct tst_tag[]) {
104130
{"linux-git", "d15d662e89fc"},
105131
{"CVE", "2018-7566"},

0 commit comments

Comments
 (0)