1 /******************************************************************************
2 * Copyright (c) Crackerjack Project., 2007 *
3 * Copyright (c) 2017 Google, Inc. *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See *
13 * the GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 * *
19 ******************************************************************************/
20
21 /*
22 * Test that the add_key() syscall correctly handles a NULL payload with nonzero
23 * length. Specifically, it should fail with EFAULT rather than oopsing the
24 * kernel with a NULL pointer dereference or failing with EINVAL, as it did
25 * before (depending on the key type). This is a regression test for commit
26 * 5649645d725c ("KEYS: fix dereferencing NULL payload with nonzero length").
27 *
28 * Note that none of the key types that exhibited the NULL pointer dereference
29 * are guaranteed to be built into the kernel, so we just test as many as we
30 * can, in the hope of catching one. We also test with the "user" key type for
31 * good measure, although it was one of the types that failed with EINVAL rather
32 * than dereferencing NULL.
33 *
34 * This has been assigned CVE-2017-15274.
35 */
36
37 #include <errno.h>
38
39 #include "tst_test.h"
40 #include "lapi/keyctl.h"
41
42 struct tcase {
43 const char *type;
44 size_t plen;
45 } tcases[] = {
46 /*
47 * The payload length we test for each key type needs to pass initial
48 * validation but is otherwise arbitrary. Note: the "rxrpc_s" key type
49 * requires a payload of exactly 8 bytes.
50 */
51 { "asymmetric", 64 },
52 { "cifs.idmap", 64 },
53 { "cifs.spnego", 64 },
54 { "pkcs7_test", 64 },
55 { "rxrpc", 64 },
56 { "rxrpc_s", 8 },
57 { "user", 64 },
58 { "logon", 64 },
59 };
60
verify_add_key(unsigned int i)61 static void verify_add_key(unsigned int i)
62 {
63 TEST(add_key(tcases[i].type,
64 "abc:def", NULL, tcases[i].plen, KEY_SPEC_PROCESS_KEYRING));
65
66 if (TST_RET != -1) {
67 tst_res(TFAIL,
68 "add_key() with key type '%s' unexpectedly succeeded",
69 tcases[i].type);
70 return;
71 }
72
73 if (TST_ERR == EFAULT) {
74 tst_res(TPASS, "received expected EFAULT with key type '%s'",
75 tcases[i].type);
76 return;
77 }
78
79 if (TST_ERR == ENODEV) {
80 tst_res(TCONF, "kernel doesn't support key type '%s'",
81 tcases[i].type);
82 return;
83 }
84
85 /*
86 * It's possible for the "asymmetric" key type to be supported, but with
87 * no asymmetric key parsers registered. In that case, attempting to
88 * add a key of type asymmetric will fail with EBADMSG.
89 */
90 if (TST_ERR == EBADMSG && !strcmp(tcases[i].type, "asymmetric")) {
91 tst_res(TCONF, "no asymmetric key parsers are registered");
92 return;
93 }
94
95 tst_res(TFAIL | TTERRNO, "unexpected error with key type '%s'",
96 tcases[i].type);
97 }
98
99 static struct tst_test test = {
100 .tcnt = ARRAY_SIZE(tcases),
101 .test = verify_add_key,
102 };
103