Skip to content

Commit 3cfabeb

Browse files
committed
loop.c: enhance loop ioctl parser
Decode as much data on entering syscall as possible. * loop.c: Include <linux/ioctl.h> instead of <sys/ioctl.h>. 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.
1 parent 97317d9 commit 3cfabeb

File tree

1 file changed

+124
-99
lines changed

1 file changed

+124
-99
lines changed

loop.c

Lines changed: 124 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -26,127 +26,145 @@
2626
*/
2727

2828
#include "defs.h"
29-
30-
#include <sys/ioctl.h>
31-
29+
#include <linux/ioctl.h>
3230
#include <linux/loop.h>
3331

3432
#include "xlat/loop_flags_options.h"
3533
#include "xlat/loop_crypt_type_options.h"
3634

37-
int
38-
loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
35+
static void
36+
decode_loop_info(struct tcb *tcp, const long addr)
3937
{
4038
struct loop_info info;
41-
struct loop_info64 info64;
4239

43-
if (entering(tcp))
44-
return 0;
40+
tprints(", ");
41+
if (umove_or_printaddr(tcp, addr, &info))
42+
return;
4543

46-
switch (code) {
44+
tprintf("{number=%d", info.lo_number);
4745

48-
case LOOP_SET_STATUS:
49-
case LOOP_GET_STATUS:
50-
if (!verbose(tcp) || umove(tcp, arg, &info) < 0)
51-
return 0;
46+
if (!abbrev(tcp)) {
47+
tprintf(", device=%#lx, inode=%lu, rdevice=%#lx",
48+
(unsigned long) info.lo_device,
49+
info.lo_inode,
50+
(unsigned long) info.lo_rdevice);
51+
}
5252

53-
tprintf(", {number=%d", info.lo_number);
53+
tprintf(", offset=%#x", info.lo_offset);
5454

55-
if (!abbrev(tcp)) {
56-
tprintf(", device=%#lx, inode=%lu, rdevice=%#lx",
57-
(unsigned long) info.lo_device,
58-
info.lo_inode,
59-
(unsigned long) info.lo_rdevice);
60-
}
55+
if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
56+
tprints(", encrypt_type=");
57+
printxval(loop_crypt_type_options, info.lo_encrypt_type,
58+
"LO_CRYPT_???");
59+
tprintf(", encrypt_key_size=%d", info.lo_encrypt_key_size);
60+
}
6161

62-
tprintf(", offset=%#x", info.lo_offset);
62+
tprints(", flags=");
63+
printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
6364

64-
if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
65-
tprints(", encrypt_type=");
66-
printxval(loop_crypt_type_options, info.lo_encrypt_type,
67-
"LO_CRYPT_???");
68-
tprintf(", encrypt_key_size=%d", info.lo_encrypt_key_size);
69-
}
65+
tprints(", name=");
66+
print_quoted_string(info.lo_name, LO_NAME_SIZE,
67+
QUOTE_0_TERMINATED);
7068

71-
tprints(", flags=");
72-
printflags(loop_flags_options, info.lo_flags, "LO_FLAGS_???");
69+
if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
70+
tprints(", encrypt_key=");
71+
print_quoted_string((void *) info.lo_encrypt_key,
72+
LO_KEY_SIZE, 0);
73+
}
7374

74-
tprints(", name=");
75-
print_quoted_string(info.lo_name, LO_NAME_SIZE,
76-
QUOTE_0_TERMINATED);
75+
if (!abbrev(tcp))
76+
tprintf(", init={%#lx, %#lx}"
77+
", reserved={%#x, %#x, %#x, %#x}}",
78+
info.lo_init[0], info.lo_init[1],
79+
info.reserved[0], info.reserved[1],
80+
info.reserved[2], info.reserved[3]);
81+
else
82+
tprints(", ...}");
83+
}
7784

78-
if (!abbrev(tcp) || info.lo_encrypt_type != LO_CRYPT_NONE) {
79-
tprints(", encrypt_key=");
80-
print_quoted_string((void *) info.lo_encrypt_key,
81-
LO_KEY_SIZE, 0);
82-
}
85+
static void
86+
decode_loop_info64(struct tcb *tcp, const long addr)
87+
{
88+
struct loop_info64 info64;
8389

84-
if (!abbrev(tcp))
85-
tprintf(", init={%#lx, %#lx}"
86-
", reserved={%#x, %#x, %#x, %#x}}",
87-
info.lo_init[0], info.lo_init[1],
88-
info.reserved[0], info.reserved[1],
89-
info.reserved[2], info.reserved[3]);
90-
else
91-
tprints(", ...}");
90+
tprints(", ");
91+
if (umove_or_printaddr(tcp, addr, &info64))
92+
return;
93+
94+
if (!abbrev(tcp)) {
95+
tprintf("{device=%" PRIu64 ", inode=%" PRIu64 ", "
96+
"rdevice=%" PRIu64 ", offset=%#" PRIx64 ", "
97+
"sizelimit=%" PRIu64 ", number=%" PRIu32,
98+
(uint64_t) info64.lo_device,
99+
(uint64_t) info64.lo_inode,
100+
(uint64_t) info64.lo_rdevice,
101+
(uint64_t) info64.lo_offset,
102+
(uint64_t) info64.lo_sizelimit,
103+
(uint32_t) info64.lo_number);
104+
} else {
105+
tprintf("{offset=%#" PRIx64 ", number=%" PRIu32,
106+
(uint64_t) info64.lo_offset,
107+
(uint32_t) info64.lo_number);
108+
}
92109

93-
return 1;
110+
if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
111+
tprints(", encrypt_type=");
112+
printxval(loop_crypt_type_options, info64.lo_encrypt_type,
113+
"LO_CRYPT_???");
114+
tprintf(", encrypt_key_size=%" PRIu32,
115+
info64.lo_encrypt_key_size);
116+
}
94117

