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 <enh@google.com>
This commit is contained in:
Дмитрий Левин 2015-03-18 16:32:04 +00:00
parent 8f54664d68
commit babe7f6a30

View File

@ -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 */