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:
parent
589cff6975
commit
e5f236d341
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
4
utimes.c
4
utimes.c
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user