1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Copyright (c) 2020 Viresh Kumar <viresh.kumar@linaro.org> 4 * 5 * openat2() tests with various resolve flags. 6 */ 7#include "tst_test.h" 8#include "lapi/openat2.h" 9 10#define FOO_SYMLINK "foo_symlink" 11 12static struct open_how *how; 13 14static struct tcase { 15 const char *name; 16 const char *pathname; 17 uint64_t resolve; 18 int exp_errno; 19} tcases[] = { 20 /* Success cases */ 21 {"open /proc/version", "/proc/version", 0, 0}, 22 {"open magiclinks", "/proc/self/exe", 0, 0}, 23 {"open symlinks", FOO_SYMLINK, 0, 0}, 24 25 /* Failure cases */ 26 {"resolve-no-xdev", "/proc/version", RESOLVE_NO_XDEV, EXDEV}, 27 {"resolve-no-magiclinks", "/proc/self/exe", RESOLVE_NO_MAGICLINKS, ELOOP}, 28 {"resolve-no-symlinks", FOO_SYMLINK, RESOLVE_NO_SYMLINKS, ELOOP}, 29 {"resolve-beneath", "/proc/version", RESOLVE_BENEATH, EXDEV}, 30 {"resolve-beneath", "../foo", RESOLVE_BENEATH, EXDEV}, 31 {"resolve-no-in-root", "/proc/version", RESOLVE_IN_ROOT, ENOENT}, 32}; 33 34static void setup(void) 35{ 36 openat2_supported_by_kernel(); 37 SAFE_SYMLINK("/proc/version", FOO_SYMLINK); 38} 39 40static void run(unsigned int n) 41{ 42 struct tcase *tc = &tcases[n]; 43 44 how->flags = O_RDONLY | O_CREAT; 45 how->mode = S_IRUSR; 46 how->resolve = tc->resolve; 47 48 TEST(openat2(AT_FDCWD, tc->pathname, how, sizeof(*how))); 49 50 if (!tc->exp_errno) { 51 if (TST_RET < 0) { 52 tst_res(TFAIL | TTERRNO, "%s: openat2() failed", 53 tc->name); 54 return; 55 } 56 57 SAFE_CLOSE(TST_RET); 58 tst_res(TPASS, "%s: openat2() passed", tc->name); 59 } else { 60 if (TST_RET >= 0) { 61 SAFE_CLOSE(TST_RET); 62 tst_res(TFAIL, "%s: openat2() passed unexpectedly", 63 tc->name); 64 return; 65 } 66 67 if (tc->exp_errno != TST_ERR) { 68 tst_res(TFAIL | TTERRNO, "%s: openat2() should fail with %s", 69 tc->name, tst_strerrno(tc->exp_errno)); 70 return; 71 } 72 73 tst_res(TPASS | TTERRNO, "%s: openat2() failed as expected", 74 tc->name); 75 } 76} 77 78static struct tst_test test = { 79 .tcnt = ARRAY_SIZE(tcases), 80 .test = run, 81 .setup = setup, 82 .needs_tmpdir = 1, 83 .bufs = (struct tst_buffers []) { 84 {&how, .size = sizeof(*how)}, 85 {}, 86 } 87}; 88