Re: any interest in tracking of file descriptors by ktrace/kdump?
Alexander Nasonov <[email protected]> Sun, 30 Aug 2009 07:31:56 +0100
| Newsgroups | gmane.os.netbsd.devel.general |
|---|---|
| Message-ID | <[email protected]> |
Alexander Nasonov wrote: > Below is an example followed by a patch. > > $ env -i ktrace -id -tafv mail [email protected] > Subject: test > test The next line was ".\n" and it seems that the mailman interprested it as a command to stop further processing. Anyway, I found a problem with my patch. fd_closeexec returns without going through all fds if closexec flag was never set during lifetime of a process. New patch addresses this problem. There are also few cosmetic changes. $ kdump 686 1 ktrace ARG "mail" 686 1 ktrace ARG "[email protected]" 686 1 mail FD file 0 686 1 mail FD file 1 686 1 mail FD file 2 687 1 mail ARG "sendmail" 687 1 mail ARG "-i" 687 1 mail ARG "[email protected]" 687 1 mailwrapper FD file 0 687 1 mailwrapper FD file 1 687 1 mailwrapper FD file 2 687 1 mailwrapper FD file 3 687 1 mailwrapper FD file 4 687 1 mailwrapper FD file 5 687 1 mailwrapper FD file 6 687 1 mailwrapper ARG "sendmail" 687 1 mailwrapper ARG "-i" 687 1 mailwrapper ARG "[email protected]" 687 1 sendmail FD file 0 687 1 sendmail FD file 1 687 1 sendmail FD file 2 687 1 sendmail FD file 3 687 1 sendmail FD file 4 687 1 sendmail FD file 5 687 1 sendmail FD file 6 434 1 sendmail ARG "/usr/sbin/postdrop" 434 1 sendmail ARG "-r" 434 1 sendmail ENV "PATH=/usr/bin:/bin:/usr/pkg/bin:/usr/local/bin" 434 1 postdrop FD socket 0 434 1 postdrop FD socket 1 434 1 postdrop FD file 2 Alex Index: sys/sys/ktrace.h =================================================================== RCS file: /cvsroot/src/sys/sys/ktrace.h,v retrieving revision 1.56 diff -u -r1.56 ktrace.h --- sys/sys/ktrace.h 11 Jan 2009 02:45:55 -0000 1.56 +++ sys/sys/ktrace.h 29 Aug 2009 22:24:02 -0000 @@ -246,6 +246,14 @@ #define KTR_MIB 14 /* Record contains MIB name */ +/* + * KTR_EXEC_FD - Opened file descriptor from exec + */ +#define KTR_EXEC_FD 15 +struct ktr_execfd { + int ktr_fd; + u_int ktr_dtype; /* one of DTYPE_* constants */ +}; /* * kernel trace points (in p_traceflag) @@ -265,6 +273,7 @@ #define KTRFAC_MOOL (1<<KTR_MOOL) #define KTRFAC_SAUPCALL (1<<KTR_SAUPCALL) #define KTRFAC_MIB (1<<KTR_MIB) +#define KTRFAC_EXEC_FD (1<<KTR_EXEC_FD) /* * trace flags (also in p_traceflags) */ @@ -319,6 +328,7 @@ void ktr_mool(const void *, size_t, const void *); void ktr_execarg(const void *, size_t); void ktr_execenv(const void *, size_t); +void ktr_execfd(int fd, u_int dtype); void ktr_saupcall(struct lwp *, int, int, int, void *, void *, void *); static inline bool @@ -440,6 +450,13 @@ } static inline void +ktrexecfd(int fd, u_int dtype) +{ + if (__predict_false(ktrace_on)) + ktr_execfd(fd, dtype); +} + +static inline void ktrsaupcall(struct lwp *a, int b, int c, int d, void *e, void *f, void *g) { if (__predict_false(ktrace_on)) Index: sys/sys/filedesc.h =================================================================== RCS file: /cvsroot/src/sys/sys/filedesc.h,v retrieving revision 1.56 diff -u -r1.56 filedesc.h --- sys/sys/filedesc.h 25 May 2009 03:59:45 -0000 1.56 +++ sys/sys/filedesc.h 29 Aug 2009 22:24:02 -0000 @@ -193,6 +193,7 @@ void fd_hold(void); void fd_free(void); void fd_closeexec(void); +void fd_ktrexecfd(void); int fd_checkstd(void); file_t *fd_getfile(unsigned); file_t *fd_getfile2(proc_t *, unsigned); Index: sys/kern/kern_ktrace.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_ktrace.c,v retrieving revision 1.149 diff -u -r1.149 kern_ktrace.c --- sys/kern/kern_ktrace.c 5 Aug 2009 19:53:42 -0000 1.149 +++ sys/kern/kern_ktrace.c 29 Aug 2009 22:24:03 -0000 @@ -655,6 +655,25 @@ ktr_kmem(l, KTR_EXEC_ENV, bf, len); } +void +ktr_execfd(int fd, u_int dtype) +{ + struct ktrace_entry *kte; + struct ktr_execfd* ktp; + + lwp_t *l = curlwp; + + if (!KTRPOINT(l->l_proc, KTR_EXEC_FD)) + return; + + if (ktealloc(&kte, (void *)&ktp, l, KTR_EXEC_FD, sizeof(*ktp))) + return; + + ktp->ktr_fd = fd; + ktp->ktr_dtype = dtype; + ktraddentry(l, kte, KTA_WAITOK); +} + static void ktr_kmem(lwp_t *l, int type, const void *bf, size_t len) { Index: sys/kern/kern_exec.c =================================================================== RCS file: /cvsroot/src/sys/kern/kern_exec.c,v retrieving revision 1.290 diff -u -r1.290 kern_exec.c --- sys/kern/kern_exec.c 6 Aug 2009 21:33:54 -0000 1.290 +++ sys/kern/kern_exec.c 29 Aug 2009 22:24:03 -0000 @@ -928,6 +928,8 @@ } fd_closeexec(); /* handle close on exec */ + if(__predict_false(ktrace_on)) + fd_ktrexecfd(); execsigs(p); /* reset catched signals */ l->l_ctxlink = NULL; /* reset ucontext link */ Index: sys/kern/subr_exec_fd.c =================================================================== RCS file: /cvsroot/src/sys/kern/subr_exec_fd.c,v retrieving revision 1.2 diff -u -r1.2 subr_exec_fd.c --- sys/kern/subr_exec_fd.c 24 May 2009 21:41:26 -0000 1.2 +++ sys/kern/subr_exec_fd.c 29 Aug 2009 22:24:03 -0000 @@ -40,6 +40,7 @@ #include <sys/namei.h> #include <sys/syslog.h> #include <sys/vnode.h> +#include <sys/ktrace.h> /* * Close open files on exec. @@ -98,6 +99,34 @@ } } +void +fd_ktrexecfd(void) +{ + proc_t *p; + filedesc_t *fdp; + fdfile_t *ff; + lwp_t *l; + fdtab_t *dt; + int fd; + + l = curlwp; + p = l->l_proc; + fdp = p->p_fd; + dt = fdp->fd_dt; + + for (fd = 0; fd <= fdp->fd_lastfile; fd++) { + if ((ff = dt->dt_ff[fd]) == NULL) { + KASSERT(fd >= NDFDFILE); + continue; + } + KASSERT(fd >= NDFDFILE || + ff == (fdfile_t *)fdp->fd_dfdfile[fd]); + if (ff->ff_file == NULL) + continue; + ktr_execfd(fd, ff->ff_file->f_type); + } +} + /* * It is unsafe for set[ug]id processes to be started with file * descriptors 0..2 closed, as these descriptors are given implicit Index: usr.bin/ktrace/ktrace.1 =================================================================== RCS file: /cvsroot/src/usr.bin/ktrace/ktrace.1,v retrieving revision 1.39 diff -u -r1.39 ktrace.1 --- usr.bin/ktrace/ktrace.1 27 Aug 2007 16:35:47 -0000 1.39 +++ usr.bin/ktrace/ktrace.1 29 Aug 2009 22:24:03 -0000 @@ -181,6 +181,8 @@ trace system calls .It Cm e trace emulation changes +.It Cm f +trace open file descriptors after exec .It Cm i trace .Tn I/O Index: usr.bin/ktrace/subr.c =================================================================== RCS file: /cvsroot/src/usr.bin/ktrace/subr.c,v retrieving revision 1.16 diff -u -r1.16 subr.c --- usr.bin/ktrace/subr.c 9 Feb 2007 22:08:49 -0000 1.16 +++ usr.bin/ktrace/subr.c 29 Aug 2009 22:24:04 -0000 @@ -73,6 +73,9 @@ case 'e': fac = KTRFAC_EMUL; break; + case 'f': + fac = KTRFAC_EXEC_FD; + break; case 'i': fac = KTRFAC_GENIO; break; Index: usr.bin/kdump/kdump.c =================================================================== RCS file: /cvsroot/src/usr.bin/kdump/kdump.c,v retrieving revision 1.104 diff -u -r1.104 kdump.c --- usr.bin/kdump/kdump.c 13 Apr 2009 14:39:23 -0000 1.104 +++ usr.bin/kdump/kdump.c 29 Aug 2009 22:24:04 -0000 @@ -44,7 +44,9 @@ #endif /* not lint */ #include <sys/param.h> +#include <sys/proc.h> /* XXX #include <sys/file.h> fails without this header */ #define _KERNEL +#include <sys/file.h> #include <sys/errno.h> #undef _KERNEL #include <sys/time.h> @@ -117,6 +119,7 @@ static void ktrmmsg(struct ktr_mmsg *, int); static void ktrmool(struct ktr_mool *, int); static void ktrmib(int *, int); +static void ktrexecfd(struct ktr_execfd *); static void usage(void) __dead; static void eprint(int); static void rprint(register_t); @@ -303,6 +306,9 @@ case KTR_EXEC_ENV: visdump_buf(m, ktrlen, col); break; + case KTR_EXEC_FD: + ktrexecfd(m); + break; case KTR_MIB: ktrmib(m, ktrlen); break; @@ -378,6 +384,9 @@ case KTR_EXEC_ARG: type = "ARG"; break; + case KTR_EXEC_FD: + type = "FD"; + break; case KTR_SAUPCALL: type = "SAU"; break; @@ -646,6 +655,17 @@ } static void +ktrexecfd(struct ktr_execfd* ktr) +{ + static const char *dnames[] = { DTYPE_NAMES }; + const size_t dnames_sz = sizeof(dnames) / sizeof(dnames[0]); + if(ktr->ktr_dtype > 0 && ktr->ktr_dtype < dnames_sz) + printf("%s %d\n", dnames[ktr->ktr_dtype], ktr->ktr_fd); + else + printf("%d\n", ktr->ktr_fd); +} + +static void rprint(register_t ret) {