pgrep: check sanity of SC_ARG_MAX

A kernel change means we cannot trust what sysconf(SC_ARG_MAX)
returns. We clamp it so its more than 4096 and less than 128*1024
which is what findutils does.

References:
 procps-ng/procps#152
 https://git.savannah.gnu.org/cgit/findutils.git/tree/lib/buildcmd.c#n535
 https://lwn.net/Articles/727862/
 commit bb96fc4295
This commit is contained in:
Craig Small 2020-01-05 15:19:41 +11:00
parent 7ef9289ae9
commit 416b91836a

23
pgrep.c
View File

@ -477,6 +477,27 @@ static regex_t * do_regcomp (void)
return preg;
}
/*
* SC_ARG_MAX used to return the maximum size a command line can be
* however changes to the kernel mean this can be bigger than we can
* alloc. Clamp it to 128kB like xargs and friends do
* Should also not be smaller than POSIX_ARG_MAX which is 4096
*/
static size_t get_arg_max(void)
{
#define MIN_ARG_SIZE 4096u
#define MAX_ARG_SIZE (128u * 1024u)
size_t val = sysconf(_SC_ARG_MAX);
if (val < MIN_ARG_SIZE)
val = MIN_ARG_SIZE;
if (val > MAX_ARG_SIZE)
val = MAX_ARG_SIZE;
return val;
}
static struct el * select_procs (int *num)
{
#define PIDS_GETINT(e) PIDS_VAL(EU_ ## e, s_int, stack, info)
@ -494,7 +515,7 @@ static struct el * select_procs (int *num)
regex_t *preg;
pid_t myself = getpid();
struct el *list = NULL;
long cmdlen = sysconf(_SC_ARG_MAX) * sizeof(char);
long cmdlen = get_arg_max() * sizeof(char);
char *cmdline = xmalloc(cmdlen);
char *cmdsearch = xmalloc(cmdlen);
char *cmdoutput = xmalloc(cmdlen);