Sign extend offset for pwritev/preadv.
Kernel expects a 64 bit offset, so if a
user's offset is 32 bit, the wrapper will
drop the sign. To fix, sign extend the
32 bit value before doing the syscall.
Bug: 31225071
Test: pwritev02 32 bit passes
Change-Id: Ie272601662c2c35b0e8d8fc3823c9063c2f73e64
diff --git a/libc/bionic/legacy_32_bit_support.cpp b/libc/bionic/legacy_32_bit_support.cpp
index 983fb32..ba59e8e 100644
--- a/libc/bionic/legacy_32_bit_support.cpp
+++ b/libc/bionic/legacy_32_bit_support.cpp
@@ -85,13 +85,13 @@
// to implement all four functions because the two system calls don't match any
// of the userspace functions. Unlike llseek, the pair is split lo-hi, not hi-lo.
ssize_t preadv(int fd, const struct iovec* ios, int count, off_t offset) {
- return __preadv64(fd, ios, count, offset, 0);
+ return preadv64(fd, ios, count, offset);
}
ssize_t preadv64(int fd, const struct iovec* ios, int count, off64_t offset) {
return __preadv64(fd, ios, count, offset, offset >> 32);
}
ssize_t pwritev(int fd, const struct iovec* ios, int count, off_t offset) {
- return __pwritev64(fd, ios, count, offset, 0);
+ return pwritev64(fd, ios, count, offset);
}
ssize_t pwritev64(int fd, const struct iovec* ios, int count, off64_t offset) {
return __pwritev64(fd, ios, count, offset, offset >> 32);