1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019 SUSE LLC 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Author: Christian Amann <camann@suse.com> 6f08c3bdfSopenharmony_ci */ 7f08c3bdfSopenharmony_ci/* 8f08c3bdfSopenharmony_ci * Regression test for CVE-2017-18344: 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * In kernels prior to 4.14.8 sigevent.sigev_notify is not 11f08c3bdfSopenharmony_ci * properly verified when calling timer_create(2) with the 12f08c3bdfSopenharmony_ci * field being set to (SIGEV_SIGNAL | SIGEV_THREAD_ID). 13f08c3bdfSopenharmony_ci * This can be used to read arbitrary kernel memory. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * For more info see: https://nvd.nist.gov/vuln/detail/CVE-2017-18344 16f08c3bdfSopenharmony_ci * or commit: cef31d9af908 17f08c3bdfSopenharmony_ci * 18f08c3bdfSopenharmony_ci * This test uses an unused number instead of SIGEV_THREAD_ID to check 19f08c3bdfSopenharmony_ci * if this field gets verified correctly. 20f08c3bdfSopenharmony_ci */ 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_ci#include <errno.h> 23f08c3bdfSopenharmony_ci#include <signal.h> 24f08c3bdfSopenharmony_ci#include <time.h> 25f08c3bdfSopenharmony_ci#include "tst_test.h" 26f08c3bdfSopenharmony_ci#include "lapi/common_timers.h" 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#define RANDOM_UNUSED_NUMBER (54321) 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_cistatic void run(void) 31f08c3bdfSopenharmony_ci{ 32f08c3bdfSopenharmony_ci struct sigevent evp; 33f08c3bdfSopenharmony_ci clock_t clock = CLOCK_MONOTONIC; 34f08c3bdfSopenharmony_ci kernel_timer_t created_timer_id; 35f08c3bdfSopenharmony_ci 36f08c3bdfSopenharmony_ci memset(&evp, 0, sizeof(evp)); 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_ci evp.sigev_signo = SIGALRM; 39f08c3bdfSopenharmony_ci evp.sigev_notify = SIGEV_SIGNAL | RANDOM_UNUSED_NUMBER; 40f08c3bdfSopenharmony_ci evp._sigev_un._tid = getpid(); 41f08c3bdfSopenharmony_ci 42f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_timer_create, clock, &evp, &created_timer_id)); 43f08c3bdfSopenharmony_ci 44f08c3bdfSopenharmony_ci if (TST_RET != 0) { 45f08c3bdfSopenharmony_ci if (TST_ERR == EINVAL) { 46f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, 47f08c3bdfSopenharmony_ci "timer_create() failed as expected"); 48f08c3bdfSopenharmony_ci } else { 49f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 50f08c3bdfSopenharmony_ci "timer_create() unexpectedly failed"); 51f08c3bdfSopenharmony_ci } 52f08c3bdfSopenharmony_ci return; 53f08c3bdfSopenharmony_ci } 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci tst_res(TFAIL, 56f08c3bdfSopenharmony_ci "timer_create() succeeded for invalid notification type"); 57f08c3bdfSopenharmony_ci 58f08c3bdfSopenharmony_ci TEST(tst_syscall(__NR_timer_delete, created_timer_id)); 59f08c3bdfSopenharmony_ci if (TST_RET != 0) { 60f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "Failed to delete timer %s", 61f08c3bdfSopenharmony_ci get_clock_str(clock)); 62f08c3bdfSopenharmony_ci } 63f08c3bdfSopenharmony_ci} 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_cistatic struct tst_test test = { 66f08c3bdfSopenharmony_ci .test_all = run, 67f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 68f08c3bdfSopenharmony_ci {"CVE", "2017-18344"}, 69f08c3bdfSopenharmony_ci {"linux-git", "cef31d9af908"}, 70f08c3bdfSopenharmony_ci {} 71f08c3bdfSopenharmony_ci } 72f08c3bdfSopenharmony_ci}; 73