printstr_ex: fix decoding of non-NUL-terminated strings when len == -1
Do not treat len == -1 in any special way. All users who need the string to be handled as a NUL-terminated string set QUOTE_0_TERMINATED bit in user_style flags already. * util.c (printstr_ex): Remove (len == -1) check. * tests/printstr.c: New file. * tests/printstr.test: New test. * tests/.gitignore: Add printstr. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add printstr.test.
This commit is contained in:
parent
9af28a4d13
commit
a3c2e4e20b
1
tests/.gitignore
vendored
1
tests/.gitignore
vendored
@ -223,6 +223,7 @@ preadv
|
||||
preadv-pwritev
|
||||
preadv2-pwritev2
|
||||
print_maxfd
|
||||
printstr
|
||||
prlimit64
|
||||
process_vm_readv
|
||||
process_vm_writev
|
||||
|
@ -283,6 +283,7 @@ check_PROGRAMS = \
|
||||
preadv-pwritev \
|
||||
preadv2-pwritev2 \
|
||||
print_maxfd \
|
||||
printstr \
|
||||
prlimit64 \
|
||||
process_vm_readv \
|
||||
process_vm_writev \
|
||||
@ -667,6 +668,7 @@ DECODER_TESTS = \
|
||||
preadv-pwritev.test \
|
||||
preadv2-pwritev2.test \
|
||||
preadv.test \
|
||||
printstr.test \
|
||||
prlimit64.test \
|
||||
process_vm_readv.test \
|
||||
process_vm_writev.test \
|
||||
|
69
tests/printstr.c
Normal file
69
tests/printstr.c
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Check decoding of non-NUL-terminated strings when len == -1.
|
||||
*
|
||||
* 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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#define DEFAULT_STRLEN 32
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char *const buf = tail_alloc(DEFAULT_STRLEN + 1);
|
||||
const struct iovec io = {
|
||||
.iov_base = buf,
|
||||
.iov_len = -1
|
||||
};
|
||||
int rc;
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
tprintf("%s", "");
|
||||
|
||||
memset(buf + 1, 'X', DEFAULT_STRLEN);
|
||||
buf[DEFAULT_STRLEN - 1] = 0;
|
||||
|
||||
rc = writev(-1, &io, 1);
|
||||
tprintf("writev(-1, [{iov_base=\"\\0%*s\\0\"..., iov_len=%lu}], 1)"
|
||||
" = %s\n", DEFAULT_STRLEN - 2, buf + 1, -1UL, sprintrc(rc));
|
||||
|
||||
buf[DEFAULT_STRLEN - 1] = 'X';
|
||||
buf[DEFAULT_STRLEN] = 0;
|
||||
|
||||
rc = writev(-1, &io, 1);
|
||||
tprintf("writev(-1, [{iov_base=\"\\0%*s\"..., iov_len=%lu}], 1)"
|
||||
" = %s\n", DEFAULT_STRLEN - 1, buf + 1, -1UL, sprintrc(rc));
|
||||
|
||||
tprintf("+++ exited with 0 +++\n");
|
||||
return 0;
|
||||
}
|
6
tests/printstr.test
Executable file
6
tests/printstr.test
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Check decoding of non-NUL-terminated strings when len == -1.
|
||||
. "${srcdir=.}/init.sh"
|
||||
|
||||
run_strace_match_diff -e trace=writev
|
25
util.c
25
util.c
@ -850,12 +850,11 @@ printpath(struct tcb *const tcp, const kernel_ureg_t addr)
|
||||
|
||||
/*
|
||||
* Print string specified by address `addr' and length `len'.
|
||||
* If `len' == -1, set QUOTE_0_TERMINATED bit in `user_style'.
|
||||
* If `user_style' has QUOTE_0_TERMINATED bit set, treat the string
|
||||
* as a NUL-terminated string.
|
||||
* Pass `user_style' on to `string_quote'.
|
||||
* Append `...' to the output if either the string length exceeds `max_strlen',
|
||||
* or `len' != -1 and the string length exceeds `len'.
|
||||
* or QUOTE_0_TERMINATED bit is set and the string length exceeds `len'.
|
||||
*/
|
||||
void
|
||||
printstr_ex(struct tcb *const tcp, const kernel_ureg_t addr, const long len,
|
||||
@ -882,22 +881,16 @@ printstr_ex(struct tcb *const tcp, const kernel_ureg_t addr, const long len,
|
||||
outstr = xmalloc(outstr_size);
|
||||
}
|
||||
|
||||
/* Fetch one byte more because string_quote may look one byte ahead. */
|
||||
size = max_strlen + 1;
|
||||
if (len == -1) {
|
||||
/*
|
||||
* Treat as a NUL-terminated string: fetch one byte more
|
||||
* because string_quote may look one byte ahead.
|
||||
*/
|
||||
style |= QUOTE_0_TERMINATED;
|
||||
|
||||
if (size > (unsigned long) len)
|
||||
size = (unsigned long) len;
|
||||
if (style & QUOTE_0_TERMINATED)
|
||||
rc = umovestr(tcp, addr, size, str);
|
||||
} else {
|
||||
if (size > (unsigned long) len)
|
||||
size = (unsigned long) len;
|
||||
if (style & QUOTE_0_TERMINATED)
|
||||
rc = umovestr(tcp, addr, size, str);
|
||||
else
|
||||
rc = umoven(tcp, addr, size, str);
|
||||
}
|
||||
else
|
||||
rc = umoven(tcp, addr, size, str);
|
||||
|
||||
if (rc < 0) {
|
||||
printaddr(addr);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user