Hey,

Thanks all for the comments.

On Wed, Feb 10, 2016 at 04:27:38PM -0800, patrick keshishian wrote:
> NULL pointer dereference is possible here.
> 
> Also, unclear why you need both arg and args variables.

^ Fix these and make cmd_matches() static.

Updated diff:


Index: machine.c
===================================================================
RCS file: /home/edd/cvsync/src/usr.bin/top/machine.c,v
retrieving revision 1.85
diff -u -p -r1.85 machine.c
--- machine.c   20 Aug 2015 22:32:42 -0000      1.85
+++ machine.c   12 Feb 2016 18:52:31 -0000
@@ -57,6 +57,8 @@
 static int     swapmode(int *, int *);
 static char    *state_abbr(struct kinfo_proc *);
 static char    *format_comm(struct kinfo_proc *);
+static int     cmd_matches(struct kinfo_proc *proc, char *cmd);
+static char    **get_proc_args(struct kinfo_proc *kp);
 
 /* get_process_info passes back a handle.  This is what it looks like: */
 
@@ -360,6 +362,61 @@ getprocs(int op, int arg, int *cnt)
        return (procbase);
 }
 
+static char **
+get_proc_args(struct kinfo_proc *kp)
+{
+       static char     **s;
+       size_t          siz = 100;
+       int             mib[4];
+
+       for (;; siz *= 2) {
+               if ((s = realloc(s, siz)) == NULL)
+                       err(1, NULL);
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_PROC_ARGS;
+               mib[2] = kp->p_pid;
+               mib[3] = KERN_PROC_ARGV;
+               if (sysctl(mib, 4, s, &siz, NULL, 0) == 0)
+                       break;
+               if (errno != ENOMEM)
+                       return (NULL);
+       }
+       return (s);
+}
+
+static int
+cmd_matches(struct kinfo_proc *proc, char *term)
+{
+       extern int      show_args;
+       char            **args = NULL;
+
+       if (!term) {
+               /* No command filter set */
+               return (1);
+       } else {
+               /* Filter set, process name needs to contain term */
+               if (strstr(proc->p_comm, term)) {
+                       return (1);
+               }
+               /* If showing arguments, search those as well */
+               if (show_args) {
+                       args = get_proc_args(proc);
+
+                       if (args == NULL) {
+                               /* Failed to get args, so can't search them */
+                               return (0);
+                       }
+
+                       while (*args != NULL) {
+                               if (strstr(*args, term))
+                                       return (1);
+                               args++;
+                       }
+               }
+       }
+       return (0);
+}
+
 caddr_t
 get_process_info(struct system_info *si, struct process_select *sel,
     int (*compare) (const void *, const void *))
@@ -421,8 +478,7 @@ get_process_info(struct system_info *si,
                            (!hide_uid || pp->p_ruid != sel->huid) &&
                            (!show_uid || pp->p_ruid == sel->uid) &&
                            (!show_pid || pp->p_pid == sel->pid) &&
-                           (!show_cmd || strstr(pp->p_comm,
-                               sel->command))) {
+                           (!show_cmd || cmd_matches(pp, sel->command))) {
                                *prefp++ = pp;
                                active_procs++;
                        }
@@ -462,27 +518,17 @@ state_abbr(struct kinfo_proc *pp)
 static char *
 format_comm(struct kinfo_proc *kp)
 {
-       static char **s, buf[MAX_COLS];
-       size_t siz = 100;
-       char **p;
-       int mib[4];
+       static char     buf[MAX_COLS];
+       char            **p, **s;
        extern int show_args;
 
        if (!show_args)
                return (kp->p_comm);
 
-       for (;; siz *= 2) {
-               if ((s = realloc(s, siz)) == NULL)
-                       err(1, NULL);
-               mib[0] = CTL_KERN;
-               mib[1] = KERN_PROC_ARGS;
-               mib[2] = kp->p_pid;
-               mib[3] = KERN_PROC_ARGV;
-               if (sysctl(mib, 4, s, &siz, NULL, 0) == 0)
-                       break;
-               if (errno != ENOMEM)
-                       return (kp->p_comm);
-       }
+       s = get_proc_args(kp);
+       if (s == NULL)
+               return (kp->p_comm);
+
        buf[0] = '\0';
        for (p = s; *p != NULL; p++) {
                if (p != s)
Index: top.1
===================================================================
RCS file: /home/edd/cvsync/src/usr.bin/top/top.1,v
retrieving revision 1.66
diff -u -p -r1.66 top.1
--- top.1       6 May 2015 07:53:29 -0000       1.66
+++ top.1       6 Feb 2016 15:03:50 -0000
@@ -107,7 +107,8 @@ The default is 1 for dumb terminals.
 .It Fl g Ar string
 Display only processes that contain
 .Ar string
-in their command name.
+in their command name. If displaying of arguments is enabled, the
+arguments are searched too.
 .It Fl H
 Show process threads in the display.
 Normally, only the main process is shown.
@@ -305,7 +306,8 @@ command.
 .It g Ar string
 Display only processes that contain
 .Ar string
-in their command name.
+in their command name. If displaying of arguments is enabled, the
+arguments are searched too.
 .Sq g+
 shows all processes.
 .It H

-- 
Best Regards
Edd Barrett

http://www.theunixzoo.co.uk

Reply via email to