From 01b4097a0414e31d96d883e387e8e2419736ac8f Mon Sep 17 00:00:00 2001 From: David Rowland Date: Mon, 20 May 2024 22:54:52 +0100 Subject: [PATCH] More checks --- README.md | 55 ++++++++++++++++++++++- src/lib_rt_check.cpp | 85 +++++++++++++++++++++++++++++++++-- tests/fail_calloc.cpp | 10 +++++ tests/fail_mmap.cpp | 44 ++++++++++++++++++ tests/fail_munmap.cpp | 46 +++++++++++++++++++ tests/fail_nanosleep.cpp | 12 +++++ tests/fail_posix_memalign.cpp | 11 +++++ tests/fail_realloc.cpp | 11 +++++ tests/fail_sleep.cpp | 10 +++++ tests/fail_stdsleep.cpp | 13 ++++++ tests/fail_usleep.cpp | 10 +++++ tests/fail_valloc.cpp | 10 +++++ 12 files changed, 312 insertions(+), 5 deletions(-) create mode 100644 tests/fail_calloc.cpp create mode 100644 tests/fail_mmap.cpp create mode 100644 tests/fail_munmap.cpp create mode 100644 tests/fail_nanosleep.cpp create mode 100644 tests/fail_posix_memalign.cpp create mode 100644 tests/fail_realloc.cpp create mode 100644 tests/fail_sleep.cpp create mode 100644 tests/fail_stdsleep.cpp create mode 100644 tests/fail_usleep.cpp create mode 100644 tests/fail_valloc.cpp diff --git a/README.md b/README.md index e575126..20a5bf8 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,60 @@ Dynamic library to catch run-time safety violations heavily inspired by [RADSan] - [ ] macOS ## Functions -- [ ] syscall (futex) +- Time + - [x] sleep + - [x] nanosleep + - [x] usleep +- Memory + - [x] malloc + - [x] calloc + - [x] realloc + - [x] free + - [ ] reallocf (macOS) + - [x] valloc + - [x] posix_memalign + - [x] mmap + - [x] munmap +- Threads + - [ ] pthread_create + - [ ] pthread_mutex_lock + - [ ] pthread_mutex_unlock + - [ ] pthread_join + - [ ] pthread_cond_signal + - [ ] pthread_cond_broadcast + - [ ] pthread_cond_wait + - [ ] pthread_cond_timedwait + - [ ] pthread_rwlock_rdlock + - [ ] pthread_rwlock_unlock + - [ ] pthread_rwlock_wrlock + - [ ] pthread_spin_lock +- Files + - [ ] open + - [ ] openat + - [ ] close + - [ ] fopen + - [ ] fread + - [ ] fwrite + - [ ] fclose + - [ ] fcntl + - [ ] creat + - [ ] puts + - [ ] fputs + - [x] stat + - [ ] stat64 + - [ ] fstat + - [ ] fstat64 +- IO + - [ ] socket + - [ ] send + - [ ] sendmsg + - [ ] sendto + - [ ] recv + - [ ] recvmsg + - [ ] recvfrom + - [ ] shutdown +- System calls + - [x] syscall ## CI/Tests - [ ] Failures diff --git a/src/lib_rt_check.cpp b/src/lib_rt_check.cpp index 2be2f3a..948d877 100644 --- a/src/lib_rt_check.cpp +++ b/src/lib_rt_check.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "lib_rt_check.h" @@ -64,18 +65,66 @@ extern "C" void *malloc(size_t size) { log_function_if_realtime_context (__func__); - static auto real_malloc = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc"); - return real_malloc(size); + static auto real = (void* (*)(size_t))dlsym(RTLD_NEXT, "malloc"); + return real(size); +} + +extern "C" void *calloc(size_t size, size_t item_size) +{ + log_function_if_realtime_context (__func__); + + static auto real = (void* (*)(size_t, size_t))dlsym(RTLD_NEXT, "calloc"); + return real(size, item_size); +} + +extern "C" void *realloc(void *ptr, size_t new_size) +{ + log_function_if_realtime_context (__func__); + + static auto real = (void* (*)(void*, size_t))dlsym(RTLD_NEXT, "realloc"); + return real(ptr, new_size); +} + +extern "C" void *valloc(size_t size) +{ + log_function_if_realtime_context (__func__); + + static auto real = (void* (*)(size_t))dlsym(RTLD_NEXT, "valloc"); + return real(size); } extern "C" void free(void* ptr) { log_function_if_realtime_context (__func__); - static auto real_free = (void (*)(void*))dlsym(RTLD_NEXT, "free"); - return real_free(ptr); + static auto real = (void (*)(void*))dlsym(RTLD_NEXT, "free"); + return real(ptr); +} + +extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size) +{ + log_function_if_realtime_context (__func__); + + static auto real = (int (*)(void**, size_t, size_t))dlsym(RTLD_NEXT, "posix_memalign"); + return real(memptr, alignment, size); +} + +extern "C" void *mmap(void* addr, size_t length, int prot, int flags, + int fd, off_t offset) +{ + log_function_if_realtime_context (__func__); + + static auto real = (void* (*)(void*, size_t, int, int, int, off_t))dlsym(RTLD_NEXT, "mmap"); + return real(addr, length, prot, flags, fd, offset); } +extern "C" int munmap(void* addr, size_t length) +{ + log_function_if_realtime_context (__func__); + + static auto real = (int (*)(void*, size_t))dlsym(RTLD_NEXT, "munmap"); + return real(addr, length); +} // //============================================================================== // // threads @@ -96,6 +145,34 @@ extern "C" int pthread_mutex_unlock(pthread_mutex_t *mutex) return real_pthread_mutex_unlock(mutex); } +//============================================================================== +// sleep +//============================================================================== +extern "C" unsigned int sleep(unsigned int seconds) +{ + log_function_if_realtime_context (__func__); + + static auto real = (unsigned int (*)(unsigned int))dlsym(RTLD_NEXT, "sleep"); + return real(seconds); +} + +extern "C" int usleep(useconds_t useconds) +{ + log_function_if_realtime_context (__func__); + + static auto real = (int (*)(useconds_t))dlsym(RTLD_NEXT, "usleep"); + return real(useconds); +} + +extern "C" int nanosleep(const struct timespec *req, + struct timespec * rem) +{ + log_function_if_realtime_context (__func__); + + static auto real = (int (*)(const struct timespec *, struct timespec *))dlsym(RTLD_NEXT, "nanosleep"); + return real(req, rem); +} + //============================================================================== // files //============================================================================== diff --git a/tests/fail_calloc.cpp b/tests/fail_calloc.cpp new file mode 100644 index 0000000..b00af35 --- /dev/null +++ b/tests/fail_calloc.cpp @@ -0,0 +1,10 @@ +#include + +int main() +{ + realtime_context rc; + + [[ maybe_unused ]] auto res = calloc (1024, 4); + + return 0; +} diff --git a/tests/fail_mmap.cpp b/tests/fail_mmap.cpp new file mode 100644 index 0000000..979cf85 --- /dev/null +++ b/tests/fail_mmap.cpp @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd = open("/usr/bin/awk", O_RDONLY); + + if (fd == -1) + { + std::cout << "ERROR: open failed\n"; + return 0; + } + + struct stat s; + int status = fstat (fd, &s); + auto size = s.st_size; + + char* map = nullptr; + + { + realtime_context rc; + map = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0); + } + + if (map == MAP_FAILED) + { + std::cout << "ERROR: MAP_FAILED\n"; + return 0; + } + + if (munmap(map, size) == -1) + { + std::cout << "ERROR: munmap failed\n"; + return 0; + } + + close(fd); + + return 0; +} diff --git a/tests/fail_munmap.cpp b/tests/fail_munmap.cpp new file mode 100644 index 0000000..1feb77a --- /dev/null +++ b/tests/fail_munmap.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include + +int main() +{ + int fd = open("/usr/bin/awk", O_RDONLY); + + if (fd == -1) + { + std::cout << "ERROR: open failed\n"; + return 0; + } + + struct stat s; + int status = fstat (fd, &s); + auto size = s.st_size; + + auto map = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0); + + if (map == MAP_FAILED) + { + std::cout << "ERROR: MAP_FAILED\n"; + return 0; + } + + int res; + + { + realtime_context rc; + res = munmap(map, size); + } + + if (res == -1) + { + std::cout << "ERROR: munmap failed\n"; + return 0; + } + + close(fd); + + return 0; +} diff --git a/tests/fail_nanosleep.cpp b/tests/fail_nanosleep.cpp new file mode 100644 index 0000000..e4ca486 --- /dev/null +++ b/tests/fail_nanosleep.cpp @@ -0,0 +1,12 @@ +#include +#include + +int main() +{ + timespec req; + + realtime_context rc; + nanosleep(&req, nullptr); + + return 0; +} diff --git a/tests/fail_posix_memalign.cpp b/tests/fail_posix_memalign.cpp new file mode 100644 index 0000000..eed33f1 --- /dev/null +++ b/tests/fail_posix_memalign.cpp @@ -0,0 +1,11 @@ +#include + +int main() +{ + realtime_context rc; + + void* p; + [[ maybe_unused ]] auto res = posix_memalign (&p, 32, 128); + + return 0; +} diff --git a/tests/fail_realloc.cpp b/tests/fail_realloc.cpp new file mode 100644 index 0000000..071e9dc --- /dev/null +++ b/tests/fail_realloc.cpp @@ -0,0 +1,11 @@ +#include + +int main() +{ + auto res = malloc (1024); + + realtime_context rc; + res = realloc (res, 1024 * 4); + + return 0; +} diff --git a/tests/fail_sleep.cpp b/tests/fail_sleep.cpp new file mode 100644 index 0000000..b46aed1 --- /dev/null +++ b/tests/fail_sleep.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + realtime_context rc; + sleep(1); + + return 0; +} diff --git a/tests/fail_stdsleep.cpp b/tests/fail_stdsleep.cpp new file mode 100644 index 0000000..c3f12f7 --- /dev/null +++ b/tests/fail_stdsleep.cpp @@ -0,0 +1,13 @@ +#include +#include +#include + +int main() +{ + using namespace std::chrono_literals; + + realtime_context rc; + std::this_thread::sleep_for (1ns); + + return 0; +} diff --git a/tests/fail_usleep.cpp b/tests/fail_usleep.cpp new file mode 100644 index 0000000..d5ebbd5 --- /dev/null +++ b/tests/fail_usleep.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() +{ + realtime_context rc; + usleep(100); + + return 0; +} diff --git a/tests/fail_valloc.cpp b/tests/fail_valloc.cpp new file mode 100644 index 0000000..2cf8beb --- /dev/null +++ b/tests/fail_valloc.cpp @@ -0,0 +1,10 @@ +#include + +int main() +{ + realtime_context rc; + + [[ maybe_unused ]] auto res = valloc (1024); + + return 0; +}