Fix {get,set}rlimit decoding with unreliable SIZEOF_RLIM_T
authorJames Hogan <james.hogan@imgtec.com>
Fri, 2 May 2014 13:15:41 +0000 (14:15 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 21 May 2014 00:22:07 +0000 (00:22 +0000)
When strace is built with large file support definitions in CFLAGS (as
may be provided by buildroot) the C library headers may expose a 64-bit
rlim_t even though the struct rlimit fields used by the system call
interface are only 32-bit.  The SIZEOF_RLIM_T will then be 8 which
results in bad decoding of the getrlimit and setrlimit syscalls.

This is fixed by replacing unreliable SIZEOF_RLIM_T based checks with
checks for current_wordsize.

Signed-off-by: James Hogan <james.hogan@imgtec.com>
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
configure.ac
defs.h
resource.c

index 09691738aefe3cd80fe51b4451c8e96b8311245b..e5c837b8a50ec88a7bb54564464033e595b85b6c 100644 (file)
@@ -309,7 +309,6 @@ AC_CACHE_CHECK([for BLKGETSIZE64], [ac_cv_have_blkgetsize64],
 AC_CHECK_SIZEOF([long])
 AC_CHECK_SIZEOF([long long])
 AC_CHECK_SIZEOF([off_t],,[#include <sys/types.h>])
-AC_CHECK_SIZEOF([rlim_t],,[#include <sys/resource.h>])
 
 AC_CACHE_CHECK([for SA_RESTORER], [st_cv_sa_restorer],
               [st_cv_sa_restorer="$(echo SA_RESTORER |
diff --git a/defs.h b/defs.h
index 074c8f0b831a19f619202056610663122b415f59..4e06a92a5986d7bfdc698b2a61668bc7f5bbf965 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -370,7 +370,7 @@ struct arm_pt_regs {
 # define DEFAULT_PERSONALITY 0
 #endif
 #ifndef PERSONALITY0_WORDSIZE
-# define PERSONALITY0_WORDSIZE (int)(sizeof(long))
+# define PERSONALITY0_WORDSIZE SIZEOF_LONG
 #endif
 
 #if defined(I386) || defined(X86_64)
index 5f92b39fd21a62b3001b5844f4fd17a7e27a4ec9..b62f631677f98b9da0b187bb7e3bf47d7b82ff16 100644 (file)
@@ -88,10 +88,6 @@ static const struct xlat resources[] = {
        XLAT_END
 };
 
-#if !(SIZEOF_RLIM_T == 4 || SIZEOF_RLIM_T == 8)
-# error "Unsupported SIZEOF_RLIM_T value"
-#endif
-
 static const char *
 sprint_rlim64(uint64_t lim)
 {
@@ -135,7 +131,7 @@ decode_rlimit64(struct tcb *tcp, unsigned long addr)
                print_rlimit64(tcp, addr);
 }
 
-#if SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1
+#if !defined(current_wordsize) || current_wordsize == 4
 
 static const char *
 sprint_rlim32(uint32_t lim)
@@ -176,22 +172,28 @@ decode_rlimit(struct tcb *tcp, unsigned long addr)
        else if (!verbose(tcp) || (exiting(tcp) && syserror(tcp)))
                tprintf("%#lx", addr);
        else {
-# if SIZEOF_RLIM_T == 4
-               print_rlimit32(tcp, addr);
+# if defined(X86_64) || defined(X32)
+               /*
+                * i386 is the only personality on X86_64 and X32
+                * with 32-bit rlim_t.
+                * When current_personality is X32, current_wordsize
+                * equals to 4 but rlim_t is 64-bit.
+                */
+               if (current_personality == 1)
 # else
                if (current_wordsize == 4)
+# endif
                        print_rlimit32(tcp, addr);
                else
                        print_rlimit64(tcp, addr);
-# endif
        }
 }
 
-#else /* SIZEOF_RLIM_T == 8 && SUPPORTED_PERSONALITIES == 1 */
+#else /* defined(current_wordsize) && current_wordsize != 4 */
 
 # define decode_rlimit decode_rlimit64
 
-#endif /* SIZEOF_RLIM_T == 4 || SUPPORTED_PERSONALITIES > 1 */
+#endif
 
 int
 sys_getrlimit(struct tcb *tcp)