Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: gcc 5.3 version of libasan is broken
On 2016/06/07 8:58, Christos Zoulas wrote:
This is what I was thinking. Perhaps it is easier to use syscall for ILP32
and __syscall for LP64. But then there is lseek...
Yes. And it fails for LP64BE. I made the revised patch, where 3 kinds of
internal_syscall macros are provided for different types of retval:
- internal_syscall for 32-bit length (int, pid_t)
- internal_syscall64 for 64-bit length (off_t)
- internal_syscall_ptr for pointer and (s)size_t
This seems a little messy, but it is a reliable and simple solution for
sharing codes between ILP32 and LP64 / LE and BE. I tested that libasan
works just fine for amd64, i386, and earmv7hf-eb; it detects a buffer
overflow like this:
#include <stdlib.h>
#include <string.h>
int main()
{
char *dest, *from = "123";
dest = malloc(3);
strcpy(dest, from);
return 0;
}
I also checked libubsan on amd64, i386, and earmv7hf-eb. It can detect
an undefined operation like this:
int main()
{
int i = 1, j = 0;
return i / j;
}
I expect that it maybe works also for LP64BE though I could not test.
On 2016/06/07 8:57, Christos Zoulas wrote:
Are you sure this works for 64 bit? I am worried about the (long)0, padding.
Yes. I checked. The padding for mmap(2) is long:
https://nxr.netbsd.org/source/xref/src/sys/sys/syscallargs.h#1215
I also checked and reorganized arguments for other syscalls in the
attached patch.
I did not test on GCC 5.4. But I suppose that it should work because
no syscall-related changes were made for libsanitizer.
Thanks,
Rin
====
--- ./src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc.orig 2016-06-07 16:36:47.544537652 +0900
+++ ./src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc 2016-06-07 19:25:02.083848571 +0900
@@ -25,7 +25,22 @@
# define SYSCALL(name) __NR_ ## name
#endif
-#if (SANITIZER_FREEBSD && defined(__x86_64__)) || SANITIZER_NETBSD
+#if SANITIZER_NETBSD
+// We use 3 kinds of internal_syscall's for different types of retval in order
+// to address problems related to the byte order.
+// - internal_syscall for 32-bit length (int, pid_t)
+// - internal_syscall64 for 64-bit length (off_t)
+// - internal_syscall_ptr for pointer and (s)size_t
+# define internal_syscall syscall
+# define internal_syscall64 __syscall
+# if SANITIZER_WORDSIZE == 64
+# define internal_syscall_ptr __syscall
+# else
+# define internal_syscall_ptr syscall
+# endif
+#endif
+
+#if (SANITIZER_FREEBSD && defined(__x86_64__))
# define internal_syscall __syscall
# else
# define internal_syscall syscall
--- ./src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc.orig 2016-06-07 16:36:59.863423802 +0900
+++ ./src/external/gpl3/gcc/dist/libsanitizer/sanitizer_common/sanitizer_linux.cc 2016-06-07 21:46:48.721082396 +0900
@@ -101,7 +101,10 @@
// --------------- sanitizer_libc.h
uptr internal_mmap(void *addr, uptr length, int prot, int flags,
int fd, u64 offset) {
-#if SANITIZER_NETBSD || SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
+#if SANITIZER_NETBSD
+ return internal_syscall_ptr(SYSCALL(mmap), addr, length, prot, flags, fd,
+ (long)0, offset);
+#elif SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
offset, 0);
#else
@@ -142,21 +145,33 @@
uptr internal_read(fd_t fd, void *buf, uptr count) {
sptr res;
+#ifdef SANITIZER_NETBSD
+ HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(read), fd, buf, count));
+#else
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf,
count));
+#endif
return res;
}
uptr internal_write(fd_t fd, const void *buf, uptr count) {
sptr res;
+#ifdef SANITIZER_NETBSD
+ HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(write), fd, buf, count));
+#else
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf,
count));
+#endif
return res;
}
uptr internal_ftruncate(fd_t fd, uptr size) {
sptr res;
+#ifdef SANITIZER_NETBSD
+ HANDLE_EINTR(res, internal_syscall(SYSCALL(ftruncate), fd, 0, (s64)size));
+#else
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd, size));
+#endif
return res;
}
@@ -239,7 +254,9 @@
}
uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_NETBSD
+ return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize);
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD,
(uptr)path, (uptr)buf, bufsize);
#else
@@ -311,7 +328,11 @@
kernel_timeval tv;
#endif
internal_memset(&tv, 0, sizeof(tv));
+#if SANITIZER_NETBSD
+ internal_syscall(SYSCALL(gettimeofday), &tv, NULL);
+#else
internal_syscall(SYSCALL(gettimeofday), (uptr)&tv, 0);
+#endif
return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
}
@@ -486,14 +507,22 @@
};
// Syscall wrappers.
+#if SANITIZER_NETBSD
+// XXX We need to convert arguments.
+#else
uptr internal_ptrace(int request, int pid, void *addr, void *data) {
return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr,
(uptr)data);
}
+#endif
uptr internal_waitpid(int pid, int *status, int options) {
+#if SANITIZER_NETBSD
+ return internal_syscall(SYSCALL(wait4), pid, status, options, NULL);
+#else
return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options,
0 /* rusage */);
+#endif
}
uptr internal_getpid() {
@@ -505,7 +534,9 @@
}
uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
+#if SANITIZER_NETBSD
+ return internal_syscall(SYSCALL(getdents), fd, dirp->d_name, (uptr)count);
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count);
#else
return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count);
@@ -513,7 +544,11 @@
}
uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
+#if SANITIZER_NETBSD
+ return internal_syscall64(SYSCALL(lseek), fd, 0, offset, whence);
+#else
return internal_syscall(SYSCALL(lseek), fd, offset, whence);
+#endif
}
#if SANITIZER_LINUX
Home |
Main Index |
Thread Index |
Old Index