This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Heed help: Calling sys_getcwd to resolve relative pathnames from within systemtap


On 09/28/2011 05:30 PM, Sebastian Pipping wrote:
> Hello!
> 
> 
> Simplified, I have a probe printing filenames as files are opened:
> 
>    probe syscall.open.return {
>      filename = user_string($filename)
>      printf("OPEN %s\n", filename)
>    }
> 
> Now the problem is: filename can be relative.

Yes, and this is a surprisingly complicated issue if you have to
consider mount namespaces, chroot, etc.

Note for comparison that "strace -e open ..." also leaves paths in
whatever form the caller gave.

> To make it absolute I would like to call sys_getcwd to get the current
> working directory of the process that just opened that file so I can
> prepend it to filename to make an absolute path.

The syscall is going to expect the buffer to be a userspace pointer, so
I don't think that will work.  Besides, sys_getcwd is not an exported
function, so it can't be called from modules.

> However, I fail to call sys_getcwd, even from pure blocks like
> 
>    %{ /* pure */ /* unprivileged */
>      [..]
>    %}

You left out all the interesting bits!  Please, if you want help
diagnosing your efforts, we need the details of what you tried.

But just to clarify on the two annotations you put in there:

/* pure */ means that this block has no side effects apart from the
returned value.  So if our optimizer decides the value isn't needed, we
can remove this altogether.  That's probably appropriate here.

/* unprivileged */ means that restricted users running as their script
under stap --unprivileged are allowed to call this function.  That's
almost certainly not the case here, because to even put this in your
script you must be in guru mode already.  This is mainly intended for
tapset functions, and only after careful security consideration.

> Can you help me with calling sys_getcwd or point me to other ways of
> making a pathname absolute from within systemtap?  I doubt I'm the first
> to wonder about this but I find no documentation on this.

I'm not sure there's an easy way in general.  From a slightly different
part of the open callchain though, there are better variables available.
 I found that this works:

probe kernel.function("do_filp_open").return {
    if (errno_p($return)) {
        printf("%5d %5d %-16s %s %s\n",
               pid(), tid(), execname(), errno_str($return),
               kernel_string($pathname))
    } else {
        file = task_dentry_path(task_current(),
                                $return->f_path->dentry,
                                $return->f_path->mnt)
        printf("%5d %5d %-16s opened %s\n",
               pid(), tid(), execname(), file)
    }
}

That only works for the successes though, and for failures it's still
printing a relative name.  I hope that's still helpful to you...

Josh


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]