[PATCH] Fix {get, set}rlimit decoding with unreliable SIZEOF_RLIM_T
James Hogan
james.hogan at imgtec.com
Tue May 20 22:24:51 UTC 2014
Hi Dmitry,
On 16/05/14 17:02, Dmitry V. Levin wrote:
> On Fri, May 16, 2014 at 12:53:29PM +0100, James Hogan wrote:
>> On 14/05/14 15:17, Dmitry V. Levin wrote:
> [...]
>>> I have two questions wrt this patch:
>>>
>>> 1. Removing the conditional would result with print_rlimit32 defined for
>>> all architectures, including pure 64bit ones. I suppose we need a check
>>> like this anyway:
>>>
>>> #if PERSONALITY0_WORDSIZE == 4 || \
>>> (SUPPORTED_PERSONALITIES > 1 && PERSONALITY1_WORDSIZE == 4) || \
>>> (SUPPORTED_PERSONALITIES > 2 && PERSONALITY2_WORDSIZE == 4)
>>
>> There don't appear to be any arches supported (according to defs.h) with
>>> 2 personalities with all wordsizes the same.
>>
>> Where there are 2 personalities with the same wordsize the definition of
>> current_wordsize takes this into account and defines it as
>> PERSONALITY0_WORDSIZE.
>
> Yes, so the check could be simplified to
> #if !defined(current_wordsize) || current_wordsize == 4
Unfortunately this confuses preprocessor when using this definition:
# define PERSONALITY0_WORDSIZE (int)(sizeof(long))
Maybe with this extra hunk?
diff --git a/defs.h b/defs.h
index 074c8f0..4e06a92 100644
--- 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)
>> So this would seem to allow the compiler to optimise out whichever
>> print_rlimit{32,64} is unused, and a quick look at the x86_64 assembly
>> output (gcc 4.7.3 -O2) with a hacked current_wordsize in resource.c
>> confirms that.
>
> Yes, and some day the compiler will also optimize out decode_rlimit
> because it ends up the same as decode_rlimit64.
> I'd rather not wait when it happens and add the check.
Ah yes, I see the reasoning behind it now :)
>
>> There is of course the "!addr" and "!verbose(tcp || (exiting(tcp) &&
>> syserror(tcp))" conditions which seem to be skipped for the pure 64-bit
>> case at the moment which I'm not sure was intentional anyway?
>
> Hopefully, they are not skipped. I admit these function names
> (sprint_rlim64, print_rlimit64, and decode_rlimit64) are somewhat
> confusing. The last of them does all these top level checks.
Yep, my mistake. I was confusing the functions and reading print_rlimit64.
>
>>> 2. I'm not sure about architectures where kernel wordsize is 8 but user
>>
>>> wordsize is 4 (like x32 and mips n32); what's the correct rlim_t for these
>>> architectures?
>>
>> Hmm, that's a good point.
>>
>> MIPS n32 appears to use the default __kernel_ulong_t define of unsigned
>> long (32bit) so it would work fine I think (although sadly it appears
>> that strace doesn't support personalities on MIPS yet).
>>
>> x32 appears to define __kernel_ulong_t as unsigned long long (64bit), so
>> strace handling of {get,set}rlimit would already appear to be broken for
>> that (this patch doesn't make that any worse).
>
> Thanks. I suppose this patch fixes all these rlim_t issues:
>
> --- a/configure.ac
> +++ b/configure.ac
> @@ -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 |
> --- a/resource.c
> +++ b/resource.c
> @@ -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,22 @@ 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);
> +# ifdef X32
Does this need to take X86_64 into account too, since I presume
personality 1 is X32 too?
Thanks
James
> + 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)
>
>
More information about the Strace-devel
mailing list