1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (C) 2019 Xiao Yang <ice_yangxiao@163.com> 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * Description: 6f08c3bdfSopenharmony_ci * Check various errnos for futex(FUTEX_CMP_REQUEUE). 7f08c3bdfSopenharmony_ci * 1) futex(FUTEX_CMP_REQUEUE) with invalid val returns EINVAL. 8f08c3bdfSopenharmony_ci * 2) futex(FUTEX_CMP_REQUEUE) with invalid val2 returns EINVAL. 9f08c3bdfSopenharmony_ci * 3) futex(FUTEX_CMP_REQUEUE) with mismatched val3 returns EAGAIN. 10f08c3bdfSopenharmony_ci * 11f08c3bdfSopenharmony_ci * It's also a regression test for CVE-2018-6927: 12f08c3bdfSopenharmony_ci * fbe0e839d1e2 ("futex: Prevent overflow by strengthen input validation") 13f08c3bdfSopenharmony_ci */ 14f08c3bdfSopenharmony_ci 15f08c3bdfSopenharmony_ci#include <errno.h> 16f08c3bdfSopenharmony_ci#include <sys/time.h> 17f08c3bdfSopenharmony_ci 18f08c3bdfSopenharmony_ci#include "tst_test.h" 19f08c3bdfSopenharmony_ci#include "futextest.h" 20f08c3bdfSopenharmony_ci#include "lapi/futex.h" 21f08c3bdfSopenharmony_ci 22f08c3bdfSopenharmony_cistatic futex_t *futexes; 23f08c3bdfSopenharmony_ci 24f08c3bdfSopenharmony_cistatic struct tcase { 25f08c3bdfSopenharmony_ci int set_wakes; 26f08c3bdfSopenharmony_ci int set_requeues; 27f08c3bdfSopenharmony_ci int exp_val; 28f08c3bdfSopenharmony_ci int exp_errno; 29f08c3bdfSopenharmony_ci} tcases[] = { 30f08c3bdfSopenharmony_ci {1, -1, FUTEX_INITIALIZER, EINVAL}, 31f08c3bdfSopenharmony_ci {-1, 1, FUTEX_INITIALIZER, EINVAL}, 32f08c3bdfSopenharmony_ci {1, 1, FUTEX_INITIALIZER + 1, EAGAIN}, 33f08c3bdfSopenharmony_ci}; 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_cistatic struct futex_test_variants variants[] = { 36f08c3bdfSopenharmony_ci#if (__NR_futex != __LTP__NR_INVALID_SYSCALL) 37f08c3bdfSopenharmony_ci { .fntype = FUTEX_FN_FUTEX, .desc = "syscall with old kernel spec"}, 38f08c3bdfSopenharmony_ci#endif 39f08c3bdfSopenharmony_ci 40f08c3bdfSopenharmony_ci#if (__NR_futex_time64 != __LTP__NR_INVALID_SYSCALL) 41f08c3bdfSopenharmony_ci { .fntype = FUTEX_FN_FUTEX64, .desc = "syscall time64 with kernel spec"}, 42f08c3bdfSopenharmony_ci#endif 43f08c3bdfSopenharmony_ci}; 44f08c3bdfSopenharmony_ci 45f08c3bdfSopenharmony_cistatic void verify_futex_cmp_requeue(unsigned int n) 46f08c3bdfSopenharmony_ci{ 47f08c3bdfSopenharmony_ci struct futex_test_variants *tv = &variants[tst_variant]; 48f08c3bdfSopenharmony_ci struct tcase *tc = &tcases[n]; 49f08c3bdfSopenharmony_ci 50f08c3bdfSopenharmony_ci TEST(futex_cmp_requeue(tv->fntype, &futexes[0], tc->exp_val, 51f08c3bdfSopenharmony_ci &futexes[1], tc->set_wakes, tc->set_requeues, 0)); 52f08c3bdfSopenharmony_ci if (TST_RET != -1) { 53f08c3bdfSopenharmony_ci tst_res(TFAIL, "futex_cmp_requeue() succeeded unexpectedly"); 54f08c3bdfSopenharmony_ci return; 55f08c3bdfSopenharmony_ci } 56f08c3bdfSopenharmony_ci 57f08c3bdfSopenharmony_ci if (TST_ERR != tc->exp_errno) { 58f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, 59f08c3bdfSopenharmony_ci "futex_cmp_requeue() failed unexpectedly, expected %s", 60f08c3bdfSopenharmony_ci tst_strerrno(tc->exp_errno)); 61f08c3bdfSopenharmony_ci return; 62f08c3bdfSopenharmony_ci } 63f08c3bdfSopenharmony_ci 64f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "futex_cmp_requeue() failed as expected"); 65f08c3bdfSopenharmony_ci} 66f08c3bdfSopenharmony_ci 67f08c3bdfSopenharmony_cistatic void setup(void) 68f08c3bdfSopenharmony_ci{ 69f08c3bdfSopenharmony_ci struct futex_test_variants *tv = &variants[tst_variant]; 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ci tst_res(TINFO, "Testing variant: %s", tv->desc); 72f08c3bdfSopenharmony_ci futex_supported_by_kernel(tv->fntype); 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_ci futexes = SAFE_MMAP(NULL, sizeof(futex_t) * 2, PROT_READ | PROT_WRITE, 75f08c3bdfSopenharmony_ci MAP_ANONYMOUS | MAP_SHARED, -1, 0); 76f08c3bdfSopenharmony_ci 77f08c3bdfSopenharmony_ci futexes[0] = FUTEX_INITIALIZER; 78f08c3bdfSopenharmony_ci futexes[1] = FUTEX_INITIALIZER + 1; 79f08c3bdfSopenharmony_ci} 80f08c3bdfSopenharmony_ci 81f08c3bdfSopenharmony_cistatic void cleanup(void) 82f08c3bdfSopenharmony_ci{ 83f08c3bdfSopenharmony_ci if (futexes) 84f08c3bdfSopenharmony_ci SAFE_MUNMAP((void *)futexes, sizeof(futex_t) * 2); 85f08c3bdfSopenharmony_ci} 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_cistatic struct tst_test test = { 88f08c3bdfSopenharmony_ci .setup = setup, 89f08c3bdfSopenharmony_ci .cleanup = cleanup, 90f08c3bdfSopenharmony_ci .test = verify_futex_cmp_requeue, 91f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tcases), 92f08c3bdfSopenharmony_ci .test_variants = ARRAY_SIZE(variants), 93f08c3bdfSopenharmony_ci .tags = (const struct tst_tag[]) { 94f08c3bdfSopenharmony_ci {"CVE", "2018-6927"}, 95f08c3bdfSopenharmony_ci {"linux-git", "fbe0e839d1e2"}, 96f08c3bdfSopenharmony_ci {} 97f08c3bdfSopenharmony_ci } 98f08c3bdfSopenharmony_ci}; 99