RFC: path display and path filtering features.
Grant Edwards
grant.b.edwards at gmail.com
Wed Feb 16 18:10:55 UTC 2011
On 2011-02-16, Dmitry V. Levin <ldv at altlinux.org> wrote:
> Even with these complications, readlink-based approach seems to be
> more reliable and easy to implement and support.
I agree. I've tossed out the fd-tracking code.
Once again, premature optimization proves to be a mistake.
> Another issue is how to match paths reliably without introducing code
> into every parser function. The approach implemented in your
> pathtrace_match() is not capable to handle syscalls that take several
> pathname arguments like rename(2), or pathname argument along with
> descriptor argument like openat(2).
Right. I've extended pathtrace_match so it explicity handles cases
other than a single fd/path in arg[0].
> Possible solution could be extending struct sysent with more generic
> information about syscalls, e.g. with two 8-bit bitsets describing
> pathname-like and descriptor-like arguments.
That's the approach used by the python version of strace: the "sysent"
table contains type and name information about each argument.
It would be cleaner than my approach and keep info on systemcalls more
localized.
Below is the pathtrace_match() function I'm currently using. I don't
like it much because adds another place that contains sycall-specific
information.
Would people be agreeable to adding argument type info (or argument
format function pointers) to the sysent table? In addition to making
the fd/path match function simpler, it might allow the "printargs"
function to handle many more cases.
----------------------------------------------------------------------
// return true if syscall accesses a selected path (or if no paths
// have been specified for tracing).
int pathtrace_match(struct tcb *tcp)
{
char path[1024];
const struct sysent *s;
if (selected[0] == NULL)
return 1;
s = &sysent[tcp->scno];
if (!(s->sys_flags & (TRACE_FILE | TRACE_DESC)))
return 0;
// check for special cases where we need to do something other than
// test arg[0]
#ifdef LINUX
if (s->sys_func == sys_dup3 ||
s->sys_func == sys_sendfile ||
s->sys_func == sys_sendfile64 ||
!strcmp(s->sys_name,"tee"))
{
// fd,fd
return fdmatch(tcp->pid,tcp->u_arg[0]) || fdmatch(tcp->pid,tcp->u_arg[1]);
}
if (s->sys_func == sys_inotify_add_watch ||
s->sys_func == sys_faccessat ||
s->sys_func == sys_fchmodat ||
s->sys_func == sys_futimesat ||
s->sys_func == sys_mkdirat ||
s->sys_func == sys_unlinkat ||
s->sys_func == sys_newfstatat ||
s->sys_func == sys_mknodat ||
s->sys_func == sys_openat ||
s->sys_func == sys_readlinkat ||
s->sys_func == sys_utimensat ||
s->sys_func == sys_fchownat ||
s->sys_func == sys_pipe2)
{
// fd,path
return fdmatch(tcp->pid,tcp->u_arg[0]) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path), pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_link ||
s->sys_func == sys_pivotroot ||
s->sys_func == sys_rename ||
s->sys_func == sys_symlink ||
s->sys_func == sys_mount)
{
// path,path
return (umovestr(tcp,tcp->u_arg[0],sizeof path,path), pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path), pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_renameat ||
s->sys_func == sys_linkat)
{
// fd,path,fd,path
return fdmatch(tcp->pid,tcp->u_arg[0]) ||
fdmatch(tcp->pid,tcp->u_arg[2]) ||
(umovestr(tcp,tcp->u_arg[1],sizeof path,path), pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[3],sizeof path,path), pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_old_mmap)
{
// x,x,x,x,fd
return fdmatch(tcp->pid,tcp->u_arg[4]);
}
if (s->sys_func == sys_symlinkat)
{
// path,fd,path
return fdmatch(tcp->pid,tcp->u_arg[1]) ||
(umovestr(tcp,tcp->u_arg[0],sizeof path,path), pathmatch(tcp->pid,path)) ||
(umovestr(tcp,tcp->u_arg[2],sizeof path,path), pathmatch(tcp->pid,path));
}
if (s->sys_func == sys_poll ||
s->sys_func == printargs ||
s->sys_func == sys_ppoll ||
s->sys_func == sys_select ||
s->sys_func == sys_oldselect ||
s->sys_func == sys_pselect6 ||
s->sys_func == sys_pipe ||
s->sys_func == sys_pipe2 ||
s->sys_func == sys_eventfd2 ||
s->sys_func == sys_eventfd ||
s->sys_func == sys_inotify_init1 ||
s->sys_func == sys_timerfd_create)
{
// these either return fd's or they do other things we don't
// know how to handle
return 0;
}
#else
# warning "path tracing only using arg[0]"
#endif
if (s->sys_flags & TRACE_FILE)
{
umovestr(tcp,tcp->u_arg[0],sizeof path,path);
return pathmatch(tcp->pid,path);
}
if (s->sys_flags & TRACE_DESC)
{
return fdmatch(tcp->pid,tcp->u_arg[0]);
}
return 0;
}
--
Grant Edwards grant.b.edwards Yow! I feel like a wet
at parking meter on Darvon!
gmail.com
More information about the Strace-devel
mailing list