]> sourceware.org Git - systemtap.git/commitdiff
PR16716 partial fix: Fix 'syscall.{recv,recvfrom}' on 32-bit platforms.
authorDavid Smith <dsmith@redhat.com>
Fri, 28 Mar 2014 19:10:01 +0000 (14:10 -0500)
committerDavid Smith <dsmith@redhat.com>
Fri, 28 Mar 2014 19:10:01 +0000 (14:10 -0500)
* tapset/uconversions.stp (user_ulong): New function.
  (user_ulong_warn): Ditto.
* tapset/linux/syscalls2.stp: Change all calls to user_uint64() to
  user_ulong(), so that 32-bit platforms are handled correctly.
* tapset/linux/nd_syscalls2.stp: Ditto. Also added asmlinkage() calls to
  'nd_syscall.{recv,recvfrom}'.
* testsuite/buildok/conversions-embedded.stp: Added build tests for
  user_ulong() and user_ulong_warn().
* testsuite/buildok/conversions.stp: Ditto.

tapset/linux/nd_syscalls2.stp
tapset/linux/syscalls2.stp
tapset/uconversions.stp
testsuite/buildok/conversions-embedded.stp
testsuite/buildok/conversions.stp

index b3be45acabe56924c669e5530de9cab1a10a359a..e9889d019dbf886c4067344e16445ad9c3d87975 100644 (file)
@@ -921,25 +921,28 @@ probe nd_syscall.recv = __nd_syscall.socketcall.recv ?,
 }
 probe __nd_syscall.socketcall.recv = kprobe.function("sys_socketcall").call ?
 {
+       asmlinkage()
        if (int_arg(1) != %{ SYS_RECV %}) next;
        __args = pointer_arg(2)
-       s = user_int32(&@cast(__args, "ulong")[0])
-       buf_uaddr = user_uint64(&@cast(__args, "ulong")[1])
-       len = user_uint64(&@cast(__args, "ulong")[2])
+       s = user_int(&@cast(__args, "ulong")[0])
+       buf_uaddr = user_ulong(&@cast(__args, "ulong")[1])
+       len = user_ulong(&@cast(__args, "ulong")[2])
        flags = user_uint32(&@cast(__args, "ulong")[3])
 }
 probe __nd_syscall.compat_socketcall.recv =
        kprobe.function("compat_sys_socketcall").call ?
 {
+       asmlinkage()
        if (int_arg(1) != %{ SYS_RECV %}) next;
        __args = pointer_arg(2)
-       s = user_int32(&@cast(__args, "unsigned int")[0])
+       s = user_int(&@cast(__args, "unsigned int")[0])
        buf_uaddr = user_uint32(&@cast(__args, "unsigned int")[1])
        len = user_uint32(&@cast(__args, "unsigned int")[2])
        flags = user_uint32(&@cast(__args, "unsigned int")[3])
 }
 probe __nd_syscall.recv = kprobe.function("sys_recv").call ?
 {
+       asmlinkage()
        @__syscall_gate(%{ __NR_recv %})
        s = int_arg(1)
        buf_uaddr = pointer_arg(2)
@@ -956,7 +959,7 @@ probe __nd_syscall.socketcall.recv.return =
        kprobe.function("sys_socketcall").return ?, 
        kprobe.function("compat_sys_socketcall").return ?
 {
-       if (@entry(int_arg(1)) != %{ SYS_RECV %}) next;
+       if (@entry(__asmlinkage_int_arg(1)) != %{ SYS_RECV %}) next;
 }
 probe __nd_syscall.recv.return = kprobe.function("sys_recv").return ?
 {
@@ -988,21 +991,23 @@ probe nd_syscall.recvfrom = __nd_syscall.socketcall.recvfrom ?,
 probe __nd_syscall.socketcall.recvfrom =
        kprobe.function("sys_socketcall").call ?
 {
+       asmlinkage()
        if (int_arg(1) != %{ SYS_RECVFROM %}) next
        __args = pointer_arg(2)
-       s = user_int32(&@cast(__args, "ulong")[0])
-       buf_uaddr = user_uint64(&@cast(__args, "ulong")[1])
-       len = user_uint64(&@cast(__args, "ulong")[2])
+       s = user_int(&@cast(__args, "ulong")[0])
+       buf_uaddr = user_ulong(&@cast(__args, "ulong")[1])
+       len = user_ulong(&@cast(__args, "ulong")[2])
        flags = user_uint32(&@cast(__args, "ulong")[3])
-       addr_uaddr = user_uint64(&@cast(__args, "ulong")[4])
-       addrlen_uaddr = user_uint64(&@cast(__args, "ulong")[5])
+       addr_uaddr = user_ulong(&@cast(__args, "ulong")[4])
+       addrlen_uaddr = user_ulong(&@cast(__args, "ulong")[5])
 }
 probe __nd_syscall.compat_socketcall.recvfrom =
        kprobe.function("compat_sys_socketcall").call ?
 {
+       asmlinkage()
        if (int_arg(1) != %{ SYS_RECVFROM %}) next
        __args = pointer_arg(2)
-       s = user_int32(&@cast(__args, "unsigned int")[0])
+       s = user_int(&@cast(__args, "unsigned int")[0])
        buf_uaddr = user_uint32(&@cast(__args, "unsigned int")[1])
        len = user_uint32(&@cast(__args, "unsigned int")[2])
        flags = user_uint32(&@cast(__args, "unsigned int")[3])
@@ -1145,7 +1150,7 @@ probe nd_syscall.compat_sys_recvmsg =
        if (int_arg(1) != %{ SYS_RECVMSG %}) next;
        name = "recvmsg"
        __args = pointer_arg(2)
-       s = user_int32(&@cast(__args, "unsigned int")[0])
+       s = user_int(&@cast(__args, "unsigned int")[0])
        msg_uaddr = user_uint32(&@cast(__args, "unsigned int")[1])
        flags = user_uint32(&@cast(__args, "unsigned int")[2])
        flags_str = _msg_flags_str(flags)
index c37e4cb05bc4ed2bbd13899dbe786cfe06309b50..50b8358a4e20648b6df7e648cc305ebc585cd45c 100644 (file)
@@ -973,16 +973,16 @@ probe syscall.recv = __syscall.socketcall.recv ?,
 probe __syscall.socketcall.recv = kernel.function("sys_socketcall").call ?
 {
        if ($call != %{ SYS_RECV %}) next;
-       s = user_int32(&@cast($args, "ulong")[0])
-       buf_uaddr = user_uint64(&@cast($args, "ulong")[1])
-       len = user_uint64(&@cast($args, "ulong")[2])
+       s = user_int(&@cast($args, "ulong")[0])
+       buf_uaddr = user_ulong(&@cast($args, "ulong")[1])
+       len = user_ulong(&@cast($args, "ulong")[2])
        flags = user_uint32(&@cast($args, "ulong")[3])
 }
 probe __syscall.compat_socketcall.recv =
        kernel.function("compat_sys_socketcall").call ?
 {
        if ($call != %{ SYS_RECV %}) next;
-       s = user_int32(&@cast($args, "unsigned int")[0])
+       s = user_int(&@cast($args, "unsigned int")[0])
        buf_uaddr = user_uint32(&@cast($args, "unsigned int")[1])
        len = user_uint32(&@cast($args, "unsigned int")[2])
        flags = user_uint32(&@cast($args, "unsigned int")[3])
@@ -1036,18 +1036,18 @@ probe syscall.recvfrom = __syscall.socketcall.recvfrom ?,
 probe __syscall.socketcall.recvfrom = kernel.function("sys_socketcall").call ?
 {
        if ($call != %{ SYS_RECVFROM %}) next
-       s = user_int32(&@cast($args, "ulong")[0])
-       buf_uaddr = user_uint64(&@cast($args, "ulong")[1])
-       len = user_uint64(&@cast($args, "ulong")[2])
+       s = user_int(&@cast($args, "ulong")[0])
+       buf_uaddr = user_ulong(&@cast($args, "ulong")[1])
+       len = user_ulong(&@cast($args, "ulong")[2])
        flags = user_uint32(&@cast($args, "ulong")[3])
-       addr_uaddr = user_uint64(&@cast($args, "ulong")[4])
-       addrlen_uaddr = user_uint64(&@cast($args, "ulong")[5])
+       addr_uaddr = user_ulong(&@cast($args, "ulong")[4])
+       addrlen_uaddr = user_ulong(&@cast($args, "ulong")[5])
 }
 probe __syscall.compat_socketcall.recvfrom =
        kernel.function("compat_sys_socketcall").call ?
 {
        if ($call != %{ SYS_RECVFROM %}) next
-       s = user_int32(&@cast($args, "unsigned int")[0])
+       s = user_int(&@cast($args, "unsigned int")[0])
        buf_uaddr = user_uint32(&@cast($args, "unsigned int")[1])
        len = user_uint32(&@cast($args, "unsigned int")[2])
        flags = user_uint32(&@cast($args, "unsigned int")[3])
@@ -1182,7 +1182,7 @@ probe syscall.compat_sys_recvmsg =
 {
        if ($call != %{ SYS_RECVMSG %}) next;
        name = "recvmsg"
-       s = user_int32(&@cast($args, "unsigned int")[0])
+       s = user_int(&@cast($args, "unsigned int")[0])
        msg_uaddr = user_uint32(&@cast($args, "unsigned int")[1])
        flags = user_uint32(&@cast($args, "unsigned int")[2])
        flags_str = _msg_flags_str(flags)
index 0980823cc6f01a2c25b414f2d3b0c1486759d7f5..089d0d7e013e5e55c9951fcdf5be2e6c8bde28ce 100644 (file)
@@ -519,6 +519,48 @@ function user_long_warn:long (addr:long) %{ /* pure */ /* myproc-unprivileged */
                STP_GET_USER_WARN(long);
 %}
 
+/**
+ * sfunction user_ulong - Retrieves an unsigned long value stored in user space
+ *
+ * @addr: the user space address to retrieve the unsigned long from
+ *
+ * Description: Returns the unsigned long value from a given user
+ * space address. Returns zero when user space data is not
+ * accessible. Note that the size of the unsigned long depends on the
+ * architecture of the current user space task (for those
+ * architectures that support both 64/32 bit compat tasks).
+ */
+function user_ulong:long (addr:long)
+%{ /* pure */ /* myproc-unprivileged */
+#ifdef CONFIG_COMPAT
+       if (_stp_is_compat_task())
+               STP_GET_USER(compat_ulong_t);
+       else
+#endif
+               STP_GET_USER(unsigned long);
+%}
+
+/**
+ * sfunction user_ulong_warn - Retrieves an unsigned long value stored in user space
+ *
+ * @addr: the user space address to retrieve the unsigned long from
+ *
+ * Description: Returns the unsigned long value from a given user
+ * space address. Returns zero when user space and warns (but does not
+ * abort) about the failure. Note that the size of the unsigned long
+ * depends on the architecture of the current user space task (for
+ * those architectures that support both 64/32 bit compat tasks).
+ */
+function user_ulong_warn:long (addr:long)
+%{ /* pure */ /* myproc-unprivileged */
+#ifdef CONFIG_COMPAT
+       if (_stp_is_compat_task())
+               STP_GET_USER_WARN(compat_ulong_t);
+       else
+#endif
+               STP_GET_USER_WARN(unsigned long);
+%}
+
 /**
  * sfunction user_int8 - Retrieves a 8-bit integer value stored in user space
  *
index 20fd5d3e2f65c56f01e13bce64b535c4be7e19f4..a239c6c3bcd33363061bcc01ce38b96bfce1af66 100755 (executable)
@@ -31,6 +31,8 @@ probe begin {
        print (user_int_warn(0))
        print (user_long(0))
        print (user_long_warn(0))
+       print (user_ulong(0))
+       print (user_ulong_warn(0))
        print (user_char(0))
        print (user_char_warn(0))
 
index 28997947f264cf84187dac8e3eaf526b174f4bab..25bb9546c69ba2087a147776f3c1119ebbe6d490 100755 (executable)
@@ -30,6 +30,8 @@ probe begin {
   print (user_int_warn(2342))
   print (user_long(2342))
   print (user_long_warn(2342))
+  print (user_ulong(2342))
+  print (user_ulong_warn(2342))
   print (user_char(2342))
   print (user_char_warn(2342))
 
This page took 0.045284 seconds and 5 git commands to generate.