From: Dmitry V. Levin Date: Wed, 18 Mar 2015 16:32:04 +0000 (+0000) Subject: aarch64, arm: decode extra padded compat struct statfs64 X-Git-Tag: v4.11~567 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=babe7f6a30d3d7061b94299f41e338000737abf3;p=strace aarch64, arm: decode extra padded compat struct statfs64 According to arch/arm/kernel/sys_oabi-compat.c, struct statfs64 has extra padding with EABI. * statfs.c [AARCH64 || defined ARM] (COMPAT_STATFS64_PADDED_SIZE): Define. (do_statfs64_fstatfs64): New function, factored out from sys_statfs64. [COMPAT_STATFS64_PADDED_SIZE]: Check it in addition to sizeof(struct compat_statfs64). (sys_statfs64, sys_fstatfs64): Use do_statfs64_fstatfs64. Reported-and-tested-by: Elliott Hughes --- diff --git a/statfs.c b/statfs.c index f1e9fc38..214e6b2a 100644 --- a/statfs.c +++ b/statfs.c @@ -128,6 +128,10 @@ struct compat_statfs64 { __attribute__ ((packed, aligned(4))) #endif ; +#if defined AARCH64 || defined ARM +/* See arch/arm/kernel/sys_oabi-compat.c for details. */ +# define COMPAT_STATFS64_PADDED_SIZE (sizeof(struct compat_statfs64) + 4) +#endif static void printcompat_statfs64(struct tcb *tcp, const long addr) @@ -157,16 +161,19 @@ printcompat_statfs64(struct tcb *tcp, const long addr) tprintf(", f_flags=%lu}", (unsigned long)statbuf.f_frsize); } -int -sys_statfs64(struct tcb *tcp) +static int +do_statfs64_fstatfs64(struct tcb *tcp) { if (entering(tcp)) { - printpath(tcp, tcp->u_arg[0]); tprintf(", %lu, ", tcp->u_arg[1]); } else { if (tcp->u_arg[1] == sizeof(struct statfs64)) printstatfs64(tcp, tcp->u_arg[2]); - else if (tcp->u_arg[1] == sizeof(struct compat_statfs64)) + else if (tcp->u_arg[1] == sizeof(struct compat_statfs64) +#ifdef COMPAT_STATFS64_PADDED_SIZE + || tcp->u_arg[1] == COMPAT_STATFS64_PADDED_SIZE +#endif + ) printcompat_statfs64(tcp, tcp->u_arg[2]); else tprints("{???}"); @@ -174,21 +181,20 @@ sys_statfs64(struct tcb *tcp) return 0; } +int +sys_statfs64(struct tcb *tcp) +{ + if (entering(tcp)) + printpath(tcp, tcp->u_arg[0]); + return do_statfs64_fstatfs64(tcp); +} + int sys_fstatfs64(struct tcb *tcp) { - if (entering(tcp)) { + if (entering(tcp)) printfd(tcp, tcp->u_arg[0]); - tprintf(", %lu, ", tcp->u_arg[1]); - } else { - if (tcp->u_arg[1] == sizeof(struct statfs64)) - printstatfs64(tcp, tcp->u_arg[2]); - else if (tcp->u_arg[1] == sizeof(struct compat_statfs64)) - printcompat_statfs64(tcp, tcp->u_arg[2]); - else - tprints("{???}"); - } - return 0; + return do_statfs64_fstatfs64(tcp); } #endif /* HAVE_STRUCT_STATFS64 */