Fix printing of negative offsets in pread64 and pwrite64 syscalls

* io.c (SYS_FUNC(pread), SYS_FUNC(pwrite)): Print offset
using %lld format string.
* tests/pread64-pwrite64.c: New file.
* tests/pread64-pwrite64.test: New test.
* tests/.gitignore: Add pread64-pwrite64.
* tests/Makefile.am (check_PROGRAMS): Likewise.
(pread64_pwrite64_CPPFLAGS): New variable.
(DECODER_TESTS): Add pread64-pwrite64.
This commit is contained in:
Дмитрий Левин 2016-04-02 01:08:24 +00:00
parent 69f1bf37fd
commit 9f3a6af09a
5 changed files with 181 additions and 2 deletions

4
io.c
View File

@ -169,7 +169,7 @@ SYS_FUNC(pread)
else
printstr(tcp, tcp->u_arg[1], tcp->u_rval);
tprintf(", %lu, ", tcp->u_arg[2]);
printllval(tcp, "%llu", PREAD_OFFSET_ARG);
printllval(tcp, "%lld", PREAD_OFFSET_ARG);
}
return 0;
}
@ -180,7 +180,7 @@ SYS_FUNC(pwrite)
tprints(", ");
printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
tprintf(", %lu, ", tcp->u_arg[2]);
printllval(tcp, "%llu", PREAD_OFFSET_ARG);
printllval(tcp, "%lld", PREAD_OFFSET_ARG);
return RVAL_DECODED;
}

1
tests/.gitignore vendored
View File

@ -92,6 +92,7 @@ personality
pipe
poll
ppoll
pread64-pwrite64
preadv
preadv-pwritev
pselect6

View File

@ -141,6 +141,7 @@ check_PROGRAMS = \
pipe \
poll \
ppoll \
pread64-pwrite64 \
preadv \
preadv-pwritev \
pselect6 \
@ -229,6 +230,7 @@ mmap64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
mq_LDADD = -lrt $(LDADD)
newfstatat_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
pc_LDADD = $(dl_LIBS) $(LDADD)
pread64_pwrite64_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
preadv_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
preadv_pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
pwritev_CPPFLAGS = $(AM_CPPFLAGS) -D_FILE_OFFSET_BITS=64
@ -323,6 +325,7 @@ DECODER_TESTS = \
pipe.test \
poll.test \
ppoll.test \
pread64-pwrite64.test \
preadv.test \
preadv-pwritev.test \
pselect6.test \

157
tests/pread64-pwrite64.c Normal file
View File

