git: 65a4daeaf324 - main - ktrace: log execve(2) arguments and environment

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Tue, 12 Nov 2024 00:52:50 UTC
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=65a4daeaf3247b7a2c16cf59cdea2ce05987a7cc

commit 65a4daeaf3247b7a2c16cf59cdea2ce05987a7cc
Author:     Artem Hevorhian <artemhevorhian@gmail.com>
AuthorDate: 2024-10-15 13:50:40 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2024-11-11 21:19:35 +0000

    ktrace: log execve(2) arguments and environment
    
    Two new events KTR_ARGS and KTR_ENV can be used to
    trace arguments of execve(2).
    
    Reviewed by:            glebius
    Differential Revision:  https://reviews.freebsd.org/D47127
---
 sys/kern/kern_exec.c    | 11 ++++++++++-
 sys/kern/kern_ktrace.c  | 17 +++++++++++++++++
 sys/sys/ktrace.h        | 13 +++++++++++++
 usr.bin/kdump/kdump.c   | 26 ++++++++++++++++++++++++++
 usr.bin/ktrace/ktrace.1 | 10 +++++++++-
 usr.bin/ktrace/ktrace.h |  3 ++-
 usr.bin/ktrace/subr.c   |  6 ++++++
 7 files changed, 83 insertions(+), 3 deletions(-)

diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
index 63f007624e36..4a11be5b42b8 100644
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -354,7 +354,16 @@ kern_execve(struct thread *td, struct image_args *args, struct mac *mac_p,
 	    exec_args_get_begin_envv(args) - args->begin_argv);
 	AUDIT_ARG_ENVV(exec_args_get_begin_envv(args), args->envc,
 	    args->endp - exec_args_get_begin_envv(args));
-
+#ifdef KTRACE
+	if (KTRPOINT(td, KTR_ARGS)) {
+		ktrdata(KTR_ARGS, args->begin_argv,
+		    exec_args_get_begin_envv(args) - args->begin_argv);
+        }
+	if (KTRPOINT(td, KTR_ENVS)) {
+		ktrdata(KTR_ENVS, exec_args_get_begin_envv(args),
+		    args->endp - exec_args_get_begin_envv(args));
+        }
+#endif
 	/* Must have at least one argument. */
 	if (args->argc == 0) {
 		exec_free_args(args);
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index 868885898d0c..7a31fe234cb5 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -124,6 +124,8 @@ static const int data_lengths[] = {
 	[KTR_FAULT] = sizeof(struct ktr_fault),
 	[KTR_FAULTEND] = sizeof(struct ktr_faultend),
 	[KTR_STRUCT_ARRAY] = sizeof(struct ktr_struct_array),
+	[KTR_ARGS] = 0,
+	[KTR_ENVS] = 0,
 };
 
 static STAILQ_HEAD(, ktr_request) ktr_free;
@@ -559,6 +561,21 @@ ktrsyscall(int code, int narg, syscallarg_t args[])
 	ktr_submitrequest(curthread, req);
 }
 
