1f08c3bdfSopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 2f08c3bdfSopenharmony_ci/* 3f08c3bdfSopenharmony_ci * Copyright (c) 2019 Linaro Limited. All rights reserved. 4f08c3bdfSopenharmony_ci * Author: Rafael David Tinoco <rafael.tinoco@linaro.org> 5f08c3bdfSopenharmony_ci */ 6f08c3bdfSopenharmony_ci/* 7f08c3bdfSopenharmony_ci * Bad argument tests for clock_gettime(2) on multiple clocks: 8f08c3bdfSopenharmony_ci * 9f08c3bdfSopenharmony_ci * 1) MAX_CLOCKS 10f08c3bdfSopenharmony_ci * 2) MAX_CLOCKS + 1 11f08c3bdfSopenharmony_ci * 3) CLOCK_REALTIME 12f08c3bdfSopenharmony_ci * 4) CLOCK_MONOTONIC 13f08c3bdfSopenharmony_ci * 5) CLOCK_PROCESS_CPUTIME_ID 14f08c3bdfSopenharmony_ci * 6) CLOCK_THREAD_CPUTIME_ID 15f08c3bdfSopenharmony_ci * 7) CLOCK_REALTIME_COARSE 16f08c3bdfSopenharmony_ci * 8) CLOCK_MONOTONIC_COARSE 17f08c3bdfSopenharmony_ci * 9) CLOCK_MONOTONIC_RAW 18f08c3bdfSopenharmony_ci * 10) CLOCK_BOOTTIME 19f08c3bdfSopenharmony_ci */ 20f08c3bdfSopenharmony_ci 21f08c3bdfSopenharmony_ci#include "config.h" 22f08c3bdfSopenharmony_ci#include "time64_variants.h" 23f08c3bdfSopenharmony_ci#include "tst_timer.h" 24f08c3bdfSopenharmony_ci#include "tst_safe_clocks.h" 25f08c3bdfSopenharmony_ci 26f08c3bdfSopenharmony_cistatic void *bad_addr; 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_cistruct test_case { 29f08c3bdfSopenharmony_ci clockid_t clktype; 30f08c3bdfSopenharmony_ci int exp_err; 31f08c3bdfSopenharmony_ci int allow_inval; 32f08c3bdfSopenharmony_ci}; 33f08c3bdfSopenharmony_ci 34f08c3bdfSopenharmony_cistatic struct test_case tc[] = { 35f08c3bdfSopenharmony_ci { 36f08c3bdfSopenharmony_ci .clktype = MAX_CLOCKS, 37f08c3bdfSopenharmony_ci .exp_err = EINVAL, 38f08c3bdfSopenharmony_ci }, 39f08c3bdfSopenharmony_ci { 40f08c3bdfSopenharmony_ci .clktype = MAX_CLOCKS + 1, 41f08c3bdfSopenharmony_ci .exp_err = EINVAL, 42f08c3bdfSopenharmony_ci }, 43f08c3bdfSopenharmony_ci /* 44f08c3bdfSopenharmony_ci * Different POSIX clocks have different (*clock_get)() handlers. 45f08c3bdfSopenharmony_ci * It justifies testing EFAULT for all. 46f08c3bdfSopenharmony_ci */ 47f08c3bdfSopenharmony_ci { 48f08c3bdfSopenharmony_ci .clktype = CLOCK_REALTIME, 49f08c3bdfSopenharmony_ci .exp_err = EFAULT, 50f08c3bdfSopenharmony_ci }, 51f08c3bdfSopenharmony_ci { 52f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC, 53f08c3bdfSopenharmony_ci .exp_err = EFAULT, 54f08c3bdfSopenharmony_ci }, 55f08c3bdfSopenharmony_ci { 56f08c3bdfSopenharmony_ci .clktype = CLOCK_PROCESS_CPUTIME_ID, 57f08c3bdfSopenharmony_ci .exp_err = EFAULT, 58f08c3bdfSopenharmony_ci }, 59f08c3bdfSopenharmony_ci { 60f08c3bdfSopenharmony_ci .clktype = CLOCK_THREAD_CPUTIME_ID, 61f08c3bdfSopenharmony_ci .exp_err = EFAULT, 62f08c3bdfSopenharmony_ci }, 63f08c3bdfSopenharmony_ci { 64f08c3bdfSopenharmony_ci .clktype = CLOCK_REALTIME_COARSE, 65f08c3bdfSopenharmony_ci .exp_err = EFAULT, 66f08c3bdfSopenharmony_ci .allow_inval = 1, 67f08c3bdfSopenharmony_ci }, 68f08c3bdfSopenharmony_ci { 69f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC_COARSE, 70f08c3bdfSopenharmony_ci .exp_err = EFAULT, 71f08c3bdfSopenharmony_ci .allow_inval = 1, 72f08c3bdfSopenharmony_ci }, 73f08c3bdfSopenharmony_ci { 74f08c3bdfSopenharmony_ci .clktype = CLOCK_MONOTONIC_RAW, 75f08c3bdfSopenharmony_ci .exp_err = EFAULT, 76f08c3bdfSopenharmony_ci .allow_inval = 1, 77f08c3bdfSopenharmony_ci }, 78f08c3bdfSopenharmony_ci { 79f08c3bdfSopenharmony_ci .clktype = CLOCK_BOOTTIME, 80f08c3bdfSopenharmony_ci .exp_err = EFAULT, 81f08c3bdfSopenharmony_ci .allow_inval = 1, 82f08c3bdfSopenharmony_ci }, 83f08c3bdfSopenharmony_ci}; 84f08c3bdfSopenharmony_ci 85f08c3bdfSopenharmony_cistatic struct tst_ts spec; 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci/* 88f08c3bdfSopenharmony_ci * bad pointer w/ libc causes SIGSEGV signal, call syscall directly 89f08c3bdfSopenharmony_ci */ 90f08c3bdfSopenharmony_cistatic struct time64_variants variants[] = { 91f08c3bdfSopenharmony_ci#if (__NR_clock_gettime != __LTP__NR_INVALID_SYSCALL) 92f08c3bdfSopenharmony_ci { .clock_gettime = sys_clock_gettime, .ts_type = TST_KERN_OLD_TIMESPEC, .desc = "syscall with old kernel spec"}, 93f08c3bdfSopenharmony_ci#endif 94f08c3bdfSopenharmony_ci 95f08c3bdfSopenharmony_ci#if (__NR_clock_gettime64 != __LTP__NR_INVALID_SYSCALL) 96f08c3bdfSopenharmony_ci { .clock_gettime = sys_clock_gettime64, .ts_type = TST_KERN_TIMESPEC, .desc = "syscall time64 with kernel spec"}, 97f08c3bdfSopenharmony_ci#endif 98f08c3bdfSopenharmony_ci}; 99f08c3bdfSopenharmony_ci 100f08c3bdfSopenharmony_cistatic void setup(void) 101f08c3bdfSopenharmony_ci{ 102f08c3bdfSopenharmony_ci tst_res(TINFO, "Testing variant: %d: %s", tst_variant, variants[tst_variant].desc); 103f08c3bdfSopenharmony_ci 104f08c3bdfSopenharmony_ci bad_addr = tst_get_bad_addr(NULL); 105f08c3bdfSopenharmony_ci} 106f08c3bdfSopenharmony_ci 107f08c3bdfSopenharmony_cistatic void verify_clock_gettime(unsigned int i) 108f08c3bdfSopenharmony_ci{ 109f08c3bdfSopenharmony_ci struct time64_variants *tv = &variants[tst_variant]; 110f08c3bdfSopenharmony_ci void *ts; 111f08c3bdfSopenharmony_ci 112f08c3bdfSopenharmony_ci /* bad pointer cases */ 113f08c3bdfSopenharmony_ci if (tc[i].exp_err == EFAULT) { 114f08c3bdfSopenharmony_ci ts = bad_addr; 115f08c3bdfSopenharmony_ci } else { 116f08c3bdfSopenharmony_ci spec.type = tv->ts_type; 117f08c3bdfSopenharmony_ci ts = tst_ts_get(&spec); 118f08c3bdfSopenharmony_ci } 119f08c3bdfSopenharmony_ci 120f08c3bdfSopenharmony_ci TEST(tv->clock_gettime(tc[i].clktype, ts)); 121f08c3bdfSopenharmony_ci 122f08c3bdfSopenharmony_ci if (TST_RET != -1) { 123f08c3bdfSopenharmony_ci tst_res(TFAIL, "clock_gettime(2): clock %s passed unexpectedly", 124f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 125f08c3bdfSopenharmony_ci return; 126f08c3bdfSopenharmony_ci } 127f08c3bdfSopenharmony_ci 128f08c3bdfSopenharmony_ci if ((tc[i].exp_err == TST_ERR) || 129f08c3bdfSopenharmony_ci (tc[i].allow_inval && TST_ERR == EINVAL)) { 130f08c3bdfSopenharmony_ci tst_res(TPASS | TTERRNO, "clock_gettime(2): clock %s failed as expected", 131f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 132f08c3bdfSopenharmony_ci } else { 133f08c3bdfSopenharmony_ci tst_res(TFAIL | TTERRNO, "clock_gettime(2): clock %s failed unexpectedly", 134f08c3bdfSopenharmony_ci tst_clock_name(tc[i].clktype)); 135f08c3bdfSopenharmony_ci } 136f08c3bdfSopenharmony_ci} 137f08c3bdfSopenharmony_ci 138f08c3bdfSopenharmony_cistatic struct tst_test test = { 139f08c3bdfSopenharmony_ci .test = verify_clock_gettime, 140f08c3bdfSopenharmony_ci .tcnt = ARRAY_SIZE(tc), 141f08c3bdfSopenharmony_ci .test_variants = ARRAY_SIZE(variants), 142f08c3bdfSopenharmony_ci .setup = setup, 143f08c3bdfSopenharmony_ci .needs_root = 1, 144f08c3bdfSopenharmony_ci}; 145