From: Dmitry V. Levin Date: Sat, 4 Jul 2015 14:40:02 +0000 (+0300) Subject: loop.c: enhance loop ioctl parser X-Git-Tag: v4.11~476 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3cfabeb8815811b42691fe626862073e75aec8cb;p=strace loop.c: enhance loop ioctl parser Decode as much data on entering syscall as possible. * loop.c: Include instead of . Update for RVAL_DECODED. (decode_loop_info, decode_loop_info64): New functions. (loop_ioctl): Use them. Decode LOOP_SET_STATUS, LOOP_SET_STATUS64, LOOP_SET_FD, LOOP_CHANGE_FD, LOOP_CTL_ADD and LOOP_CTL_REMOVE on entering syscall. Print LOOP_SET_FD and LOOP_CHANGE_FD arguments using printfd. --- diff --git a/loop.c b/loop.c index bb622fd9..26aaca0b 100644 --- a/loop.c +++ b/loop.c @@ -26,127 +26,145 @@ */ #include "defs.h" - -#include - +#include #include #include "xlat/loop_flags_options.h" #include "xlat/loop_crypt_type_options.h" -int -loop_ioctl(struct tcb *tcp, const unsigned int code, long arg) +static void +decode_loop_info(struct tcb *tcp, const long addr) { struct loop_info info; - struct loop_info64 info64; - if (entering(tcp)) - return 0; + tprints(", "); + if (umove_or_printaddr(tcp, addr, &info)) + return; - switch (code) { + tprintf("{number=%d", info.lo_number); - case LOOP_SET_STATUS: - case LOOP_GET_STATUS: - if (!verbose(tcp) || umove(tcp, arg, &info) < 0) - return 0; + if (!abbrev(tcp)) { + tprintf(", device=%#lx, inode=%lu, rdevice=%#lx", + (unsigned long) info.lo_device, + info.lo_inode, + (unsigned long) info.lo_rdevice); + } - tprintf(", {number=%d", info.lo_number); + tprintf(", offset=%#x", info.lo_offset); - if (!abbrev(tcp)) { - tprintf(", device=%#lx, inode=%lu, rdevice=%#lx", - (unsigned long) info.lo_device, - info.lo_inode, - (unsigned long) info.lo_rdevice); - } + if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) { + tprints(", encrypt_type="); + printxval(loop_crypt_type_options, info.lo_encrypt_type, + "LO_CRYPT_???"); + tprintf(", encrypt_key_size=%d", info.lo_encrypt_key_size); + } - tprintf(", offset=%#x", info.lo_offset); + tprints(", flags="); + printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???"); - if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) { - tprints(", encrypt_type="); - printxval(loop_crypt_type_options, info.lo_encrypt_type, - "LO_CRYPT_???"); - tprintf(", encrypt_key_size=%d", info.lo_encrypt_key_size); - } + tprints(", name="); + print_quoted_string(info.lo_name, LO_NAME_SIZE, + QUOTE_0_TERMINATED); - tprints(", flags="); - printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???"); + if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) { + tprints(", encrypt_key="); + print_quoted_string((void *) info.lo_encrypt_key, + LO_KEY_SIZE, 0); + } - tprints(", name="); - print_quoted_string(info.lo_name, LO_NAME_SIZE, - QUOTE_0_TERMINATED); + if (!abbrev(tcp)) + tprintf(", init={%#lx, %#lx}" + ", reserved={%#x, %#x, %#x, %#x}}", + info.lo_init[0], info.lo_init[1], + info.reserved[0], info.reserved[1], + info.reserved[2], info.reserved[3]); + else + tprints(", ...}"); +} - if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) { - tprints(", encrypt_key="); - print_quoted_string((void *) info.lo_encrypt_key, - LO_KEY_SIZE, 0); - } +static void +decode_loop_info64(struct tcb *tcp, const long addr) +{ + struct loop_info64 info64; - if (!abbrev(tcp)) - tprintf(", init={%#lx, %#lx}" - ", reserved={%#x, %#x, %#x, %#x}}", - info.lo_init[0], info.lo_init[1], - info.reserved[0], info.reserved[1], - info.reserved[2], info.reserved[3]); - else - tprints(", ...}"); + tprints(", "); + if (umove_or_printaddr(tcp, addr, &info64)) + return; + + if (!abbrev(tcp)) { + tprintf("{device=%" PRIu64 ", inode=%" PRIu64 ", " + "rdevice=%" PRIu64 ", offset=%#" PRIx64 ", " + "sizelimit=%" PRIu64 ", number=%" PRIu32, + (uint64_t) info64.lo_device, + (uint64_t) info64.lo_inode, + (uint64_t) info64.lo_rdevice, + (uint64_t) info64.lo_offset, + (uint64_t) info64.lo_sizelimit, + (uint32_t) info64.lo_number); + } else { + tprintf("{offset=%#" PRIx64 ", number=%" PRIu32, + (uint64_t) info64.lo_offset, + (uint32_t) info64.lo_number); + } - return 1; + if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) { + tprints(", encrypt_type="); + printxval(loop_crypt_type_options, info64.lo_encrypt_type, + "LO_CRYPT_???"); + tprintf(", encrypt_key_size=%" PRIu32, + info64.lo_encrypt_key_size); + } - case LOOP_SET_STATUS64: - case LOOP_GET_STATUS64: - if (!verbose(tcp) || umove(tcp, arg, &info64) < 0) - return 0; + tprints(", flags="); + printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???"); + + tprints(", file_name="); + print_quoted_string((void *) info64.lo_file_name, + LO_NAME_SIZE, QUOTE_0_TERMINATED); - tprints(", {"); - - if (!abbrev(tcp)) { - tprintf("device=%" PRIu64 ", inode=%" PRIu64 ", " - "rdevice=%" PRIu64 ", offset=%#" PRIx64 ", " - "sizelimit=%" PRIu64 ", number=%" PRIu32, - (uint64_t) info64.lo_device, - (uint64_t) info64.lo_inode, - (uint64_t) info64.lo_rdevice, - (uint64_t) info64.lo_offset, - (uint64_t) info64.lo_sizelimit, - (uint32_t) info64.lo_number); - } else { - tprintf("offset=%#" PRIx64 ", number=%" PRIu32, - (uint64_t) info64.lo_offset, - (uint32_t) info64.lo_number); - } - - if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) { - tprints(", encrypt_type="); - printxval(loop_crypt_type_options, info64.lo_encrypt_type, - "LO_CRYPT_???"); - tprintf(", encrypt_key_size=%" PRIu32, - info64.lo_encrypt_key_size); - } - - tprints(", flags="); - printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???"); - - tprints(", file_name="); - print_quoted_string((void *) info64.lo_file_name, + if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) { + tprints(", crypt_name="); + print_quoted_string((void *) info64.lo_crypt_name, LO_NAME_SIZE, QUOTE_0_TERMINATED); + tprints(", encrypt_key="); + print_quoted_string((void *) info64.lo_encrypt_key, + LO_KEY_SIZE, 0); + } - if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) { - tprints(", crypt_name="); - print_quoted_string((void *) info64.lo_crypt_name, - LO_NAME_SIZE, QUOTE_0_TERMINATED); - tprints(", encrypt_key="); - print_quoted_string((void *) info64.lo_encrypt_key, - LO_KEY_SIZE, 0); - } + if (!abbrev(tcp)) + tprintf(", init={%#" PRIx64 ", %#" PRIx64 "}}", + (uint64_t) info64.lo_init[0], + (uint64_t) info64.lo_init[1]); + else + tprints(", ...}"); +} - if (!abbrev(tcp)) - tprintf(", init={%#" PRIx64 ", %#" PRIx64 "}}", - (uint64_t) info64.lo_init[0], - (uint64_t) info64.lo_init[1]); - else - tprints(", ...}"); +int +loop_ioctl(struct tcb *tcp, const unsigned int code, long arg) +{ + if (!verbose(tcp)) + return RVAL_DECODED; - return 1; + switch (code) { + case LOOP_SET_STATUS: + decode_loop_info(tcp, arg); + break; + + case LOOP_GET_STATUS: + if (entering(tcp)) + return 0; + decode_loop_info(tcp, arg); + break; + + case LOOP_SET_STATUS64: + decode_loop_info64(tcp, arg); + break; + + case LOOP_GET_STATUS64: + if (entering(tcp)) + return 0; + decode_loop_info64(tcp, arg); + break; case LOOP_CLR_FD: #ifdef LOOP_SET_CAPACITY @@ -157,18 +175,25 @@ loop_ioctl(struct tcb *tcp, const unsigned int code, long arg) case LOOP_CTL_GET_FREE: #endif /* Takes no arguments */ - return 1; + break; case LOOP_SET_FD: case LOOP_CHANGE_FD: + tprints(", "); + printfd(tcp, arg); + break; + #ifdef LOOP_CTL_ADD /* newer loop-control stuff */ case LOOP_CTL_ADD: case LOOP_CTL_REMOVE: + tprintf(", %d", (int) arg); + break; #endif - /* These take simple args, so let default printer handle it */ default: - return 0; + return RVAL_DECODED; } + + return RVAL_DECODED | 1; }