summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Van Assche <bvanassche@acm.org>2020-05-23 20:39:47 -0700
committerBart Van Assche <bvanassche@acm.org>2020-05-23 20:46:42 -0700
commit969b9fbbf4fadbe48eb4d9fea071837d2d3eeb11 (patch)
tree8d89252d657dc2608d96f8a6e3ff5bf6832a9cbc
parent26f14c3162309115c87ed49fd4082e8cc27545d6 (diff)
downloadfio-969b9fbbf4fadbe48eb4d9fea071837d2d3eeb11.tar.gz
fio-969b9fbbf4fadbe48eb4d9fea071837d2d3eeb11.tar.bz2
Do not read past the end of fmt_desc[]
Callers of parse_format() pass a size in bytes while the parse_format() function itself expects a number of elements. Fix this by making the fmt_desc[] array NULL-terminated. This patch fixes the following Coverity complaint: CID 300986 (#1 of 1): Out-of-bounds access (OVERRUN) overrun-buffer-arg: Overrunning array fmt_desc of 1 24-byte elements by passing it to a function which accesses it at element index 23 (byte offset 575) using argument 24U. Cc: Roman Pen <r.peniaev@gmail.com> Fixes: 634bd210c17a ("lib/pattern: add set of functions to parse combined pattern input") Signed-off-by: Bart Van Assche <bvanassche@acm.org>
-rw-r--r--lib/pattern.c11
-rw-r--r--lib/pattern.h1
-rw-r--r--options.c7
3 files changed, 7 insertions, 12 deletions
diff --git a/lib/pattern.c b/lib/pattern.c
index 04d30657..680a12be 100644
--- a/lib/pattern.c
+++ b/lib/pattern.c
@@ -205,7 +205,6 @@ static const char *parse_number(const char *beg, char *out,
* @parsed - number of bytes which were already parsed so far
* @out_len - length of the output buffer
* @fmt_desc - format descriptor array, what we expect to find
- * @fmt_desc_sz - size of the format descriptor array
* @fmt - format array, the output
* @fmt_sz - size of format array
*
@@ -223,19 +222,18 @@ static const char *parse_number(const char *beg, char *out,
static const char *parse_format(const char *in, char *out, unsigned int parsed,
unsigned int out_len, unsigned int *filled,
const struct pattern_fmt_desc *fmt_desc,
- unsigned int fmt_desc_sz,
struct pattern_fmt *fmt, unsigned int fmt_sz)
{
int i;
struct pattern_fmt *f = NULL;
unsigned int len = 0;
- if (!out_len || !fmt_desc || !fmt_desc_sz || !fmt || !fmt_sz)
+ if (!out_len || !fmt_desc || !fmt || !fmt_sz)
return NULL;
assert(*in == '%');
- for (i = 0; i < fmt_desc_sz; i++) {
+ for (i = 0; fmt_desc[i].fmt; i++) {
const struct pattern_fmt_desc *desc;
desc = &fmt_desc[i];
@@ -267,7 +265,6 @@ static const char *parse_format(const char *in, char *out, unsigned int parsed,
* @out - output buffer where parsed result will be put
* @out_len - lengths of the output buffer
* @fmt_desc - array of pattern format descriptors [input]
- * @fmt_desc_sz - size of the format descriptor array
* @fmt - array of pattern formats [output]
* @fmt_sz - pointer where the size of pattern formats array stored [input],
* after successfull parsing this pointer will contain the number
@@ -311,7 +308,6 @@ static const char *parse_format(const char *in, char *out, unsigned int parsed,
int parse_and_fill_pattern(const char *in, unsigned int in_len,
char *out, unsigned int out_len,
const struct pattern_fmt_desc *fmt_desc,
- unsigned int fmt_desc_sz,
struct pattern_fmt *fmt,
unsigned int *fmt_sz_out)
{
@@ -340,8 +336,7 @@ int parse_and_fill_pattern(const char *in, unsigned int in_len,
break;
case '%':
end = parse_format(beg, out, out - out_beg, out_len,
- &filled, fmt_desc, fmt_desc_sz,
- fmt, fmt_rem);
+ &filled, fmt_desc, fmt, fmt_rem);
parsed_fmt = 1;
break;
default:
diff --git a/lib/pattern.h b/lib/pattern.h
index 2d655ad0..a6d9d6b4 100644
--- a/lib/pattern.h
+++ b/lib/pattern.h
@@ -24,7 +24,6 @@ struct pattern_fmt {
int parse_and_fill_pattern(const char *in, unsigned int in_len,
char *out, unsigned int out_len,
const struct pattern_fmt_desc *fmt_desc,
- unsigned int fmt_desc_sz,
struct pattern_fmt *fmt,
unsigned int *fmt_sz_out);
diff --git a/options.c b/options.c
index bb450fff..85a0f490 100644
--- a/options.c
+++ b/options.c
@@ -24,7 +24,8 @@ static const struct pattern_fmt_desc fmt_desc[] = {
.fmt = "%o",
.len = FIELD_SIZE(struct io_u *, offset),
.paste = paste_blockoff
- }
+ },
+ { }
};
/*
@@ -1339,7 +1340,7 @@ static int str_buffer_pattern_cb(void *data, const char *input)
/* FIXME: for now buffer pattern does not support formats */
ret = parse_and_fill_pattern(input, strlen(input), td->o.buffer_pattern,
- MAX_PATTERN_SIZE, NULL, 0, NULL, NULL);
+ MAX_PATTERN_SIZE, NULL, NULL, NULL);
if (ret < 0)
return 1;
@@ -1388,7 +1389,7 @@ static int str_verify_pattern_cb(void *data, const char *input)
td->o.verify_fmt_sz = ARRAY_SIZE(td->o.verify_fmt);
ret = parse_and_fill_pattern(input, strlen(input), td->o.verify_pattern,
- MAX_PATTERN_SIZE, fmt_desc, sizeof(fmt_desc),
+ MAX_PATTERN_SIZE, fmt_desc,
td->o.verify_fmt, &td->o.verify_fmt_sz);
if (ret < 0)
return 1;