Fix {get,set}rlimit decoding with unreliable SIZEOF_RLIM_T
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>
diff --git a/configure.ac b/configure.ac
index 0969173..e5c837b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -309,7 +309,6 @@
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 074c8f0..4e06a92 100644
--- a/defs.h
+++ b/defs.h
@@ -370,7 +370,7 @@
# 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)
diff --git a/resource.c b/resource.c
index 5f92b39..b62f631 100644
--- a/resource.c
+++ b/resource.c
@@ -88,10 +88,6 @@
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 @@
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 @@
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)