This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] PowerPC64 - Fix INTERNAL_[V]SYSCALL_NCS macros to not castreturn val to (int)


Please consider the following fix.
        
Ryan S. Arnold
IBM Linux Technology Center

2011-02-11  Ryan S. Arnold  <rsa@us.ibm.com>

	* sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile: New file to add
	tst-writev to 'tests' variable.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
	(INTERNAL_VSYSCALL_NCS INTERNAL_SYSCALL_NCS): Remove erroneous (int)
	cast from r3.
	* sysdeps/unix/sysv/linux/powerpc/powerpc64/tst-writev.c: Verify that
	writev() for powerpc64 returns the valid number of written bytes in
	the return value, i.e., make sure the ret val isnt' mangled by the
	syscall wrapper.

commit 6783e2135c4b24b560388593727158a3d5bdfe75
Author: Ryan Arnold <ryanarn@etna.rchland.ibm.com>
Date:   Fri Feb 11 11:23:42 2011 -0600

    Remove erroneous (int) cast from PowerPC64 INTERNAL_SYSCALL macros.

    The PowerPC64 implementation of INTERNAL_VSYSCALL_NCS and INTERNAL_SYSCALL_NCS
    erroneously cast the return value held in r3 to (int).  Normally this wasn't a
    problem but for syscalls wrappers that require a ssize_t return, like writev()
    this bug would mangle the high half word of the return value and even
    erroneously sign-extend the high half word if the sign-bit of the low half
    word was '1'.

diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile
new file mode 100644
index 0000000..9903f51
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/Makefile
@@ -0,0 +1,6 @@
+ifeq ($(subdir),misc)
+tests += tst-writev
+
+# Time enough for a large writev syscall to complete.
+tst-writev-ENV = TIMEOUTFACTOR="10"
+endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
index aab4b72..e714c4c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
@@ -172,7 +172,7 @@
        : "r9", "r10", "r11", "r12",					\
          "cr0", "ctr", "lr", "memory");					\
 	  err = (long int) r0;						\
-    (int) r3;								\
+    r3;								\
   })
 
 #undef INLINE_SYSCALL
@@ -219,7 +219,7 @@
        : "r9", "r10", "r11", "r12",					\
          "cr0", "ctr", "memory");					\
 	  err = r0;  \
-    (int) r3;  \
+    r3;  \
   })
 #define INTERNAL_SYSCALL(name, err, nr, args...)			\
   INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, args)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/tst-writev.c b/sysdeps/unix/sysv/linux/powerpc/powerpc64/tst-writev.c
new file mode 100644
index 0000000..7848aa1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/tst-writev.c
@@ -0,0 +1,36 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/uio.h>
+
+/* The purpose of this test is to verify that the powerpc64 INTERNAL_SYSCALL_NCS
+ * macro for powerpc64 doesn't cast the return type to (int) which would
+ * erroneously sign extend the return value should the high bit of the bottom
+ * half of the word be '1'.  */
+
+#define bufsz (unsigned long)(0x1l << 31)
+
+static int
+do_test (void)
+{
+  struct iovec iv[1];
+  ssize_t ret;
+
+  /* Write a bunch of junk to /dev/null with the writev syscall in order to get
+   * a return of 0x8000000 bytes to verify that the INTERNAL_SYSCALL wrappers
+   * aren't mangling the result if the signbit of a 32-bit number is set.  */
+  (void) freopen ("/dev/null", "a", stderr);
+
+   iv[0].iov_base = malloc(bufsz);
+   iv[0].iov_len = bufsz;
+
+   /* Write it out to stderr and it'll get dumped into /dev/null.  */
+   ret = writev(2, iv, 1);
+   if (ret != 0x80000000) {
+     fprintf(stdout, "ret = %lu\n", ret);
+     return ret;
+   }
+   return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]