95-
case LOOP_SET_STATUS64:
96-
case LOOP_GET_STATUS64:
97-
if (!verbose(tcp) || umove(tcp, arg, &info64) < 0)
98-
return 0;
118+
tprints(", flags=");
119+
printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
120+
121+
tprints(", file_name=");
122+
print_quoted_string((void *) info64.lo_file_name,
123+
LO_NAME_SIZE, QUOTE_0_TERMINATED);
99124

100-
tprints(", {");
101-
102-
if (!abbrev(tcp)) {
103-
tprintf("device=%" PRIu64 ", inode=%" PRIu64 ", "
104-
"rdevice=%" PRIu64 ", offset=%#" PRIx64 ", "
105-
"sizelimit=%" PRIu64 ", number=%" PRIu32,
106-
(uint64_t) info64.lo_device,
107-
(uint64_t) info64.lo_inode,
108-
(uint64_t) info64.lo_rdevice,
109-
(uint64_t) info64.lo_offset,
110-
(uint64_t) info64.lo_sizelimit,
111-
(uint32_t) info64.lo_number);
112-
} else {
113-
tprintf("offset=%#" PRIx64 ", number=%" PRIu32,
114-
(uint64_t) info64.lo_offset,
115-
(uint32_t) info64.lo_number);
116-
}
117-
118-
if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
119-
tprints(", encrypt_type=");
120-
printxval(loop_crypt_type_options, info64.lo_encrypt_type,
121-
"LO_CRYPT_???");
122-
tprintf(", encrypt_key_size=%" PRIu32,
123-
info64.lo_encrypt_key_size);
124-
}
125-
126-
tprints(", flags=");
127-
printflags(loop_flags_options, info64.lo_flags, "LO_FLAGS_???");
128-
129-
tprints(", file_name=");
130-
print_quoted_string((void *) info64.lo_file_name,
125+
if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
126+
tprints(", crypt_name=");
127+
print_quoted_string((void *) info64.lo_crypt_name,
131128
LO_NAME_SIZE, QUOTE_0_TERMINATED);
129+
tprints(", encrypt_key=");
130+
print_quoted_string((void *) info64.lo_encrypt_key,
131+
LO_KEY_SIZE, 0);
132+
}
132133

133-
if (!abbrev(tcp) || info64.lo_encrypt_type != LO_CRYPT_NONE) {
134-
tprints(", crypt_name=");
135-
print_quoted_string((void *) info64.lo_crypt_name,
136-
LO_NAME_SIZE, QUOTE_0_TERMINATED);
137-
tprints(", encrypt_key=");
138-
print_quoted_string((void *) info64.lo_encrypt_key,
139-
LO_KEY_SIZE, 0);
140-
}
134+
if (!abbrev(tcp))
135+
tprintf(", init={%#" PRIx64 ", %#" PRIx64 "}}",
136+
(uint64_t) info64.lo_init[0],
137+
(uint64_t) info64.lo_init[1]);
138+
else
139+
tprints(", ...}");
140+
}
141141

142-
if (!abbrev(tcp))
143-
tprintf(", init={%#" PRIx64 ", %#" PRIx64 "}}",
144-
(uint64_t) info64.lo_init[0],
145-
(uint64_t) info64.lo_init[1]);
146-
else
147-
tprints(", ...}");
142+
int
143+
loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
144+
{
145+
if (!verbose(tcp))
146+
return RVAL_DECODED;
148147

149-
return 1;
148+
switch (code) {
149+
case LOOP_SET_STATUS:
150+
decode_loop_info(tcp, arg);
151+
break;
152+
153+
case LOOP_GET_STATUS:
154+
if (entering(tcp))
155+
return 0;
156+
decode_loop_info(tcp, arg);
157+
break;
158+
159+
case LOOP_SET_STATUS64:
160+
decode_loop_info64(tcp, arg);
161+
break;
162+
163+
case LOOP_GET_STATUS64:
164+
if (entering(tcp))
165+
return 0;
166+
decode_loop_info64(tcp, arg);
167+
break;
150168

151169
case LOOP_CLR_FD:
152170
#ifdef LOOP_SET_CAPACITY
@@ -157,18 +175,25 @@ loop_ioctl(struct tcb *tcp, const unsigned int code, long arg)
157175
case LOOP_CTL_GET_FREE:
158176
#endif
159177
/* Takes no arguments */
160-
return 1;
178+
break;
161179

162180
case LOOP_SET_FD:
163181
case LOOP_CHANGE_FD:
182+
tprints(", ");
183+
printfd(tcp, arg);
184+
break;
185+
164186
#ifdef LOOP_CTL_ADD
165187
/* newer loop-control stuff */
166188
case LOOP_CTL_ADD:
167189
case LOOP_CTL_REMOVE:
190+
tprintf(", %d", (int) arg);
191+
break;
168192
#endif
169-
/* These take simple args, so let default printer handle it */
170193

171194
default:
172-
return 0;
195+
return RVAL_DECODED;
173196
}
197+
198+
return RVAL_DECODED | 1;
174199
}

0 commit comments

Comments
 (0)