io: add I/O buffer decoding infrastructure
* defs.h (enum fileops): New enumeration definition. (filebuf_decoder_fn): New type definition. * io.c: Include <fnmatch.h> (struct filebuf_decoder_desc): New type definition. (decode_filebuf, decode_readbuf, decode_writebuf): New functions. (SYS_FUNC(read), SYS_FUNC(write), SYS_FUNC(pread), SYS_FUNC(pwrite)): Call decode_readbuf/decode_writebuf instead of printing I/O buffer as a string.
This commit is contained in:
parent
ef330a84d9
commit
4f72de66f4
9
defs.h
9
defs.h
@ -403,6 +403,15 @@ enum sock_proto {
|
|||||||
extern enum sock_proto get_proto_by_name(const char *);
|
extern enum sock_proto get_proto_by_name(const char *);
|
||||||
extern int get_family_by_proto(enum sock_proto proto);
|
extern int get_family_by_proto(enum sock_proto proto);
|
||||||
|
|
||||||
|
enum fileops {
|
||||||
|
FILEOP_READ,
|
||||||
|
FILEOP_WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef bool (*filebuf_decoder_fn)(struct tcb *tcp, int fd, const char *fdpath,
|
||||||
|
enum fileops op, kernel_ulong_t addr,
|
||||||
|
kernel_ulong_t addrlen);
|
||||||
|
|
||||||
enum iov_decode {
|
enum iov_decode {
|
||||||
IOV_DECODE_ADDR,
|
IOV_DECODE_ADDR,
|
||||||
IOV_DECODE_STR,
|
IOV_DECODE_STR,
|
||||||
|
67
io.c
67
io.c
@ -30,9 +30,66 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
struct filebuf_decoder_desc {
|
||||||
|
const char *fname;
|
||||||
|
filebuf_decoder_fn decoder;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
decode_filebuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
|
||||||
|
const kernel_ulong_t addrlen,
|
||||||
|
const struct filebuf_decoder_desc *decoders, size_t decoders_cnt,
|
||||||
|
enum fileops op)
|
||||||
|
{
|
||||||
|
if (!verbose(tcp))
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
|
char fdpath[PATH_MAX + 1];
|
||||||
|
|
||||||
|
if (getfdpath(tcp, fd, ARRSZ_PAIR(fdpath)) < 0)
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
|
/* We don't support any "regular" files so far */
|
||||||
|
if (fdpath[0] == '/')
|
||||||
|
goto no_match;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < decoders_cnt; i++) {
|
||||||
|
if (!fnmatch(decoders[i].fname, fdpath, 0) &&
|
||||||
|
decoders[i].decoder(tcp, fd, fdpath, op, addr, addrlen))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
no_match:
|
||||||
|
printstrn(tcp, addr, addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
decode_readbuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
|
||||||
|
const kernel_ulong_t addrlen)
|
||||||
|
{
|
||||||
|
static const struct filebuf_decoder_desc decoders[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
decode_filebuf(tcp, fd, addr, addrlen, ARRSZ_PAIR(decoders),
|
||||||
|
FILEOP_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
decode_writebuf(struct tcb *const tcp, const int fd, const kernel_ulong_t addr,
|
||||||
|
const kernel_ulong_t addrlen)
|
||||||
|
{
|
||||||
|
static const struct filebuf_decoder_desc decoders[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
decode_filebuf(tcp, fd, addr, addrlen, ARRSZ_PAIR(decoders),
|
||||||
|
FILEOP_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
SYS_FUNC(read)
|
SYS_FUNC(read)
|
||||||
{
|
{
|
||||||
if (entering(tcp)) {
|
if (entering(tcp)) {
|
||||||
@ -42,7 +99,8 @@ SYS_FUNC(read)
|
|||||||
if (syserror(tcp))
|
if (syserror(tcp))
|
||||||
printaddr(tcp->u_arg[1]);
|
printaddr(tcp->u_arg[1]);
|
||||||
else
|
else
|
||||||
printstrn(tcp, tcp->u_arg[1], tcp->u_rval);
|
decode_readbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
|
||||||
|
tcp->u_rval);
|
||||||
tprintf(", %" PRI_klu, tcp->u_arg[2]);
|
tprintf(", %" PRI_klu, tcp->u_arg[2]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -52,7 +110,7 @@ SYS_FUNC(write)
|
|||||||
{
|
{
|
||||||
printfd(tcp, tcp->u_arg[0]);
|
printfd(tcp, tcp->u_arg[0]);
|
||||||
tprints(", ");
|
tprints(", ");
|
||||||
printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
decode_writebuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
|
||||||
tprintf(", %" PRI_klu, tcp->u_arg[2]);
|
tprintf(", %" PRI_klu, tcp->u_arg[2]);
|
||||||
|
|
||||||
return RVAL_DECODED;
|
return RVAL_DECODED;
|
||||||
@ -159,7 +217,8 @@ SYS_FUNC(pread)
|
|||||||
if (syserror(tcp))
|
if (syserror(tcp))
|
||||||
printaddr(tcp->u_arg[1]);
|
printaddr(tcp->u_arg[1]);
|
||||||
else
|
else
|
||||||
printstrn(tcp, tcp->u_arg[1], tcp->u_rval);
|
decode_readbuf(tcp, tcp->u_arg[0], tcp->u_arg[1],
|
||||||
|
tcp->u_rval);
|
||||||
tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
|
tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
|
||||||
printllval(tcp, "%lld", 3);
|
printllval(tcp, "%lld", 3);
|
||||||
}
|
}
|
||||||
@ -170,7 +229,7 @@ SYS_FUNC(pwrite)
|
|||||||
{
|
{
|
||||||
printfd(tcp, tcp->u_arg[0]);
|
printfd(tcp, tcp->u_arg[0]);
|
||||||
tprints(", ");
|
tprints(", ");
|
||||||
printstrn(tcp, tcp->u_arg[1], tcp->u_arg[2]);
|
decode_writebuf(tcp, tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
|
||||||
tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
|
tprintf(", %" PRI_klu ", ", tcp->u_arg[2]);
|
||||||
printllval(tcp, "%lld", 3);
|
printllval(tcp, "%lld", 3);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user