diff --git a/src/__readlink_chk.c b/src/__readlink_chk.c index b77f17c4..5433a0af 100644 --- a/src/__readlink_chk.c +++ b/src/__readlink_chk.c @@ -25,6 +25,7 @@ #define _FORTIFY_SOURCE 2 #include #include +#include #include "libfakechroot.h" @@ -41,7 +42,12 @@ wrapper(__readlink_chk, ssize_t, (const char * path, char * buf, size_t bufsiz, debug("__readlink_chk(\"%s\", &buf, %zd, %zd)", path, bufsiz, buflen); expand_chroot_path(path); - if ((linksize = nextcall(__readlink_chk)(path, tmp, FAKECHROOT_PATH_MAX-1, buflen)) == -1) { + if (__builtin_expect(!!(bufsiz > buflen), 0)) { + printf("readlink: prevented write past end of buffer\n"); + exit(-1); + } + + if ((linksize = nextcall(__readlink_chk)(path, tmp, FAKECHROOT_PATH_MAX-1, FAKECHROOT_PATH_MAX-1)) == -1) { return -1; } tmp[linksize] = '\0'; diff --git a/src/__readlinkat_chk.c b/src/__readlinkat_chk.c index a7f11652..c25160ce 100644 --- a/src/__readlinkat_chk.c +++ b/src/__readlinkat_chk.c @@ -26,6 +26,7 @@ #define _FORTIFY_SOURCE 2 #include #include +#include #include "libfakechroot.h" @@ -42,7 +43,12 @@ wrapper(__readlinkat_chk, ssize_t, (int dirfd, const char * path, char * buf, si debug("__readlinkat_chk(%d, \"%s\", &buf, %zd, %zd)", dirfd, path, bufsiz, buflen); expand_chroot_path_at(dirfd, path); - if ((linksize = nextcall(__readlinkat_chk)(dirfd, path, tmp, FAKECHROOT_PATH_MAX-1, buflen)) == -1) { + if (__builtin_expect(!!(bufsiz > buflen), 0)) { + printf("readlinkat: prevented write past end of buffer\n"); + exit(-1); + } + + if ((linksize = nextcall(__readlinkat_chk)(dirfd, path, tmp, FAKECHROOT_PATH_MAX-1, FAKECHROOT_PATH_MAX-1)) == -1) { return -1; } tmp[linksize] = '\0';