Introduce print_quoted_cstring

In many places where kernel expects a NUL-terminated string of length
up to a known fixed limit, e.g. when a NUL-terminated string is
a fixed-size field of a structure, strace does not print the last byte
assuming it is NUL, which is not always the case.

Change output format for such strings to distinguish NUL-terminated
strings from non-NUL-terminated ones: append ellipsis to the output
when the string is not NUL-terminated.

* defs.h (print_quoted_cstring): New prototype.
* util.c (print_quoted_cstring): New function.
(printpathn): Use it instead of print_quoted_string with
QUOTE_0_TERMINATED argument.
* print_fields.h (PRINT_FIELD_CSTRING): Likewise.
* btrfs.c (btrfs_ioctl): Likewise.
* dirent.c (SYS_FUNC(getdents)): Likewise.
* dirent64.c (SYS_FUNC(getdents64)): Likewise.
* print_ifindex.c (print_ifindex): Likewise.
* sysmips.c (SYS_FUNC(sysmips)): Likewise.
* ubi.c (ubi_ioctl): Likewise.
* tests/tests.h (print_quoted_cstring): New prototype.
* tests/print_quoted_string.c (print_quoted_cstring): New function.
* tests/ioctl_block.c (main): Update expected output.
* tests/ioctl_dm.c (main): Likewise.
* tests/ioctl_loop.c (print_loop_info, print_loop_info64): Likewise.
* tests/netlink_crypto.c (test_crypto_msg_newalg): Likewise.
This commit is contained in:
Дмитрий Левин 2017-07-24 12:10:54 +00:00
parent 53a56aa0d8
commit de484eced5
15 changed files with 66 additions and 48 deletions

12
btrfs.c
View File

@ -680,14 +680,12 @@ MPERS_PRINTER_DECL(int, btrfs_ioctl,
(uint64_t) args.start.cont_reading_from_srcdev_mode);
str = (const char *) args.start.srcdev_name;
print_quoted_string(str,
sizeof(args.start.srcdev_name),
QUOTE_0_TERMINATED);
print_quoted_cstring(str,
sizeof(args.start.srcdev_name));
tprints(", tgtdev_name=");
str = (const char *) args.start.tgtdev_name;
print_quoted_string(str,
sizeof(args.start.tgtdev_name),
QUOTE_0_TERMINATED);
print_quoted_cstring(str,
sizeof(args.start.tgtdev_name));
tprints("}");
}
@ -1327,7 +1325,7 @@ MPERS_PRINTER_DECL(int, btrfs_ioctl,
tprints(", ");
if (umove_or_printaddr(tcp, arg, &label))
break;
print_quoted_string(label, sizeof(label), QUOTE_0_TERMINATED);
print_quoted_cstring(label, sizeof(label));
break;
}

1
defs.h
View File

