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 
     35 #include "config.h"
     36 #ifdef HAVE_LINUX_KEYCTL_H
     37 # include <linux/keyctl.h>
     38 #endif
     39 #include "tst_test.h"
     40 #include "linux_syscall_numbers.h"
     41 
     42 #ifdef HAVE_LINUX_KEYCTL_H
     43 struct tcase {
     44 	const char *type;
     45 	size_t plen;
     46 } tcases[] = {
     47 	/*
     48 	 * The payload length we test for each key type needs to pass initial
     49 	 * validation but is otherwise arbitrary.  Note: the "rxrpc_s" key type
     50 	 * requires a payload of exactly 8 bytes.
     51 	 */
     52 	{ "asymmetric",		64 },
     53 	{ "cifs.idmap",		64 },
     54 	{ "cifs.spnego",	64 },
     55 	{ "pkcs7_test",		64 },
     56 	{ "rxrpc",		64 },
     57 	{ "rxrpc_s",		 8 },
     58 	{ "user",		64 },
     59 };
     60 #endif /* HAVE_LINUX_KEYCTL_H */
     61 
     62 static void verify_add_key(unsigned int i)
     63 {
     64 #ifdef HAVE_LINUX_KEYCTL_H
     65 	TEST(tst_syscall(__NR_add_key, tcases[i].type, "abc:def",
     66 			 NULL, tcases[i].plen, KEY_SPEC_PROCESS_KEYRING));
     67 
     68 	if (TEST_RETURN != -1) {
     69 		tst_res(TFAIL,
     70 			"add_key() with key type '%s' unexpectedly succeeded",
     71 			tcases[i].type);
     72 		return;
     73 	}
     74 
     75 	if (TEST_ERRNO == EFAULT) {
     76 		tst_res(TPASS, "received expected EFAULT with key type '%s'",
     77 			tcases[i].type);
     78 		return;
     79 	}
     80 
     81 	if (TEST_ERRNO == ENODEV) {
     82 		tst_res(TCONF, "kernel doesn't support key type '%s'",
     83 			tcases[i].type);
     84 		return;
     85 	}
     86 
     87 	/*
     88 	 * It's possible for the "asymmetric" key type to be supported, but with
     89 	 * no asymmetric key parsers registered.  In that case, attempting to
     90 	 * add a key of type asymmetric will fail with EBADMSG.
     91 	 */
     92 	if (TEST_ERRNO == EBADMSG && !strcmp(tcases[i].type, "asymmetric")) {
     93 		tst_res(TCONF, "no asymmetric key parsers are registered");
     94 		return;
     95 	}
     96 
     97 	tst_res(TFAIL | TTERRNO, "unexpected error with key type '%s'",
     98 		tcases[i].type);
     99 #else
    100 	tst_brk(TCONF, "linux/keyctl.h was missing upon compilation.");
    101 #endif /* HAVE_LINUX_KEYCTL_H */
    102 }
    103 
    104 static struct tst_test test = {
    105 	.tid = "add_key02",
    106 	.tcnt = ARRAY_SIZE(tcases),
    107 	.test = verify_add_key,
    108 };
    109