Fix printing of inaccessible times argument of utimes and futimesat syscalls

When the whole pair of struct timeval structures cannot be fetched from
tracee's memory, print the address.  This behavior follows the kernel's
that uses copy_from_user for the whole pair, too.

* print_timeval.c (print_timeval_item): Remove.
(print_timeval_pair): Rename to print_timeval_utimes, all callers
updated.  Fetch the whole timeval_t array with a single
umove_or_printaddr call.
* tests/futimesat.c (main): Update expected output.
* tests/utimes.c (main): Likewise.
This commit is contained in:
Дмитрий Левин 2017-04-16 18:13:27 +00:00
parent 589cff6975
commit e5f236d341
4 changed files with 28 additions and 38 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -57,23 +57,19 @@ MPERS_PRINTER_DECL(void, print_timeval,
print_timeval_t(&t);
}
static bool
print_timeval_item(struct tcb *tcp, void *elem_buf, size_t size, void *data)
{
timeval_t *t = elem_buf;
print_timeval_t(t);
return true;
}
MPERS_PRINTER_DECL(void, print_timeval_pair,
MPERS_PRINTER_DECL(void, print_timeval_utimes,
struct tcb *const tcp, const kernel_ulong_t addr)
{
timeval_t t;
timeval_t t[2];
print_array(tcp, addr, 2, &t, sizeof(t), umoven_or_printaddr,
print_timeval_item, NULL);
if (umove_or_printaddr(tcp, addr, &t))
return;
tprints("[");
print_timeval_t(&t[0]);
tprints(", ");
print_timeval_t(&t[1]);
tprints("]");
}
MPERS_PRINTER_DECL(const char *, sprint_timeval,

View File

@ -1,7 +1,7 @@
/*
* Check decoding of futimesat syscall.
*
* Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -45,8 +45,8 @@ main(void)
unsigned long dirfd = (unsigned long) 0xdeadbeef00000000ULL | -100U;
long rc = syscall(__NR_futimesat, dirfd, sample, 0);
printf("futimesat(AT_FDCWD, \"%s\", NULL) = %ld %s (%m)\n",
sample, rc, errno2name());
printf("futimesat(AT_FDCWD, \"%s\", NULL) = %s\n",
sample, sprintrc(rc));
struct timeval *const ts = tail_alloc(sizeof(*ts) * 2);
dirfd = (unsigned long) 0xdeadbeefffffffffULL;
@ -57,22 +57,20 @@ main(void)
ts[1].tv_usec = 678902345;
rc = syscall(__NR_futimesat, dirfd, 0, ts + 2);
printf("futimesat(%d, NULL, %p) = %ld %s (%m)\n",
(int) dirfd, ts + 2, rc, errno2name());
printf("futimesat(%d, NULL, %p) = %s\n",
(int) dirfd, ts + 2, sprintrc(rc));
rc = syscall(__NR_futimesat, dirfd, 0, ts + 1);
printf("futimesat(%d, NULL, [{tv_sec=%jd, tv_usec=%jd}, %p]) = "
"%ld %s (%m)\n", (int) dirfd,
(intmax_t) ts[1].tv_sec, (intmax_t) ts[1].tv_usec,
ts + 2, rc, errno2name());
printf("futimesat(%d, NULL, %p) = %s\n",
(int) dirfd, ts + 1, sprintrc(rc));
(void) close(0);
rc = syscall(__NR_futimesat, 0, "", ts);
printf("futimesat(0, \"\", [{tv_sec=%jd, tv_usec=%jd}, "
"{tv_sec=%jd, tv_usec=%jd}]) = %ld %s (%m)\n",
"{tv_sec=%jd, tv_usec=%jd}]) = %s\n",
(intmax_t) ts[0].tv_sec, (intmax_t) ts[0].tv_usec,
(intmax_t) ts[1].tv_sec, (intmax_t) ts[1].tv_usec,
rc, errno2name());
sprintrc(rc));
puts("+++ exited with 0 +++");
return 0;

View File

@ -1,7 +1,7 @@
/*
* Check decoding of utimes syscall.
*
* Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
* Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -43,8 +43,7 @@ main(void)
static const char sample[] = "utimes_sample";
long rc = syscall(__NR_utimes, sample, 0);
printf("utimes(\"%s\", NULL) = %ld %s (%m)\n",
sample, rc, errno2name());
printf("utimes(\"%s\", NULL) = %s\n", sample, sprintrc(rc));
struct timeval *const ts = tail_alloc(sizeof(*ts) * 2);
@ -54,20 +53,17 @@ main(void)
ts[1].tv_usec = 456789023;
rc = syscall(__NR_utimes, 0, ts + 2);
printf("utimes(NULL, %p) = %ld %s (%m)\n", ts + 2, rc, errno2name());
printf("utimes(NULL, %p) = %s\n", ts + 2, sprintrc(rc));
rc = syscall(__NR_utimes, 0, ts + 1);
printf("utimes(NULL, [{tv_sec=%jd, tv_usec=%jd}, %p]) = "
"%ld %s (%m)\n",
(intmax_t) ts[1].tv_sec, (intmax_t) ts[1].tv_usec,
ts + 2, rc, errno2name());
printf("utimes(NULL, %p) = %s\n", ts + 1, sprintrc(rc));
rc = syscall(__NR_utimes, "", ts);
printf("utimes(\"\", [{tv_sec=%jd, tv_usec=%jd}, "
"{tv_sec=%jd, tv_usec=%jd}]) = %ld %s (%m)\n",
"{tv_sec=%jd, tv_usec=%jd}]) = %s\n",
(intmax_t) ts[0].tv_sec, (intmax_t) ts[0].tv_usec,
(intmax_t) ts[1].tv_sec, (intmax_t) ts[1].tv_usec,
rc, errno2name());
sprintrc(rc));
puts("+++ exited with 0 +++");
return 0;

View File

@ -37,7 +37,7 @@ SYS_FUNC(utimes)
{
printpath(tcp, tcp->u_arg[0]);
tprints(", ");
print_timeval_pair(tcp, tcp->u_arg[1]);
print_timeval_utimes(tcp, tcp->u_arg[1]);
return RVAL_DECODED;
}
@ -47,7 +47,7 @@ SYS_FUNC(futimesat)
print_dirfd(tcp, tcp->u_arg[0]);
printpath(tcp, tcp->u_arg[1]);
tprints(", ");
print_timeval_pair(tcp, tcp->u_arg[2]);
print_timeval_utimes(tcp, tcp->u_arg[2]);
return RVAL_DECODED;
}