1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <dirent.h> 6#include <dlfcn.h> 7#include <errno.h> 8#include <fcntl.h> 9#include <string.h> 10#include <unistd.h> 11#include <unittest/unittest.h> 12 13#define GOOD_SYMBOL "zx_syscall_test_0" 14#define BAD_SYMBOL "zx_syscall_test_1" 15 16bool vdso_open_test(void) { 17 BEGIN_TEST; 18 19 int vdso_dir_fd = open("/boot/kernel/vdso", O_RDONLY | O_DIRECTORY); 20 ASSERT_GE(vdso_dir_fd, 0, "open of vdso directory failed"); 21 22 DIR* dir = fdopendir(dup(vdso_dir_fd)); 23 ASSERT_NONNULL(dir, "fdopendir failed"); 24 25 const struct dirent* d; 26 int vdso_files_found = 0; 27 while ((d = readdir(dir)) != NULL) { 28 if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) 29 continue; 30 31 ++vdso_files_found; 32 // Test that we can open for read. 33 int fd = openat(vdso_dir_fd, d->d_name, O_RDONLY); 34 EXPECT_GE(fd, 0, d->d_name); 35 EXPECT_EQ(close(fd), 0, ""); 36 37 // Test that we cannot open for write. 38 EXPECT_EQ(openat(vdso_dir_fd, d->d_name, O_RDWR), -1, 39 "opening vDSO file for writing"); 40 EXPECT_EQ(errno, EACCES, "opening vDSO file for writing"); 41 } 42 43 EXPECT_GT(vdso_files_found, 1, "didn't find vDSO files"); 44 45 EXPECT_EQ(closedir(dir), 0, ""); 46 EXPECT_EQ(close(vdso_dir_fd), 0, ""); 47 48 END_TEST; 49} 50 51bool vdso_missing_test_syscall1_test(void) { 52 BEGIN_TEST; 53 54 void* dso = dlopen("libzircon.so", RTLD_LOCAL | RTLD_NOLOAD); 55 ASSERT_NONNULL(dso, dlerror()); 56 57 EXPECT_NONNULL(dlsym(dso, GOOD_SYMBOL), dlerror()); 58 59 EXPECT_NULL(dlsym(dso, BAD_SYMBOL), BAD_SYMBOL " symbol found in vDSO"); 60 61 EXPECT_EQ(dlclose(dso), 0, ""); 62 63 END_TEST; 64} 65 66BEGIN_TEST_CASE(vdso_variant_tests) 67RUN_TEST(vdso_open_test) 68RUN_TEST(vdso_missing_test_syscall1_test) 69END_TEST_CASE(vdso_variant_tests) 70 71int main(int argc, char** argv) { 72 return unittest_run_all_tests(argc, argv) ? 0 : -1; 73} 74