On Sat, Sep 17, 2016 at 09:20:31PM +0200, Theo Buehler wrote: > While this patch avoids the bug, it isn't quite right: pstat -ft should > be equivalent to "pstat -f && pstat -t" but... > > $ pstat -ft > pstat: kvm_openfiles: /dev/mem: Permission denied > > The actual problem is in ttymode(): if kd != NULL (which is the case if > -f is combined with -t), there are accesses of the kvm datastructures > without them being properly initialized: > > 879 if (kd != NULL) > 880 KGET(TTY_NTTY, ntty); > > and > > 896 KGET(TTY_TTYLIST, tty_head); > 897 for (tp = TAILQ_FIRST(&tty_head); tp; > 898 tp = TAILQ_NEXT(&tty, tty_link)) { > 899 KGET2(tp, &tty, sizeof tty, "tty struct"); > 900 tty2itty(&tty, &itty); > 901 ttyprt(&itty); > 902 } > > These code paths must not be hit unless need_nlist is true, so expose it > globally and replace 'kd != NULL' with the proper condition need_nlist > > The following patch works in all affected cases, pstat -t, pstat -f, > pstat -tf, both as root and non-root as well as pstat -tv as root > (combinations with -d aren't interesting since pstat exits before > doing anything else but -d). > > Index: pstat.c > =================================================================== > RCS file: /var/cvs/src/usr.sbin/pstat/pstat.c,v > retrieving revision 1.108 > diff -u -p -r1.108 pstat.c > --- pstat.c 14 Aug 2016 22:47:26 -0000 1.108 > +++ pstat.c 17 Sep 2016 17:57:38 -0000 > @@ -89,6 +89,7 @@ struct e_vnode { > struct vnode vnode; > }; > > +int need_nlist; > int usenumflag; > int totalflag; > int kflag; > @@ -141,7 +142,7 @@ main(int argc, char *argv[]) > const char *dformat = NULL; > extern char *optarg; > extern int optind; > - int i, need_nlist; > + int i; > > hideroot = getuid(); > > @@ -869,7 +870,7 @@ ttymode(void) > struct itty itty, *itp; > size_t nlen; > > - if (kd == 0) { > + if (!need_nlist) { > mib[0] = CTL_KERN; > mib[1] = KERN_TTYCOUNT; > nlen = sizeof(ntty); > @@ -879,7 +880,7 @@ ttymode(void) > KGET(TTY_NTTY, ntty); > (void)printf("%d terminal device%s\n", ntty, ntty == 1 ? "" : "s"); > (void)printf("%s", hdr); > - if (kd == 0) { > + if (!need_nlist) { > mib[0] = CTL_KERN; > mib[1] = KERN_TTY; > mib[2] = KERN_TTY_INFO; >
Thanks Theo. Fixes the regress and works well with your pending pledge diff. Rob