summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Wilson <chris+github@qwirx.com>2017-06-18 18:56:08 +0000
committerChris Wilson <chris+github@qwirx.com>2017-06-22 20:28:06 +0100
commit6a04b0abd728da5211e6702b1d42aef95c02d8da (patch)
treebc8ec9cb1f7aa1783b73096f6e4a54c96133cb90
parentd8422a8b053b62c67e5fe2e861a09d2c792b657a (diff)
Fix intercept of SYS_open on platforms that only have SYS_openat (e.g. arm64)
-rw-r--r--infrastructure/m4/boxbackup_tests.m41
-rw-r--r--lib/intercept/intercept.cpp6
-rw-r--r--lib/intercept/intercept.h9
-rw-r--r--test/raidfile/testraidfile.cpp9
4 files changed, 17 insertions, 8 deletions
diff --git a/infrastructure/m4/boxbackup_tests.m4 b/infrastructure/m4/boxbackup_tests.m4
index 849ffd7a..7410159a 100644
--- a/infrastructure/m4/boxbackup_tests.m4
+++ b/infrastructure/m4/boxbackup_tests.m4
@@ -224,6 +224,7 @@ AC_CHECK_DECLS([INFTIM],,, [[#include <poll.h>]])
AC_CHECK_DECLS([SO_PEERCRED],,, [[#include <sys/socket.h>]])
AC_CHECK_DECLS([SOL_TCP],,, [[#include <netinet/tcp.h>]])
AC_CHECK_DECLS([TCP_INFO],,, [[#include <netinet/tcp.h>]])
+AC_CHECK_DECLS([SYS_open, SYS_openat],,, [[#include <sys/syscall.h>]])
if test -n "$have_sys_socket_h"; then
AC_CHECK_DECLS([SO_SNDBUF],,, [[#include <sys/socket.h>]])
diff --git a/lib/intercept/intercept.cpp b/lib/intercept/intercept.cpp
index ac8c4431..72bd8d4e 100644
--- a/lib/intercept/intercept.cpp
+++ b/lib/intercept/intercept.cpp
@@ -242,6 +242,10 @@ extern "C" int
open(const char *path, int flags, ...)
#endif // DEFINE_ONLY_OPEN64
{
+ // Some newer architectures don't have an open() syscall, but use openat() instead.
+ // In these cases we will need to call sys_openat() instead of sys_open().
+ // https://chromium.googlesource.com/linux-syscall-support/
+
if(intercept_count > 0)
{
if(intercept_filename != NULL &&
@@ -264,6 +268,8 @@ extern "C" int
#ifdef PLATFORM_NO_SYSCALL
int r = TEST_open(path, flags, mode);
+#elif HAVE_DECL_SYS_OPENAT && !HAVE_DECL_SYS_OPEN
+ int r = syscall(SYS_openat, AT_FDCWD, path, flags, mode);
#else
int r = syscall(SYS_open, path, flags, mode);
#endif
diff --git a/lib/intercept/intercept.h b/lib/intercept/intercept.h
index c0d61638..4de5f9f2 100644
--- a/lib/intercept/intercept.h
+++ b/lib/intercept/intercept.h
@@ -62,5 +62,14 @@ void intercept_setup_stat_post_hook (lstat_post_hook_t hookfn);
void intercept_clear_setup();
+// Some newer architectures don't have an open() syscall, but use openat() instead.
+// In these cases we define SYS_open (which is otherwise undefined) to equal SYS_openat
+// (which is defined) so that everywhere else we can call intercept_setup_error(SYS_open)
+// without caring about the difference.
+// https://chromium.googlesource.com/linux-syscall-support/
+#if !HAVE_DECL_SYS_OPEN && HAVE_DECL_SYS_OPENAT
+# define SYS_open SYS_openat
+#endif
+
#endif // !PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE
#endif // !INTERCEPT_H
diff --git a/test/raidfile/testraidfile.cpp b/test/raidfile/testraidfile.cpp
index c8150387..d771f23d 100644
--- a/test/raidfile/testraidfile.cpp
+++ b/test/raidfile/testraidfile.cpp
@@ -25,6 +25,7 @@
#include "RaidFileException.h"
#include "RaidFileRead.h"
#include "Guards.h"
+#include "intercept.h"
#include "MemLeakFindOn.h"
@@ -37,14 +38,6 @@
#define TRF_CAN_INTERCEPT
#endif
-
-#ifdef TRF_CAN_INTERCEPT
-// function in intercept.cpp for setting up errors
-void intercept_setup_error(const char *filename, unsigned int errorafter, int errortoreturn, int syscalltoerror);
-bool intercept_triggered();
-void intercept_clear_setup();
-#endif
-
// Nice random data for testing written files
class R250 {
public: