Arguments offset and len in fallocate system call in Linux
kernel have 64-bit types. However these arguments in fallocate
wrapper in uClibc may have 32-bit types. In this case it's
necessary to pass two 32-bit words to the systemc call for every
argument - an actual argument and its sign extension.

Thus high word of 64-bit value must be 0 or 0xFFFFFFFF depending
on sign of the original 32-bit value (offset or len). It is how
sign extansion works - all high bits of the negative value must be 1.

fallocate does sign extension incorrectly when 32 bit values are
passed (offset or len). It just fills the second word of 64-bit
value by zeros. E.g. fallocate works incorrectly when offset or
length is negative value - in this case kernel thinks that positive
values are passed.

Signed-off-by: Yuriy Kolerov <[email protected]>
---
 libc/sysdeps/linux/common/fallocate.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/libc/sysdeps/linux/common/fallocate.c 
b/libc/sysdeps/linux/common/fallocate.c
index b2309e9..446d9ef 100644
--- a/libc/sysdeps/linux/common/fallocate.c
+++ b/libc/sysdeps/linux/common/fallocate.c
@@ -21,14 +21,12 @@ int attribute_hidden __libc_fallocate(int fd, int mode, 
__off_t offset, __off_t
        int ret;
 
 # if __WORDSIZE == 32
-       uint32_t off_low = offset;
-       uint32_t len_low = len;
-       /* may assert that these >>31 are 0 */
-       uint32_t zero = 0;
+       int32_t offset_sign_extension = (offset < 0) ? 0xFFFFFFFF : 0;
+       int32_t len_sign_extension = (len < 0) ? 0xFFFFFFFF : 0;
        INTERNAL_SYSCALL_DECL(err);
        ret = (int) (INTERNAL_SYSCALL(fallocate, err, 6, fd, mode,
-               __LONG_LONG_PAIR (zero, off_low),
-               __LONG_LONG_PAIR (zero, len_low)));
+               __LONG_LONG_PAIR (offset_sign_extension, offset),
+               __LONG_LONG_PAIR (len_sign_extension, len)));
 # elif __WORDSIZE == 64
        INTERNAL_SYSCALL_DECL(err);
        ret = (int) (INTERNAL_SYSCALL(fallocate, err, 4, fd, mode, offset, 
len));
-- 
2.2.0

_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to