mem.c: introduce fetch_old_mmap_args

Move common old_mmap/old_mmap_pgoff argument fetching code into a
separate function.

As it is, it also fixes the case of non-verbose printing of old_mmap
arguments (see the new test in the next commit).  Also, it is a
preparation for the fix of path tracing for these syscalls.

* defs.h [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New prototype.
* mem.c [HAVE_ARCH_OLD_MMAP] (fetch_old_mmap_args): New function.
[HAVE_ARCH_OLD_MMAP] (old_mmap, old_mmap_pgoff): Use it.

Fixes: 3db07f11 "Fix old_mmap output when mmap arguments are unfetchable"
Suggested-by: Dmitry V. Levin <ldv@altlinux.org>
This commit is contained in:
Eugene Syromyatnikov 2018-01-17 02:18:45 +01:00 committed by Dmitry V. Levin
parent 408ce203da
commit 52314cc9a4
2 changed files with 45 additions and 24 deletions

4
defs.h
View File

@ -575,6 +575,10 @@ extern void print_numeric_long_umask(unsigned long);
extern void print_dev_t(unsigned long long dev);
extern void print_abnormal_hi(kernel_ulong_t);
#ifdef HAVE_ARCH_OLD_MMAP
extern kernel_ulong_t *fetch_old_mmap_args(struct tcb *tcp);
#endif
extern void
dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size);

65
mem.c
View File

@ -108,47 +108,64 @@ print_mmap(struct tcb *tcp, kernel_ulong_t *u_arg, unsigned long long offset)
*/
#ifdef HAVE_ARCH_OLD_MMAP
/* Params are pointed to by u_arg[0], offset is in bytes */
SYS_FUNC(old_mmap)
/**
* Fetch old_mmap/old_mmap_pgoff arguments that are provided as a 6-element
* array. Return pointer to a static array or NULL in case of fetch failure.
*/
kernel_ulong_t *
fetch_old_mmap_args(struct tcb *tcp)
{
kernel_ulong_t u_arg[6];
static kernel_ulong_t u_arg[6];
# if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
/* We are here only in a 32-bit personality. */
unsigned int narrow_arg[6];
if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
return RVAL_DECODED | RVAL_HEX;
unsigned int i;
for (i = 0; i < 6; i++)
if (umove(tcp, tcp->u_arg[0], &narrow_arg))
return NULL;
for (unsigned int i = 0; i < 6; i++)
u_arg[i] = narrow_arg[i];
# else
if (umove_or_printaddr(tcp, tcp->u_arg[0], &u_arg))
return RVAL_DECODED | RVAL_HEX;
if (umove(tcp, tcp->u_arg[0], &u_arg))
return NULL;
# endif
print_mmap(tcp, u_arg, u_arg[5]);
return u_arg;
}
/* Params are pointed to by u_arg[0], offset is in bytes */
SYS_FUNC(old_mmap)
{
kernel_ulong_t *args = fetch_old_mmap_args(tcp);
if (args)
print_mmap(tcp, args, args[5]);
else
printaddr(tcp->u_arg[0]);
return RVAL_DECODED | RVAL_HEX;
}
#endif /* HAVE_ARCH_OLD_MMAP */
#ifdef S390
# ifdef S390
/* Params are pointed to by u_arg[0], offset is in pages */
SYS_FUNC(old_mmap_pgoff)
{
kernel_ulong_t u_arg[5];
int i;
unsigned int narrow_arg[6];
unsigned long long offset;
if (umove_or_printaddr(tcp, tcp->u_arg[0], &narrow_arg))
return RVAL_DECODED | RVAL_HEX;
for (i = 0; i < 5; i++)
u_arg[i] = narrow_arg[i];
offset = narrow_arg[5];
offset *= get_pagesize();
print_mmap(tcp, u_arg, offset);
kernel_ulong_t *args = fetch_old_mmap_args(tcp);
if (args) {
unsigned long long offset;
offset = args[5];
offset *= get_pagesize();
print_mmap(tcp, args, offset);
} else {
printaddr(tcp->u_arg[0]);
}
return RVAL_DECODED | RVAL_HEX;
}
#endif /* S390 */
# endif /* S390 */
#endif /* HAVE_ARCH_OLD_MMAP */
/* Params are passed directly, offset is in bytes */
SYS_FUNC(mmap)