From: Dmitry V. Levin Date: Mon, 24 Jul 2017 12:10:54 +0000 (+0000) Subject: Introduce print_quoted_cstring X-Git-Tag: v4.19~211 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=de484eced54f1703ef8c7027410d365bc789380b;p=strace 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. --- diff --git a/btrfs.c b/btrfs.c index 8bffba8b..3c48e798 100644 --- a/btrfs.c +++ b/btrfs.c @@ -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; } diff --git a/defs.h b/defs.h index 539afa2b..8aca8083 100644 --- a/defs.h +++ b/defs.h @@ -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 diff --git a/dirent.c b/dirent.c index 71963ec3..2ab626bf 100644 --- a/dirent.c +++ b/dirent.c @@ -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) diff --git a/dirent64.c b/dirent64.c index d54cb9e7..4172d649 100644 --- a/dirent64.c +++ b/dirent64.c @@ -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("}"); } diff --git a/print_fields.h b/print_fields.h index b6b54c04..0aab1d7a 100644 --- a/print_fields.h +++ b/print_fields.h @@ -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_) \ diff --git a/print_ifindex.c b/print_ifindex.c index 21f68f68..f978a5a6 100644 --- a/print_ifindex.c +++ b/print_ifindex.c @@ -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; } diff --git a/sysmips.c b/sysmips.c index a0ed557f..e095cb36 100644 --- a/sysmips.c +++ b/sysmips.c @@ -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; } diff --git a/tests/ioctl_block.c b/tests/ioctl_block.c index 0d518643..2bb68085 100644 --- a/tests/ioctl_block.c +++ b/tests/ioctl_block.c @@ -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, diff --git a/tests/ioctl_dm.c b/tests/ioctl_dm.c index 544d70b3..2f77e041 100644 --- a/tests/ioctl_dm.c +++ b/tests/ioctl_dm.c @@ -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); diff --git a/tests/ioctl_loop.c b/tests/ioctl_loop.c index 4dcbf9ad..3411a4d8 100644 --- a/tests/ioctl_loop.c +++ b/tests/ioctl_loop.c @@ -39,6 +39,7 @@ #include #include #include +#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 "]}", diff --git a/tests/netlink_crypto.c b/tests/netlink_crypto.c index 96bf4c22..deb1644e 100644 --- a/tests/netlink_crypto.c +++ b/tests/netlink_crypto.c @@ -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); diff --git a/tests/print_quoted_string.c b/tests/print_quoted_string.c index dcfcfa0e..2894e49b 100644 --- a/tests/print_quoted_string.c +++ b/tests/print_quoted_string.c @@ -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) { diff --git a/tests/tests.h b/tests/tests.h index 258fbd96..6fa2f402 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -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); diff --git a/ubi.c b/ubi.c index 65db02da..808e4a2b 100644 --- a/ubi.c +++ b/ubi.c @@ -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("]}"); diff --git a/util.c b/util.c index 2ccfe4fe..06a939e7 100644 --- a/util.c +++ b/util.c @@ -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); } }