@ -556,6 +556,7 @@ str_strip_prefix_len(const char *str, const char *prefix, size_t prefix_len)
extern int string_quote(const char *, char *, unsigned int, unsigned int);
extern int print_quoted_string(const char *, unsigned int, unsigned int);
extern int print_quoted_cstring(const char *, unsigned int);
/* a refers to the lower numbered u_arg,
* b refers to the higher numbered u_arg

View File

@ -132,10 +132,7 @@ SYS_FUNC(getdents)
zero_extend_signed_to_ull(d->d_off),
d->d_reclen);
if (print_quoted_string(d->d_name, d_name_len,
QUOTE_0_TERMINATED) > 0) {
tprints("...");
}
print_quoted_cstring(d->d_name, d_name_len);
tprints(", d_type=");
if (oob)

View File

@ -105,10 +105,7 @@ SYS_FUNC(getdents64)
printxval(dirent_types, d->d_type, "DT_???");
tprints(", d_name=");
if (print_quoted_string(d->d_name, d_name_len,
QUOTE_0_TERMINATED) > 0) {
tprints("...");
}
print_quoted_cstring(d->d_name, d_name_len);
tprints("}");
}

View File

@ -93,9 +93,8 @@
#define PRINT_FIELD_CSTRING(prefix_, where_, field_) \
do { \
STRACE_PRINTF("%s%s=", (prefix_), #field_); \
print_quoted_string((const char *)(where_).field_, \
sizeof((where_).field_), \
QUOTE_0_TERMINATED); \
print_quoted_cstring((const char *)(where_).field_, \
sizeof((where_).field_)); \
} while (0)
#define PRINT_FIELD_INET_ADDR(prefix_, where_, field_, af_) \

View File

@ -36,7 +36,7 @@ print_ifindex(const unsigned int ifindex)
if (if_indextoname(ifindex, buf)) {
tprints("if_nametoindex(");
print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
print_quoted_cstring(buf, sizeof(buf));
tprints(")");
return;
}

View File

@ -59,8 +59,7 @@ SYS_FUNC(sysmips)
nodename) < 0) {
printaddr(tcp->u_arg[1]);
} else {
print_quoted_string(nodename, __NEW_UTS_LEN + 1,
QUOTE_0_TERMINATED);
print_quoted_cstring(nodename, __NEW_UTS_LEN + 1);
}
return RVAL_DECODED;
}

View File

@ -171,7 +171,7 @@ main(void)
ioctl(-1, BLKPG, blkpg);
printf("ioctl(-1, BLKPG, {op=%s, flags=%d, datalen=%d"
", data={start=%lld, length=%lld, pno=%d"
", devname=\"%.*s\", volname=\"%.*s\"}})"
", devname=\"%.*s\"..., volname=\"%.*s\"...}})"
" = -1 EBADF (%m)\n",
"BLKPG_ADD_PARTITION",
blkpg->flags, blkpg->datalen,

View File

@ -251,7 +251,7 @@ main(void)
strncpy(dm_arg->uuid, str129, sizeof(dm_arg->uuid));
ioctl(-1, DM_VERSION, dm_arg);
printf("ioctl(-1, DM_VERSION, {version=4.1.2, data_size=%zu, "
"dev=makedev(18, 52), name=\"%.127s\", uuid=\"%.128s\", "
"dev=makedev(18, 52), name=\"%.127s\"..., uuid=\"%.128s\"..., "
"flags=0}) = -1 EBADF (%m)\n",
min_sizeof_dm_ioctl, str129, str129);

View File

@ -39,6 +39,7 @@
#include <sys/sysmacros.h>
#include <linux/ioctl.h>
#include <linux/loop.h>
#include "print_fields.h"
#include "xlat/loop_cmds.h"
#ifndef ABBREV
@ -81,8 +82,7 @@ print_loop_info(struct loop_info * const info, bool print_encrypt,
else
printf("%#x /* LO_FLAGS_??? */", info->lo_flags);
printf(", lo_name=\"%.*s\"",
(int) sizeof(info->lo_name) - 1, info->lo_name);
PRINT_FIELD_CSTRING(", ", *info, lo_name);
if (VERBOSE || print_encrypt)
printf(", lo_encrypt_key=\"%.*s\"",
@ -144,17 +144,16 @@ print_loop_info64(struct loop_info64 * const info64, bool print_encrypt,
printf("%s", flags);
else
printf("%#x /* LO_FLAGS_??? */", info64->lo_flags);
printf(", lo_file_name=\"%.*s\"",
(int) sizeof(info64->lo_file_name) - 1, info64->lo_file_name);
PRINT_FIELD_CSTRING(", ", *info64, lo_file_name);
if (VERBOSE || print_encrypt)
printf(", lo_crypt_name=\"%.*s\", lo_encrypt_key=\"%.*s\"",
(int) sizeof(info64->lo_crypt_name) - 1,
info64->lo_crypt_name,
if (VERBOSE || print_encrypt) {
PRINT_FIELD_CSTRING(", ", *info64, lo_crypt_name);
printf(", lo_encrypt_key=\"%.*s\"",
encrypt_key ? (int) strlen(encrypt_key) :
(int) sizeof(info64->lo_encrypt_key),
encrypt_key ? encrypt_key :
(char *) info64->lo_encrypt_key);
}
# if VERBOSE
printf(", lo_init=[%#" PRIx64 ", %#" PRIx64 "]}",

View File

@ -125,13 +125,13 @@ test_crypto_msg_newalg(const int fd)
printf("{cru_name=");
print_quoted_memory(alg.cru_name,
sizeof(alg.cru_name) - 1);
printf(", cru_driver_name=");
printf("..., cru_driver_name=");
print_quoted_memory(alg.cru_driver_name,
sizeof(alg.cru_driver_name) - 1);
printf(", cru_module_name=");
printf("..., cru_module_name=");
print_quoted_memory(alg.cru_module_name,
sizeof(alg.cru_module_name) - 1);
PRINT_FIELD_X(", ", alg, cru_type);
PRINT_FIELD_X("..., ", alg, cru_type);
PRINT_FIELD_X(", ", alg, cru_mask);
PRINT_FIELD_U(", ", alg, cru_refcnt);
PRINT_FIELD_X(", ", alg, cru_flags);

View File

@ -15,6 +15,18 @@ print_quoted_string(const char *instr)
print_quoted_memory(instr, strlen(instr));
}
void
print_quoted_cstring(const char *instr, const size_t size)
{
const size_t len = strnlen(instr, size);
if (len < size) {
print_quoted_memory(instr, len);
} else {
print_quoted_memory(instr, size - 1);
printf("...");
}
}
void
print_quoted_memory(const void *const instr, const size_t len)
{

View File

@ -134,6 +134,12 @@ unsigned long inode_of_sockfd(int);
/* Print string in a quoted form. */
void print_quoted_string(const char *);
/*
* Print a NUL-terminated string `str' of length up to `size' - 1
* in a quoted form.
*/
void print_quoted_cstring(const char *str, size_t size);
/* Print memory in a quoted form. */
void print_quoted_memory(const void *, size_t);

14
ubi.c
View File

@ -62,11 +62,8 @@ ubi_ioctl(struct tcb *const tcp, const unsigned int code,
printxval(ubi_volume_types,
(uint8_t) mkvol.vol_type, "UBI_???_VOLUME");
tprintf(", name_len=%" PRIi16 ", name=", mkvol.name_len);
if (print_quoted_string(mkvol.name,
CLAMP(mkvol.name_len, 0, UBI_MAX_VOLUME_NAME),
QUOTE_0_TERMINATED) > 0) {
tprints("...");
}
print_quoted_cstring(mkvol.name,
CLAMP(mkvol.name_len, 0, UBI_MAX_VOLUME_NAME));
tprints("}");
return 1;
}
@ -103,11 +100,8 @@ ubi_ioctl(struct tcb *const tcp, const unsigned int code,
tprintf("{vol_id=%" PRIi32 ", name_len=%" PRIi16
", name=", rnvol.ents[c].vol_id,
rnvol.ents[c].name_len);
if (print_quoted_string(rnvol.ents[c].name,
CLAMP(rnvol.ents[c].name_len, 0, UBI_MAX_VOLUME_NAME),
QUOTE_0_TERMINATED) > 0) {
tprints("...");
}
print_quoted_cstring(rnvol.ents[c].name,
CLAMP(rnvol.ents[c].name_len, 0, UBI_MAX_VOLUME_NAME));
tprints("}");
}
tprints("]}");

24
util.c
View File

@ -695,6 +695,24 @@ print_quoted_string(const char *str, unsigned int size,
return rc;
}
/*
* Quote a NUL-terminated string `str' of length up to `size' - 1
* and print the result.
*
* Returns 0 if NUL was seen, 1 otherwise.
*/
int
print_quoted_cstring(const char *str, unsigned int size)
{
int unterminated =
print_quoted_string(str, size, QUOTE_0_TERMINATED);
if (unterminated)
tprints("...");
return unterminated;
}
/*
* Print path string specified by address `addr' and length `n'.
* If path length exceeds `n', append `...' to the output.
@ -719,10 +737,8 @@ printpathn(struct tcb *const tcp, const kernel_ulong_t addr, unsigned int n)
if (nul_seen < 0)
printaddr(addr);
else {
path[n++] = '\0';
print_quoted_string(path, n, QUOTE_0_TERMINATED);
if (!nul_seen)
tprints("...");
path[n++] = !nul_seen;
print_quoted_cstring(path, n);
}
}