1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
2f08c3bdfSopenharmony_ci/*
3f08c3bdfSopenharmony_ci * Copyright (c) 2018 Google, Inc.
4f08c3bdfSopenharmony_ci */
5f08c3bdfSopenharmony_ci
6f08c3bdfSopenharmony_ci/*
7f08c3bdfSopenharmony_ci * Regression test for commit 4dca6ea1d943 ("KEYS: add missing permission check
8f08c3bdfSopenharmony_ci * for request_key() destination"), or CVE-2017-17807.  This bug allowed adding
9f08c3bdfSopenharmony_ci * a key to a keyring given only Search permission to that keyring, rather than
10f08c3bdfSopenharmony_ci * the expected Write permission.
11f08c3bdfSopenharmony_ci *
12f08c3bdfSopenharmony_ci * We test for the bug by trying to add a negatively instantiated key, since
13f08c3bdfSopenharmony_ci * adding a negatively instantiated key using the bug was easy whereas adding a
14f08c3bdfSopenharmony_ci * positively instantiated key required exploiting a race condition.
15f08c3bdfSopenharmony_ci */
16f08c3bdfSopenharmony_ci
17f08c3bdfSopenharmony_ci#include <errno.h>
18f08c3bdfSopenharmony_ci
19f08c3bdfSopenharmony_ci#include "tst_test.h"
20f08c3bdfSopenharmony_ci#include "lapi/keyctl.h"
21f08c3bdfSopenharmony_ci
22f08c3bdfSopenharmony_cistatic void do_test(void)
23f08c3bdfSopenharmony_ci{
24f08c3bdfSopenharmony_ci	key_serial_t keyid;
25f08c3bdfSopenharmony_ci	int saved_errno;
26f08c3bdfSopenharmony_ci
27f08c3bdfSopenharmony_ci	TEST(keyctl(KEYCTL_JOIN_SESSION_KEYRING, NULL));
28f08c3bdfSopenharmony_ci	if (TST_RET < 0)
29f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "failed to join new session keyring");
30f08c3bdfSopenharmony_ci
31f08c3bdfSopenharmony_ci	TEST(keyctl(KEYCTL_SETPERM, KEY_SPEC_SESSION_KEYRING,
32f08c3bdfSopenharmony_ci		    KEY_POS_SEARCH|KEY_POS_READ|KEY_POS_VIEW));
33f08c3bdfSopenharmony_ci	if (TST_RET < 0) {
34f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO,
35f08c3bdfSopenharmony_ci			"failed to set permissions on session keyring");
36f08c3bdfSopenharmony_ci	}
37f08c3bdfSopenharmony_ci
38f08c3bdfSopenharmony_ci	TEST(keyctl(KEYCTL_SET_REQKEY_KEYRING,
39f08c3bdfSopenharmony_ci		    KEY_REQKEY_DEFL_SESSION_KEYRING));
40f08c3bdfSopenharmony_ci	if (TST_RET < 0) {
41f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO,
42f08c3bdfSopenharmony_ci			"failed to set request-key default keyring");
43f08c3bdfSopenharmony_ci	}
44f08c3bdfSopenharmony_ci
45f08c3bdfSopenharmony_ci	TEST(keyctl(KEYCTL_READ, KEY_SPEC_SESSION_KEYRING,
46f08c3bdfSopenharmony_ci		    &keyid, sizeof(keyid)));
47f08c3bdfSopenharmony_ci	if (TST_RET < 0)
48f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "failed to read from session keyring");
49f08c3bdfSopenharmony_ci	if (TST_RET != 0)
50f08c3bdfSopenharmony_ci		tst_brk(TBROK, "session keyring is not empty");
51f08c3bdfSopenharmony_ci
52f08c3bdfSopenharmony_ci	TEST(request_key("user", "desc", "callout_info", 0));
53f08c3bdfSopenharmony_ci	if (TST_RET != -1)
54f08c3bdfSopenharmony_ci		tst_brk(TBROK, "request_key() unexpectedly succeeded");
55f08c3bdfSopenharmony_ci	saved_errno = TST_ERR;
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci	TEST(keyctl(KEYCTL_READ, KEY_SPEC_SESSION_KEYRING,
58f08c3bdfSopenharmony_ci		    &keyid, sizeof(keyid)));
59f08c3bdfSopenharmony_ci	if (TST_RET < 0)
60f08c3bdfSopenharmony_ci		tst_brk(TBROK | TTERRNO, "failed to read from session keyring");
61f08c3bdfSopenharmony_ci	if (TST_RET != 0)
62f08c3bdfSopenharmony_ci		tst_brk(TFAIL, "added key to keyring without permission");
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ci	TST_ERR = saved_errno;
65f08c3bdfSopenharmony_ci	if (TST_ERR == EACCES) {
66f08c3bdfSopenharmony_ci		tst_res(TPASS, "request_key() failed with EACCES as expected");
67f08c3bdfSopenharmony_ci	} else {
68f08c3bdfSopenharmony_ci		tst_res(TFAIL | TTERRNO,
69f08c3bdfSopenharmony_ci			"request_key() failed with unexpected error code");
70f08c3bdfSopenharmony_ci	}
71f08c3bdfSopenharmony_ci}
72f08c3bdfSopenharmony_ci
73f08c3bdfSopenharmony_cistatic struct tst_test test = {
74f08c3bdfSopenharmony_ci	.test_all = do_test,
75f08c3bdfSopenharmony_ci	.tags = (const struct tst_tag[]) {
76f08c3bdfSopenharmony_ci		{"CVE", "2017-17807"},
77f08c3bdfSopenharmony_ci		{"linux-git", "4dca6ea1d943"},
78f08c3bdfSopenharmony_ci		{}
79f08c3bdfSopenharmony_ci	}
80f08c3bdfSopenharmony_ci};
81