@ -0,0 +1,157 @@
/*
* Check decoding of pread64 and pwrite64 syscalls.
*
* Copyright (c) 2016 Dmitry V. Levin <ldv@altlinux.org>
* 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 "tests.h"
#include <fcntl.h>
#include <stdio.h>
#include <sys/uio.h>
#include <unistd.h>
int
main(void)
{
tprintf("%s", "");
static char tmp[] = "pread64-pwrite64-tmpfile";
if (open(tmp, O_CREAT|O_RDONLY|O_TRUNC, 0600) != 0)
perror_msg_and_fail("creat: %s", tmp);
if (open(tmp, O_WRONLY) != 1)
perror_msg_and_fail("open: %s", tmp);
char *nil = tail_alloc(1);
*nil = '\0';
static const char w_c[] = "0123456789abcde";
const unsigned int w_len = LENGTH_OF(w_c);
const char *w_d = hexdump_strdup(w_c);
const void *w = tail_memdup(w_c, w_len);
static const char r0_c[] = "01234567";
const char *r0_d = hexdump_strdup(r0_c);
const unsigned int r0_len = (w_len + 1) / 2;
void *r0 = tail_alloc(r0_len);
static const char r1_c[] = "89abcde";
const char *r1_d = hexdump_strdup(r1_c);
const unsigned int r1_len = w_len - r0_len;
void *r1 = tail_alloc(w_len);
void *efault = r1 - get_page_size();
long rc;
rc = pwrite(1, w, 0, 0);
if (rc)
perror_msg_and_fail("pwrite64: expected 0, returned %ld", rc);
tprintf("pwrite64(1, \"\", 0, 0) = 0\n");
rc = pwrite(1, w, w_len + 1, 0);
if (rc != -1)
perror_msg_and_fail("pwrite64: expected -1 EFAULT"
", returned %ld", rc);
tprintf("pwrite64(1, %p, %u, 0) = -1 EFAULT (%m)\n",
w, w_len + 1);
rc = pwrite(1, nil, 1, -3);
if (rc != -1)
perror_msg_and_fail("pwrite64: expected -1, returned %ld", rc);
tprintf("pwrite64(1, \"\\0\", 1, -3) = -1 EINVAL (%m)\n");
rc = pwrite(1, w, w_len, 0);
if (rc != (int) w_len)
perror_msg_and_fail("pwrite64: expected %u, returned %ld",
w_len, rc);
tprintf("pwrite64(1, \"%s\", %u, 0) = %ld\n"
" | 00000 %-49s %-16s |\n",
w_c, w_len, rc, w_d, w_c);
close(1);
rc = pread(0, efault, 1, 0);
if (rc != -1)
perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
tprintf("pread64(0, %p, 1, 0) = -1 EFAULT (%m)\n", efault);
rc = pread(0, efault, 2, -7);
if (rc != -1)
perror_msg_and_fail("pread64: expected -1, returned %ld", rc);
tprintf("pread64(0, %p, 2, -7) = -1 EINVAL (%m)\n", efault);
rc = pread(0, r0, r0_len, 0);
if (rc != (int) r0_len)
perror_msg_and_fail("pread64: expected %u, returned %ld",
r0_len, rc);
tprintf("pread64(0, \"%s\", %u, 0) = %ld\n"
" | 00000 %-49s %-16s |\n",
r0_c, r0_len, rc, r0_d, r0_c);
rc = pread(0, r1, w_len, r0_len);
if (rc != (int) r1_len)
perror_msg_and_fail("pread64: expected %u, returned %ld",
r1_len, rc);
tprintf("pread64(0, \"%s\", %u, %u) = %ld\n"
" | 00000 %-49s %-16s |\n",
r1_c, w_len, r0_len, rc, r1_d, r1_c);
close(0);
const off_t offset = 0xdefaceddeadbeefLL;
const int rw_len = 8;
char *rw_buf = tail_alloc(rw_len);
if (open("/dev/zero", O_RDONLY))
perror_msg_and_fail("open");
rc = pread(0, rw_buf, rw_len, offset);
if (rc != rw_len)
perror_msg_and_fail("pread64: expected %d, returned %ld",
rw_len, rc);
tprintf("%s(%d, \"%s\", %d, %lld) = %ld\n"
" | 00000 %-49s %-16s |\n",
"pread64", 0, "\\0\\0\\0\\0\\0\\0\\0\\0",
rw_len, (long long) offset, rc,
" 00 00 00 00 00 00 00 00", "........");
if (open("/dev/null", O_WRONLY) != 1)
perror_msg_and_fail("open");
rc = pwrite(1, rw_buf, rw_len, offset);
if (rc != rw_len)
perror_msg_and_fail("pwrite64: expected %d, returned %ld",
rw_len, rc);
tprintf("%s(%d, \"%s\", %d, %lld) = %ld\n"
" | 00000 %-49s %-16s |\n",
"pwrite64", 1, "\\0\\0\\0\\0\\0\\0\\0\\0",
rw_len, (long long) offset, rc,
" 00 00 00 00 00 00 00 00", "........");
tprintf("+++ exited with 0 +++\n");
return 0;
}

18
tests/pread64-pwrite64.test Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
# Check decoding and dumping of pread64 and pwrite64 syscalls.
. "${srcdir=.}/init.sh"
# strace -P is implemented using /proc/self/fd
[ -d /proc/self/fd/ ] ||
framework_skip_ '/proc/self/fd/ is not available'
tmpfile=pread64-pwrite64-tmpfile
> $tmpfile
run_strace_match_diff \
-a22 -eread=0 -ewrite=1 -e trace=pread64,pwrite64 \
-P $tmpfile -P /dev/zero -P /dev/null
rm -f $tmpfile