diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..90a0ca0b6e79492af5092aaa9a431010eb49ccad --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,67 @@ +# This file is a template, and might need editing before it works on your project. +# This is a sample GitLab CI/CD configuration file that should run without any modifications. +# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts, +# it uses echo commands to simulate the pipeline execution. +# +# A pipeline is composed of independent jobs that run scripts, grouped into stages. +# Stages run in sequential order, but jobs within stages run in parallel. +# +# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages +# +# You can copy and paste this template into a new `.gitlab-ci.yml` file. +# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword. +# +# To contribute improvements to CI/CD templates, please follow the Development guide at: +# https://docs.gitlab.com/ee/development/cicd/templates.html +# This specific template is located at: +# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml + +stages: # List of stages for jobs, and their order of execution + - build + - test + - deploy + +variables: + BUILD_PATH: "${CI_PROJECT_DIR}/syscall/build" + INSTALL_PATH: "${CI_PROJECT_DIR}/syscall/install" + LD_LIBRARY_PATH: "${CI_PROJECT_DIR}/deps/install/lib:${CI_PROJECT_DIR}/deps/install/lib64" + CCACHE_DIR: "${CI_PROJECT_DIR}/ccache" + +image: gekkofs/core:0.9.4-dev + +build-job: # This job runs in the build stage, which runs first. + stage: build + image: gekkofs/deps:0.9.4-dev + script: + - echo "Compiling the code..." + - ccache --zero-stats + - /usr/sbin/update-ccache-symlinks + - export PATH="/usr/lib/ccache:$PATH" + - mkdir -p ${BUILD_PATH} ${INSTALL_PATH} + - cd ${BUILD_PATH} + - cmake ${CI_PROJECT_DIR} + - make -j $(nproc) install + artifacts: + paths: + - ${BUILD_PATH} + - ${INSTALL_PATH} + expire_in: 1 day + cache: + key: ccache-syscall + paths: + - $CCACHE_DIR + +unit-test-job: # This job runs in the test stage. + stage: test # It only starts when the job in the build stage completes successfully. + image: gekkofs/deps:0.9.4-dev + needs: ['build-job'] + script: + - ls -ltrh ${INSTALL_PATH} + - ${BUILD_PATH}/opendevnull --syscall getpid + - LD_PRELOAD=${BUILD_PATH}/libeval_intercept.so ${BUILD_PATH}/opendevnull --syscall getpid + artifacts: + expire_in: 1 week + when: always + paths: + - ${BUILD_PATH} + diff --git a/src/eval.cpp b/src/eval.cpp index 1400eec172b32415b64fd9dd1b66456f84684ce9..8e6177e0e0eda60ff18df59799b52701beb5c2ab 100644 --- a/src/eval.cpp +++ b/src/eval.cpp @@ -10,6 +10,10 @@ int hook_openat(int dirfd, const char *cpath, int flags, mode_t mode) { return syscall_no_intercept(SYS_openat, dirfd, cpath, flags, mode); } +int hook_getpid() { + return 42; +} + inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4, long arg5, long *result) { @@ -26,6 +30,9 @@ inline int hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, reinterpret_cast(arg1), static_cast(arg2), static_cast(arg3)); break; + case SYS_getpid: + *result = hook_getpid(); + break; default: // ignore any other syscalls, i.e.: pass them on to the kernel // (syscalls forwarded to the kernel that return are logged in @@ -46,7 +53,10 @@ int hook_guard_wrapper(long syscall_number, long arg0, long arg1, long arg2, if (syscall_number == SYS_openat) was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, syscall_return_value); - + else + if (syscall_number == SYS_getpid) + was_hooked = hook(syscall_number, arg0, arg1, arg2, arg3, arg4, arg5, + syscall_return_value); return was_hooked; } diff --git a/src/opendevnull.cpp b/src/opendevnull.cpp index 2596becbc34ce85a3c96e51a17e9dce3c2a2f2b3..3198caa6e3db8bb629b74e1f3ee37e661b496779 100644 --- a/src/opendevnull.cpp +++ b/src/opendevnull.cpp @@ -4,36 +4,61 @@ #include #include -int main() { +int main(int argc, char* argv[]) { + // Check if the correct number of arguments is provided + if (argc != 3) { + std::cerr << "Usage: " << argv[0] << " --syscall " << std::endl; + return 1; + } + + + // measure time to run in microseconds - struct timespec start, end; - clock_gettime(CLOCK_MONOTONIC, &start); - // open /dev/null 100000 times + + std::string option = argv[1]; + std::string syscall = argv[2]; + + double reps = 1000.0*100000.0; + // Handle the --syscall option + if (option == "--syscall") { + if (syscall == "open") { - for (int j = 0; j < 1000; j++) { - for (int i = 0; i < 100000; i++) { - int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + + for (int j = 0; j < 1000; j++) { + for (int i = 0; i < 100000; i++) { + int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); - close(fd); + close(fd); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + double time_taken = + (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3; + + + std::cout << "Mean time taken: " << time_taken / reps << " microseconds" + << std::endl; } + else if (syscall == "getpid") { + struct timespec start, end; + clock_gettime(CLOCK_MONOTONIC, &start); + + for (int j = 0; j < 1000; j++) { + for (int i = 0; i < 100000; i++) { + int ret = getpid(); + } + } + clock_gettime(CLOCK_MONOTONIC, &end); + double time_taken = + (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3; + + + std::cout << "Mean time taken: " << time_taken / reps << " microseconds" + << std::endl; + } } - clock_gettime(CLOCK_MONOTONIC, &end); - double time_taken = - (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3; - std::cout << "Time taken: " << time_taken << " microseconds" << std::endl; - // mean of the time for a syscall (10000000) - - std::cout << "Mean time taken: " << time_taken / 100000000.0 << " microseconds" - << std::endl; - // Calculate single syscall () - clock_gettime(CLOCK_MONOTONIC, &start); - int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0); - close(fd); - clock_gettime(CLOCK_MONOTONIC, &end); - std::cout << "Time taken for single syscall: " - << (end.tv_sec - start.tv_sec) * 1e6 + - (end.tv_nsec - start.tv_nsec) / 1e3 - << " microseconds" << std::endl; return 0; }