1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2022 Alejandro Guerrero <aguerrero@qualys.com>
4f08c3bdfSopenharmony_ci * Copyright (c) 2023 Wei Gao <wegao@suse.com>
5f08c3bdfSopenharmony_ci */
6f08c3bdfSopenharmony_ci
7f08c3bdfSopenharmony_ci/*\
8f08c3bdfSopenharmony_ci * [Description]
9f08c3bdfSopenharmony_ci *
10f08c3bdfSopenharmony_ci * Test for CVE-2022-0185.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * References links:
13f08c3bdfSopenharmony_ci *
14f08c3bdfSopenharmony_ci * - https://www.openwall.com/lists/oss-security/2022/01/25/14
15f08c3bdfSopenharmony_ci * - https://github.com/Crusaders-of-Rust/CVE-2022-0185
16f08c3bdfSopenharmony_ci *
17f08c3bdfSopenharmony_ci */
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci#include "tst_test.h"
20f08c3bdfSopenharmony_ci#include "lapi/fsmount.h"
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_ci#define MNTPOINT	"mntpoint"
23f08c3bdfSopenharmony_ci
24f08c3bdfSopenharmony_cistatic int fd = -1;
25f08c3bdfSopenharmony_ci
26f08c3bdfSopenharmony_cistatic void setup(void)
27f08c3bdfSopenharmony_ci{
28f08c3bdfSopenharmony_ci	fsopen_supported_by_kernel();
29f08c3bdfSopenharmony_ci}
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_cistatic void run(void)
32f08c3bdfSopenharmony_ci{
33f08c3bdfSopenharmony_ci	char *val = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
34f08c3bdfSopenharmony_ci	long pagesize;
35f08c3bdfSopenharmony_ci
36f08c3bdfSopenharmony_ci	TEST(fd = fsopen(tst_device->fs_type, 0));
37f08c3bdfSopenharmony_ci	if (fd == -1)
38f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "fsopen() failed");
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_ci	pagesize = sysconf(_SC_PAGESIZE);
41f08c3bdfSopenharmony_ci	if (pagesize == -1)
42f08c3bdfSopenharmony_ci		tst_brk(TBROK, "sysconf(_SC_PAGESIZE) failed");
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	for (size_t i = 0; i < 5000; i++) {
45f08c3bdfSopenharmony_ci		/* use same logic in kernel legacy_parse_param function */
46f08c3bdfSopenharmony_ci		const size_t len = i * (strlen(val) + 2) + (strlen(val) + 1) + 2;
47f08c3bdfSopenharmony_ci
48f08c3bdfSopenharmony_ci		TEST(fsconfig(fd, FSCONFIG_SET_STRING, "\x00", val, 0));
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ci		/* Legacy fsconfig() just copies arguments to buffer */
51f08c3bdfSopenharmony_ci		if (!TST_RET && len <= (size_t)pagesize)
52f08c3bdfSopenharmony_ci			continue;
53f08c3bdfSopenharmony_ci
54f08c3bdfSopenharmony_ci		if (!TST_RET) {
55f08c3bdfSopenharmony_ci			tst_res(TFAIL, "fsconfig() passed unexpectedly");
56f08c3bdfSopenharmony_ci		} else if (TST_RET != -1) {
57f08c3bdfSopenharmony_ci			tst_brk(TBROK | TTERRNO,
58f08c3bdfSopenharmony_ci				"Invalid fsconfig() return value %ld", TST_RET);
59f08c3bdfSopenharmony_ci		} else if (TST_ERR != EINVAL) {
60f08c3bdfSopenharmony_ci			tst_res(TFAIL | TTERRNO,
61f08c3bdfSopenharmony_ci				"fsconfig() failed with unexpected error");
62f08c3bdfSopenharmony_ci		}
63f08c3bdfSopenharmony_ci	}
64f08c3bdfSopenharmony_ci
65f08c3bdfSopenharmony_ci	if (fd != -1)
66f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd);
67f08c3bdfSopenharmony_ci
68f08c3bdfSopenharmony_ci	if (tst_taint_check())
69f08c3bdfSopenharmony_ci		tst_res(TFAIL, "kernel has issues on %s",
70f08c3bdfSopenharmony_ci			tst_device->fs_type);
71f08c3bdfSopenharmony_ci	else
72f08c3bdfSopenharmony_ci		tst_res(TPASS, "kernel seems to be fine on %s",
73f08c3bdfSopenharmony_ci			tst_device->fs_type);
74f08c3bdfSopenharmony_ci}
75f08c3bdfSopenharmony_ci
76f08c3bdfSopenharmony_cistatic void cleanup(void)
77f08c3bdfSopenharmony_ci{
78f08c3bdfSopenharmony_ci	if (fd >= 0)
79f08c3bdfSopenharmony_ci		SAFE_CLOSE(fd);
80f08c3bdfSopenharmony_ci}
81f08c3bdfSopenharmony_ci
82f08c3bdfSopenharmony_cistatic struct tst_test test = {
83f08c3bdfSopenharmony_ci	.test_all = run,
84f08c3bdfSopenharmony_ci	.setup = setup,
85f08c3bdfSopenharmony_ci	.cleanup = cleanup,
86f08c3bdfSopenharmony_ci	.needs_root = 1,
87f08c3bdfSopenharmony_ci	.format_device = 1,
88f08c3bdfSopenharmony_ci	.mntpoint = MNTPOINT,
89f08c3bdfSopenharmony_ci	.all_filesystems = 1,
90f08c3bdfSopenharmony_ci	.taint_check = TST_TAINT_W | TST_TAINT_D,
91f08c3bdfSopenharmony_ci	.skip_filesystems = (const char *const []){"fuse", NULL},
92f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
93f08c3bdfSopenharmony_ci		{"linux-git", "722d94847de29"},
94f08c3bdfSopenharmony_ci		{"CVE", "2022-0185"},
95f08c3bdfSopenharmony_ci		{}
96f08c3bdfSopenharmony_ci	}
97f08c3bdfSopenharmony_ci};
98