On Fri, Dec 14, 2018 at 09:15:08AM -0800, Suren Baghdasaryan wrote: > +ssize_t psi_trigger_parse(char *buf, size_t nbytes, enum psi_res res, > + enum psi_states *state, u32 *threshold_us, u32 *win_sz_us) > +{ > + bool some; > + bool threshold_pct; > + u32 threshold; > + u32 win_sz; > + char *p; > + > + p = strsep(&buf, " "); > + if (p == NULL) > + return -EINVAL; > + > + /* parse type */ > + if (!strcmp(p, "some")) > + some = true; > + else if (!strcmp(p, "full")) > + some = false; > + else > + return -EINVAL; > + > + switch (res) { > + case (PSI_IO): > + *state = some ? PSI_IO_SOME : PSI_IO_FULL; > + break; > + case (PSI_MEM): > + *state = some ? PSI_MEM_SOME : PSI_MEM_FULL; > + break; > + case (PSI_CPU): > + if (!some) > + return -EINVAL; > + *state = PSI_CPU_SOME; > + break; > + default: > + return -EINVAL; > + } > + > + while (isspace(*buf)) > + buf++; > + > + p = strsep(&buf, "%"); > + if (p == NULL) > + return -EINVAL; > + > + if (buf == NULL) { > + /* % sign was not found, threshold is specified in us */ > + buf = p; > + p = strsep(&buf, " "); > + if (p == NULL) > + return -EINVAL; > + > + threshold_pct = false; > + } else > + threshold_pct = true; > + > + /* parse threshold */ > + if (kstrtouint(p, 0, &threshold)) > + return -EINVAL; > + > + while (isspace(*buf)) > + buf++; > + > + p = strsep(&buf, " "); > + if (p == NULL) > + return -EINVAL; > + > + /* Parse window size */ > + if (kstrtouint(p, 0, &win_sz)) > + return -EINVAL; > + > + /* Check window size */ > + if (win_sz < PSI_TRIG_MIN_WIN_US || win_sz > PSI_TRIG_MAX_WIN_US) > + return -EINVAL; > + > + if (threshold_pct) > + threshold = (threshold * win_sz) / 100; > + > + /* Check threshold */ > + if (threshold == 0 || threshold > win_sz) > + return -EINVAL; > + > + *threshold_us = threshold; > + *win_sz_us = win_sz; > + > + return 0; > +} How well has this thing been fuzzed? Custom string parser, yay!