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:
Eugene Syromyatnikov 2018-09-25 01:53:51 +02:00
parent ef330a84d9
commit 4f72de66f4
2 changed files with 72 additions and 4 deletions

9
defs.h
View File

@ -403,6 +403,15 @@ enum sock_proto {
extern enum sock_proto get_proto_by_name(const char *);
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 {
IOV_DECODE_ADDR,
IOV_DECODE_STR,

67
io.c
View File

@ -30,9 +30,66 @@
*/
#include "defs.h"
#include <fcntl.h>
#include <fnmatch.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)
{
if (entering(tcp)) {
@ -42,7 +99,8 @@ SYS_FUNC(read)
if (syserror(tcp))
printaddr(tcp->u_arg[1]);
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]);
}
return 0;
@ -52,7 +110,7 @@ SYS_FUNC(write)
{
printfd(tcp, tcp->u_arg[0]);
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]);
return RVAL_DECODED;
@ -159,7 +217,8 @@ SYS_FUNC(pread)
if (syserror(tcp))
printaddr(tcp->u_arg[1]);
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]);
printllval(tcp, "%lld", 3);
}
@ -170,7 +229,7 @@ SYS_FUNC(pwrite)
{
printfd(tcp, tcp->u_arg[0]);
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]);
printllval(tcp, "%lld", 3);