NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/59911: dtrace: process arguments not easily available



>Number:         59911
>Category:       bin
>Synopsis:       dtrace: process arguments not easily available
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Jan 12 08:25:00 +0000 2026
>Originator:     Thomas Klausner
>Release:        NetBSD 10.1, 11.99.4
>Organization:
	
>Environment:
	
	
Architecture: x86_64
Machine: amd64
>Description:

I think execsnoop is supposed to print the whole commandline, using curpsinfo->pr_psargs .

But I only see argv[0].

I found, in psinfo.d:
        pr_psargs = stringof(T->p_comm);
        pr_arglen = strlen(T->p_comm);

while on FreeBSD I see:
        pr_psargs = (T->p_args == 0) ? "" :
            memstr(T->p_args->ar_args, ' ', T->p_args->ar_length);
        pr_arglen = T->p_args->ar_length;

but I don't know what the equivalent for NetBSD would be.

Taylor writes:

--- begin quote ---

FreeBSD has the arguments mapped in kva, as a contiguous
length-delimited blob of NUL-terminated strings:

/*
 * pargs, used to hold a copy of the command line, if it had a sane length.
 */
struct pargs {
        u_int   ar_ref;         /* Reference count. */
        u_int   ar_length;      /* Length. */
        u_char  ar_args[1];     /* Arguments. */
};

https://cgit.freebsd.org/src/tree/sys/sys/proc.h?id=e3bfcf6b594e8388c4a2e1835519a8026e90cf71#n119

struct proc {
...
        struct pargs    *p_args;        /* (c) Process arguments. */
...
};

https://cgit.freebsd.org/src/tree/sys/sys/proc.h?id=e3bfcf6b594e8388c4a2e1835519a8026e90cf71#n736

But in NetBSD they are only stored in the user address space:

struct proc {
...
        vaddr_t         p_psstrp;       /* :: address of process's ps_strings */
...
};

https://nxr.netbsd.org/xref/src/sys/sys/proc.h?r=1.373#332

This is the user virtual address of a struct ps_strings object, which
holds an array of pointers to strings -- which are almost always in a
contiguous blob in memory, but we don't have the the length recorded:

struct ps_strings {
        char    **ps_argvstr;   /* first of 0 or more argument strings */
        int     ps_nargvstr;    /* the number of argument strings */
        char    **ps_envstr;    /* first of 0 or more environment strings */
        int     ps_nenvstr;     /* the number of environment strings */
};

https://nxr.netbsd.org/xref/src/sys/sys/exec.h?r=1.162#103

We could probably recover the length of the contiguous blob in memory
by something like:

        ps = (struct ps_strings *)copyin(curthread->l_proc->p_psstrp,
            sizeof(struct ps_strings));
        argv_first = copyin(&ps->ps_argvstr[0], sizeof(char *));
        argv_last = copyin(&ps->ps_argvstr[ps->nargvstr - 1],
            sizeof(char *));
        argv_last_end = argv_last + strlen(copyinstr(argv_last)) + 1;
        nbytes = argv_last_end - argv_first;

and then use something like

        memstr(copyin(argv_first, nbytes), ' ', nbytes)

to get what FreeBSD has.  (Translating this pseudocode to working D
left as an exercise for the reader.)

--- end quote ---

but I'm not that reader.
>How-To-Repeat:

su
modload dtrace
execsnoop
(wait)

see lines like

 1000  15610  22337 sh

instead of

 1000  15610  22337 sh someshellscript with arguments

>Fix:
Yes, please.

>Unformatted:
 	
 	


Home | Main Index | Thread Index | Old Index