• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright 2019 Google LLC
4  */
5 
6 /*
7  * Regression test for commit ecaaab564978 ("crypto: salsa20 - fix
8  * blkcipher_walk API usage"), or CVE-2017-17805.  This test verifies that an
9  * empty message can be encrypted with Salsa20 without crashing the kernel.
10  *
11  * Fix for kernels < 4.14:
12  * With kernels missing commit 2d97591ef43d ("crypto: af_alg - consolidation
13  * of duplicate code") read() does not return in this situation. The call is
14  * now moved to a child thread in order to cancel it in case read() takes an
15  * unusual long amount of time.
16  */
17 
18 #include "tst_test.h"
19 #include "tst_af_alg.h"
20 #include "tst_safe_pthread.h"
21 #include <pthread.h>
22 #include <errno.h>
23 
24 #define SALSA20_IV_SIZE       8
25 #define SALSA20_MIN_KEY_SIZE  16
26 
verify_encrypt(void * arg)27 static void *verify_encrypt(void *arg)
28 {
29 	const uint8_t iv[SALSA20_IV_SIZE] = { 0 };
30 	const struct tst_alg_sendmsg_params params = {
31 		.encrypt = true,
32 		.iv = iv,
33 		.ivlen = SALSA20_IV_SIZE,
34 	};
35 	char buf[16];
36 	int reqfd = tst_alg_setup_reqfd("skcipher", "salsa20", NULL,
37 					SALSA20_MIN_KEY_SIZE);
38 
39 	/* Send a zero-length message to encrypt */
40 	tst_alg_sendmsg(reqfd, NULL, 0, &params);
41 
42 	/*
43 	 * Read the zero-length encrypted data.
44 	 * With the bug, the kernel crashed here.
45 	 */
46 	TST_CHECKPOINT_WAKE(0);
47 	if (read(reqfd, buf, 16) == 0)
48 		tst_res(TPASS, "Successfully \"encrypted\" an empty message");
49 	else
50 		tst_res(TFAIL, "read() didn't return 0");
51 	return arg;
52 }
53 
run(void)54 static void run(void)
55 {
56 	pthread_t thr;
57 
58 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
59 	SAFE_PTHREAD_CREATE(&thr, NULL, verify_encrypt, NULL);
60 
61 	TST_CHECKPOINT_WAIT(0);
62 
63 	while (pthread_kill(thr, 0) != ESRCH) {
64 		if (tst_timeout_remaining() <= 10) {
65 			pthread_cancel(thr);
66 			tst_brk(TBROK,
67 				"Timed out while reading from request socket.");
68 		}
69 		usleep(1000);
70 	}
71 }
72 
73 static struct tst_test test = {
74 	.test_all = run,
75 	.timeout = 20,
76 	.needs_checkpoints = 1,
77 	.tags = (const struct tst_tag[]) {
78 		{"linux-git", "ecaaab564978"},
79 		{"CVE", "2017-17805"},
80 		{}
81 	}
82 };
83