[PATCH v3] Implement decoding of ustat syscall
Dmitry V. Levin
ldv at altlinux.org
Sat Jan 7 15:35:55 UTC 2017
On Sat, Jan 07, 2017 at 06:22:44PM +0800, JingPiao Chen wrote:
[...]
> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index 57dd8b9..ceeccd8 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -414,6 +414,7 @@ check_PROGRAMS = \
> utime \
> utimensat \
> utimes \
> + ustat \
> vfork-f \
> vhangup \
> vmsplice \
Please keep this list sorted.
> @@ -796,6 +797,7 @@ DECODER_TESTS = \
> utime.test \
> utimensat.test \
> utimes.test \
> + ustat.test \
> vhangup.test \
> vmsplice.test \
> wait4.test \
Likewise.
[...]
> +#include "tests.h"
> +#include <asm/unistd.h>
> +
> +#ifdef __NR_ustat
> +
> +#include <stdio.h>
Please indent.
> +#include <stdlib.h>
Include <sys/sysmacros.h> instead.
> +#include <unistd.h>
> +#include <ustat.h>
> +
> +int
> +main(int argc, char *argv[])
> +{
> + unsigned int ma = atoi(argv[1]);
> + unsigned int mi = atoi(argv[2]);
> + dev_t dev = makedev(ma, mi);
This is not needed, it's easier to obtain a valid device number without
any external help.
> + kernel_ulong_t magic = (kernel_ulong_t) 0xfacefeedffffffff;
> + struct ustat *ust = tail_alloc(sizeof(*ust));
> +
> + long rc = syscall(__NR_ustat, magic, 0);
> + printf("ustat(makedev(%u, %u), NULL) = %s\n", major((unsigned int) magic),
> + minor((unsigned int) magic), sprintrc(rc));
This looks awkward, try assigning "magic" to a variable of type unsigned int
instead, e.g.
unsigned int dev = (unsigned int) magic;
long rc = syscall(__NR_ustat, magic, 0);
printf("ustat(makedev(%u, %u), NULL) = %s\n",
major(dev), minor(dev), sprintrc(rc));
> + rc = syscall(__NR_ustat, magic, ust);
> + printf("ustat(makedev(%u, %u), %p) = %s\n", major((unsigned int) magic),
> + minor((unsigned int) magic), ust, sprintrc(rc));
Likewise.
At this point you can obtain a valid device number, assign it to "dev",
check for overflow, and proceed with the check for decoding of potentially
successful ustat invocation.
> + rc = syscall(__NR_ustat, dev, ust);
> + printf("ustat(makedev(%u, %u), {f_tfree=%llu, f_tinode=%llu}) = %s\n",
> + ma, mi, zero_extend_signed_to_ull(ust->f_tfree),
> + zero_extend_signed_to_ull(ust->f_tinode), sprintrc(rc));
> +
> + puts("+++ exited with 0 +++");
> + return 0;
> +}
> +
> +#else
> +
> +SKIP_MAIN_UNDEFINED("__NR_ustat")
> +
> +#endif
> diff --git a/tests/ustat.test b/tests/ustat.test
> new file mode 100755
> index 0000000..e7f2867
> --- /dev/null
> +++ b/tests/ustat.test
> @@ -0,0 +1,21 @@
> +#!/bin/sh
> +
> +# Check ustat syscall decoding.
> +
> +. "${srcdir=.}/init.sh"
> +
> +get_fs_dev_t()
> +{
> + name=$(ls /proc/fs/ext4/ | awk '{print $1}')
> + fs_info=$(grep "$name" /proc/diskstats)
> + major=$(echo $fs_info | awk '{print $1}')
> + minor=$(echo $fs_info | awk '{print $2}')
> +}
> +
> +check_prog awk
> +check_prog grep
> +get_fs_dev_t
> +run_prog ./ustat $major $minor > /dev/null
> +run_strace -a25 -eustat ./ustat $major $minor > "$EXP"
> +match_diff "$LOG" "$EXP"
> +rm -f "$EXP" "$LOG"
No, this is too complicated and fragile.
For example, in my test environment
$ ls /proc/fs/ext4/
ls: cannot access /proc/fs/ext4/: No such file or directory
Please revert to the previous edition of ustat.test and obtain
a valid device number inside ustat.c.
> diff --git a/ustat.c b/ustat.c
> new file mode 100644
> index 0000000..988692c
> --- /dev/null
> +++ b/ustat.c
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright (c) 2017 JingPiao Chen <chenjingpiao at gmail.com>
> + * All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + * notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + * notice, this list of conditions and the following disclaimer in the
> + * documentation and/or other materials provided with the distribution.
> + * 3. The name of the author may not be used to endorse or promote products
> + * derived from this software without specific prior written permission.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "defs.h"
> +#include DEF_MPERS_TYPE(struct_ustat)
> +#include <ustat.h>
> +typedef struct ustat struct_ustat;
> +#include MPERS_DEFS
> +
> +SYS_FUNC(ustat)
> +{
> + struct_ustat ust;
Let's move this definition ...
> + if (entering(tcp))
> + print_dev_t((unsigned int) tcp->u_arg[0]);
> + else {
... here.
> + tprints(", ");
> + if (!umove_or_printaddr(tcp, tcp->u_arg[1], &ust))
> + tprintf("{f_tfree=%llu, f_tinode=%llu}",
> + zero_extend_signed_to_ull(ust.f_tfree),
> + zero_extend_signed_to_ull(ust.f_tinode));
> + }
> +
> + return 0;
> +}
--
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 801 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20170107/cfdf3b2e/attachment.bin>
More information about the Strace-devel
mailing list