Page MenuHomeFreeBSD

Add kernelspace and userspace parts of ktrargs()
ClosedPublic

Authored by artemhevorhian_gmail.com on Oct 15 2024, 2:25 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Dec 17, 12:43 AM
Unknown Object (File)
Thu, Dec 12, 1:53 PM
Unknown Object (File)
Sat, Dec 7, 6:05 PM
Unknown Object (File)
Fri, Dec 6, 12:29 PM
Unknown Object (File)
Wed, Dec 4, 2:10 AM
Unknown Object (File)
Tue, Dec 3, 8:58 PM
Unknown Object (File)
Tue, Dec 3, 6:45 PM
Unknown Object (File)
Tue, Dec 3, 10:03 AM

Details

Summary

The problem. Currently the usage of ktrace is limited in the way that it is not possible to see the environment variables and command line arguments of execve() system call.

Solution. A new ktrace event is proposed for writing the information that is currently hidden behind the pointers of SYSCALL execve() with code 59. For that, kern_execve() is injected with a call to ktrace framework.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 60081
Build 56965: arc lint + arc unit

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
sys/kern/kern_ktrace.c
564

IMO this name is too vague. ktrexecveargs() or similar would be better.

sys/sys/ktrace.h
270

Same comment regarding the name - "ARGS" is too vague.

usr.bin/kdump/kdump.c
264

Please group this with the other ktr*() functions further down below main().

266

Please format this more like other ktrace records. Using english to describe the fields is not very useful, especially without quotes.

At the very least, something like printf("{argv='%s', envp='%s'}\n"). Though, perhaps we want to do something to show whether individual args/envvars contain whitespace?

705–708

Missing an entry here for the new record type.

Because of the need to include the whole imgact.h, remove the forward declaration
of it.

First working version. To be reviewed.

sys/kern/kern_ktrace.c
568

Hello Mark. Please check the new version. Do I still need to run a free() call at the end of the function, right after ktr_submitrequest()?

usr.bin/kdump/kdump.c
266

Is it possible that argvs and/or envv contain whitespace characters?

sys/kern/kern_ktrace.c
569

Please put a newline between variable declarations and the rest of the function. See the style.9 man page for more guidance: https://man.freebsd.org/cgi/man.cgi?style(9)

571

This can simply be buf[argc] = '\0';, no need to use bcopy().

573

Similarly, buf[argc + 1 + envc] = '\0'; is a bit simpler.

576

It's impossible to have buf == NULL here, this check can be removed.

584

Extra newline here.

sys/sys/ktrace.h
43

You don't need these includes here. Just declare struct image_args in the same place where we already declare struct ktr_io_params.

345

There should be a space before *. See the style.9 man page I linked above.

usr.bin/kdump/kdump.c
266

Yes. Try tracing a shell, and run something like

$ awk '{ print }' /dev/null

The argv reported by ktrace will look like awk { print } /dev/null, which is a bit confusing.

usr.bin/ktrace/ktrace.h
35

The ktrace man page needs to be updated as well. We should add a new flag to -t to optionally disable execve tracing, and the documented list of default tracepoints also needs to be updated.

sys/sys/ktrace.h
43

Because of parsing in ktrace.c with the help of exec_args_get_begin_envv and similar, I need the complete definition.

Use tabs instead of whitespace characters where necessary.

Remove code printing the EXEC envv parts of the image_args.
For that, a separate call is to be introducted later,
ktrexecveenvs().

artemhevorhian_gmail.com marked an inline comment as done.

Use "" quotation marks to show whitespace characters.

sys/sys/ktrace.h
43

Then imgact.h should be included in kern_ktrace.c, not here. ktrace.h is included by many different C files, and it should avoid bringing in more definitions than necessary.

This is getting close, most of my comments are style issues.

It would be nice to see some sample output.

sys/kern/kern_ktrace.c
568
574

If req == NULL here, then we need to free buf.

usr.bin/kdump/kdump.c
120
520
1657

Most of these other functions should use const as well, e.g., in ktrnamei(), but that should be handled in a separate patch.

usr.bin/kdump/kdump.c
1662

I just realized that you have no way of distinguishing arguments and environment variables here. I think the structure returned from the kernel should distinguish the two. For example, you could store the offset of the environment variables at the beginning of the ktrace record.

artemhevorhian_gmail.com marked 5 inline comments as done.

This needs to be reviewed, especially the kernel part please. If that's okay,
we can move to the userland implementation. I am not sure if I should put the
buffer in the sturcutre right now, or that it is even possible. Please help me
with the data design step at this point. We all understand what needs to be
passed to userspace, let's decide on how that should be done from the kernel
space now.

869 ktrace   EXEC  ARGV: "echo", "foo "ENVV: "LOGNAME=root", "PAGER=less", "LANG=C.UTF-8", "MAIL=/var/mail/root", "PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/root/bin", "XDG_RUNTIME_DIR=/var/run/xdg/root", "ENV=/root/.shrc", "PWD=/root", "TERM=vt100", "HOME=/root", "USER=root", "SHELL=/bin/sh", "MM_CHARSET=UTF-8", "BLOCKSIZE=K"

Here is a sample output. Let me fix the whitespace character between the two and we're done, I suppose.

This version includes working with a struc and buffer altogether.
In the struct, there is the offset required to tell the difference
between ARGV and ENVV arrays.

What do you think of idea to separate arguments vector printing and environment vector printing? I would imagine that a typical use case is interest in the arguments, ignoring environment. Two different KTR reports would allows either to filter at the tracing time, or if all tracing was enabled, then basic grep(1) would help.

Use two separate events for arguments and environment variables.

sys/kern/kern_ktrace.c
581–597

And then you can just call:

ktrdata(KTR_EXECVE_ARGS, args->begin_argv, exec_args_get_begin_envv(args) - args->begin_argv);
ktrdata(KTR_EXECVE_ENVS, exec_args_get_begin_envv(args), args->endp - exec_args_get_begin_envv(args));

straight from the kern_exec.c, without need to import <imgact.h> into ktr_ktrace.c.

New function ktrdata() can also be used to reduce ktrnamei() down to:

ktrdata(KTR_NAMEI, path, strlen(path))
sys/kern/kern_ktrace.c
581–597

Here is the version I suggest, might be easier to read than a colored diff:

void
ktrdata(int type, const void *data, size_t len)
{
        struct ktr_request *req;
        void *buf;

        if ((req = ktr_getrequest(type)) == NULL)
                return;
        buf = malloc(len, M_KTRACE, M_WAITOK);
        bcopy(data, buf, len);
        req->ktr_header.ktr_len = len;
        req->ktr_buffer = buf;
        ktr_submitrequest(curthread, req);
}

Remove unnecessary forward declaration.

usr.bin/ktrace/ktrace.1
28

Every meaningful change to a manual page must bump this date.

sys/sys/ktrace.h
270

These two new declarations need a comment, just like all old ones have. See comment above KTR_NAMEI as an example.

Update the commit message and make amendments according to the style

guide.

This revision was not accepted when it landed; it landed in state Needs Review.Nov 12 2024, 12:53 AM
This revision was automatically updated to reflect the committed changes.