1 /* 2 * Copyright (c) 2017 Google, Inc. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program, if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 /* 19 * Regression test for commit 37863c43b2c6 ("KEYS: prevent KEYCTL_READ on 20 * negative key"). This is CVE-2017-12192. 21 */ 22 23 #include <errno.h> 24 #include <stdlib.h> 25 #include <sys/wait.h> 26 27 #include "tst_test.h" 28 #include "lapi/keyctl.h" 29 30 static void try_to_read_negative_key(void) 31 { 32 key_serial_t key_id; 33 char buffer[128]; 34 35 /* 36 * Create a negatively instantiated key of the "user" key type. This 37 * key type is chosen because it has a ->read() method (which makes the 38 * bug reachable) and is available whenever CONFIG_KEYS is enabled. 39 * 40 * request_key() will result in the creation of a negative key provided 41 * that /sbin/request-key isn't configured to positively instantiate the 42 * key, based on the provided type, description, and callout_info. If 43 * /sbin/request-key doesn't exist, errno will be ENOENT; while if it 44 * does exist and we specify some random unprefixed description, errno 45 * should be ENOKEY (since /sbin/request-key should not be configured to 46 * instantiate random user keys). In either case a negative key should 47 * be created and we can continue on with the test. Negative keys last 48 * for 60 seconds so there should be plenty of time for the test. 49 */ 50 TEST(request_key("user", "description", "callout_info", 51 KEY_SPEC_PROCESS_KEYRING)); 52 if (TEST_RETURN != -1) 53 tst_brk(TBROK, "request_key() unexpectedly succeeded"); 54 55 if (TEST_ERRNO != ENOKEY && TEST_ERRNO != ENOENT) { 56 tst_brk(TBROK | TTERRNO, 57 "request_key() failed with unexpected error"); 58 } 59 60 /* Get the ID of the negative key by reading the keyring */ 61 TEST(keyctl(KEYCTL_READ, KEY_SPEC_PROCESS_KEYRING, 62 &key_id, sizeof(key_id))); 63 if (TEST_RETURN < 0) 64 tst_brk(TBROK | TTERRNO, "KEYCTL_READ unexpectedly failed"); 65 if (TEST_RETURN != sizeof(key_id)) { 66 tst_brk(TBROK, "KEYCTL_READ returned %ld but expected %zu", 67 TEST_RETURN, sizeof(key_id)); 68 } 69 70 /* 71 * Now try to read the negative key. Unpatched kernels will oops trying 72 * to read from memory address 0x00000000ffffff92. 73 */ 74 tst_res(TINFO, "trying to read from the negative key..."); 75 TEST(keyctl(KEYCTL_READ, key_id, buffer, sizeof(buffer))); 76 if (TEST_RETURN != -1) { 77 tst_brk(TFAIL, 78 "KEYCTL_READ on negative key unexpectedly succeeded"); 79 } 80 if (TEST_ERRNO != ENOKEY) { 81 tst_brk(TFAIL | TTERRNO, 82 "KEYCTL_READ on negative key failed with unexpected error"); 83 } 84 tst_res(TPASS, 85 "KEYCTL_READ on negative key expectedly failed with ENOKEY"); 86 } 87 88 static void do_test(void) 89 { 90 int status; 91 92 if (SAFE_FORK() == 0) { 93 try_to_read_negative_key(); 94 return; 95 } 96 97 SAFE_WAIT(&status); 98 99 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 100 tst_res(TPASS, "didn't crash while reading from negative key"); 101 return; 102 } 103 104 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGKILL) { 105 tst_res(TFAIL, "reading from negative key caused kernel oops"); 106 return; 107 } 108 109 if (WIFEXITED(status) && WEXITSTATUS(status) == TCONF) 110 tst_brk(TCONF, "syscall not implemented"); 111 112 tst_brk(TBROK, "Child %s", tst_strstatus(status)); 113 } 114 115 static struct tst_test test = { 116 .test_all = do_test, 117 .forks_child = 1, 118 }; 119