Home | History | Annotate | Download | only in add_key
      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 
     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 (TEST_RETURN != -1) {
     67 		tst_res(TFAIL,
     68 			"add_key() with key type '%s' unexpectedly succeeded",
     69 			tcases[i].type);
     70 		return;
     71 	}
     72 
     73 	if (TEST_ERRNO == EFAULT) {
     74 		tst_res(TPASS, "received expected EFAULT with key type '%s'",
     75 			tcases[i].type);
     76 		return;
     77 	}
     78 
     79 	if (TEST_ERRNO == 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 (TEST_ERRNO == 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