+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);
+}
+
 void
 ktrsysret(int code, int error, register_t retval)
 {
diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h
index 966af1744058..9d06cd33d5d2 100644
--- a/sys/sys/ktrace.h
+++ b/sys/sys/ktrace.h
@@ -263,6 +263,16 @@ struct ktr_struct_array {
 	 */
 };
 
+/*
+ * KTR_ARGS - arguments of execve()
+ */
+#define KTR_ARGS 16
+
+/*
+ * KTR_ENVS - environment variables of execve()
+ */
+#define KTR_ENVS 17
+
 /*
  * KTR_DROP - If this bit is set in ktr_type, then at least one event
  * between the previous record and this record was dropped.
@@ -295,6 +305,8 @@ struct ktr_struct_array {
 #define KTRFAC_FAULT	(1<<KTR_FAULT)
 #define KTRFAC_FAULTEND	(1<<KTR_FAULTEND)
 #define	KTRFAC_STRUCT_ARRAY (1<<KTR_STRUCT_ARRAY)
+#define KTRFAC_ARGS     (1<<KTR_ARGS)
+#define KTRFAC_ENVS     (1<<KTR_ENVS)
 
 /*
  * trace flags (also in p_traceflags)
@@ -335,6 +347,7 @@ void	ktrstruct(const char *, const void *, size_t);
 void	ktrstruct_error(const char *, const void *, size_t, int);
 void	ktrstructarray(const char *, enum uio_seg, const void *, int, size_t);
 void	ktrcapfail(enum ktr_cap_violation, const void *);
+void	ktrdata(int, const void *, size_t);
 #define ktrcaprights(s) \
 	ktrstruct("caprights", (s), sizeof(cap_rights_t))
 #define	ktritimerval(s) \
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 41d3eb594149..f104c20f3842 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -117,6 +117,7 @@ void ktrstructarray(struct ktr_struct_array *, size_t);
 void ktrbitset(char *, struct bitset *, size_t);
 void ktrsyscall_freebsd(struct ktr_syscall *ktr, register_t **resip,
     int *resnarg, char *resc, u_int sv_flags);
+void ktrexecve(char *, int);
 void usage(void);
 
 #define	TIMESTAMP_NONE		0x0
@@ -515,6 +516,10 @@ main(int argc, char *argv[])
 		case KTR_STRUCT_ARRAY:
 			ktrstructarray((struct ktr_struct_array *)m, ktrlen);
 			break;
+		case KTR_ARGS:
+		case KTR_ENVS:
+			ktrexecve(m, ktrlen);
+			break;
 		default:
 			printf("\n");
 			break;
@@ -699,6 +704,12 @@ dumpheader(struct ktr_header *kth, u_int sv_flags)
 	case KTR_FAULTEND:
 		type = "PRET";
 		break;
+	case KTR_ARGS:
+	        type = "ARGS";
+	        break;
+	case KTR_ENVS:
+	        type = "ENVS";
+	        break;
 	default:
 		sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
 		type = unknown;
@@ -1646,6 +1657,21 @@ ktrnamei(char *cp, int len)
 	printf("\"%.*s\"\n", len, cp);
 }
 
+void
+ktrexecve(char *m, int len)
+{
+	int i = 0;
+
+	while (i < len) {
+		printf("\"%s\"", m + i);
+		i += strlen(m + i) + 1;
+		if (i != len) {
+			printf(", ");
+		}
+	}
+	printf("\n");
+}
+
 void
 hexdump(char *p, int len, int screenwidth)
 {
diff --git a/usr.bin/ktrace/ktrace.1 b/usr.bin/ktrace/ktrace.1
index 5cc6df52d69a..6d78cb1504b4 100644
--- a/usr.bin/ktrace/ktrace.1
+++ b/usr.bin/ktrace/ktrace.1
@@ -25,7 +25,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 10, 2024
+.Dd November 1, 2024
 .Dt KTRACE 1
 .Os
 .Sh NAME
@@ -142,6 +142,14 @@ context switches
 trace
 .Xr sysctl 3
 requests
+.It Cm a
+trace
+.Xr execve 2
+arguments
+.It Cm e
+trace
+.Xr execve 2
+environment variables
 .It Cm +
 trace the default set of trace points -
 .Cm c , i , n , s , t , u , y
diff --git a/usr.bin/ktrace/ktrace.h b/usr.bin/ktrace/ktrace.h
index bf3f70539310..d6da094f33a2 100644
--- a/usr.bin/ktrace/ktrace.h
+++ b/usr.bin/ktrace/ktrace.h
@@ -31,7 +31,8 @@
 
 #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \
 		    KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \
-		    KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_STRUCT_ARRAY)
+		    KTRFAC_STRUCT | KTRFAC_SYSCTL | KTRFAC_STRUCT_ARRAY | \
+		    KTRFAC_ARGS | KTRFAC_ENVS)
 
 #define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR)
 
diff --git a/usr.bin/ktrace/subr.c b/usr.bin/ktrace/subr.c
index 520ee44a1575..6762fe9620cb 100644
--- a/usr.bin/ktrace/subr.c
+++ b/usr.bin/ktrace/subr.c
@@ -81,6 +81,12 @@ getpoints(char *s)
 		case 'y':
 			facs |= KTRFAC_SYSCTL;
 			break;
+		case 'a':
+		        facs |= KTRFAC_ARGS;
+			break;
+		case 'e':
+		        facs |= KTRFAC_ENVS;
+			break;
 		case '+':
 			facs |= DEF_POINTS;
 			break;