Commit 820874c75ea0d3a9c22d69d6eaad42a279d6756c

Authored by Jim Cromie
Committed by Greg Kroah-Hartman
1 parent 5ca7d2a6c5

dynamic_debug: tighten up error checking on debug queries

Issue error when a match-spec is given multiple times in a rule.
Previous code kept last one, but was silent about it.  Docs imply only
one is allowed by saying match-specs are ANDed together, given that
module M cannot match both A and B.  Also error when last_line < 1st_line.

Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Signed-off-by: Jason Baron <jbaron@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

Showing 1 changed file with 33 additions and 6 deletions Side-by-side Diff

... ... @@ -276,6 +276,19 @@
276 276 return str;
277 277 }
278 278  
  279 +static int check_set(const char **dest, char *src, char *name)
  280 +{
  281 + int rc = 0;
  282 +
  283 + if (*dest) {
  284 + rc = -EINVAL;
  285 + pr_err("match-spec:%s val:%s overridden by %s",
  286 + name, *dest, src);
  287 + }
  288 + *dest = src;
  289 + return rc;
  290 +}
  291 +
279 292 /*
280 293 * Parse words[] as a ddebug query specification, which is a series
281 294 * of (keyword, value) pairs chosen from these possibilities:
282 295  
... ... @@ -287,11 +300,15 @@
287 300 * format <escaped-string-to-find-in-format>
288 301 * line <lineno>
289 302 * line <first-lineno>-<last-lineno> // where either may be empty
  303 + *
  304 + * Only 1 of each type is allowed.
  305 + * Returns 0 on success, <0 on error.
290 306 */
291 307 static int ddebug_parse_query(char *words[], int nwords,
292 308 struct ddebug_query *query)
293 309 {
294 310 unsigned int i;
  311 + int rc;
295 312  
296 313 /* check we have an even number of words */
297 314 if (nwords % 2 != 0)
298 315  
299 316  
300 317  
301 318  
302 319  
303 320  
304 321  
... ... @@ -300,24 +317,32 @@
300 317  
301 318 for (i = 0 ; i < nwords ; i += 2) {
302 319 if (!strcmp(words[i], "func"))
303   - query->function = words[i+1];
  320 + rc = check_set(&query->function, words[i+1], "func");
304 321 else if (!strcmp(words[i], "file"))
305   - query->filename = words[i+1];
  322 + rc = check_set(&query->filename, words[i+1], "file");
306 323 else if (!strcmp(words[i], "module"))
307   - query->module = words[i+1];
  324 + rc = check_set(&query->module, words[i+1], "module");
308 325 else if (!strcmp(words[i], "format"))
309   - query->format = unescape(words[i+1]);
  326 + rc = check_set(&query->format, unescape(words[i+1]),
  327 + "format");
310 328 else if (!strcmp(words[i], "line")) {
311 329 char *first = words[i+1];
312 330 char *last = strchr(first, '-');
  331 + if (query->first_lineno || query->last_lineno) {
  332 + pr_err("match-spec:line given 2 times\n");
  333 + return -EINVAL;
  334 + }
313 335 if (last)
314 336 *last++ = '\0';
315 337 if (parse_lineno(first, &query->first_lineno) < 0)
316 338 return -EINVAL;
317   - if (last != NULL) {
  339 + if (last) {
318 340 /* range <first>-<last> */
319   - if (parse_lineno(last, &query->last_lineno) < 0)
  341 + if (parse_lineno(last, &query->last_lineno)
  342 + < query->first_lineno) {
  343 + pr_err("last-line < 1st-line\n");
320 344 return -EINVAL;
  345 + }
321 346 } else {
322 347 query->last_lineno = query->first_lineno;
323 348 }
... ... @@ -325,6 +350,8 @@
325 350 pr_err("unknown keyword \"%s\"\n", words[i]);
326 351 return -EINVAL;
327 352 }
  353 + if (rc)
  354 + return rc;
328 355 }
329 356  
330 357 if (verbose)