Commit 3745488e authored by Daniel Axtens's avatar Daniel Axtens Committed by Greg Kroah-Hartman

altera-stapl: altera_get_note: prevent write beyond end of 'key'

altera_get_note is called from altera_init, where key is kzalloc(33).

When the allocation functions are annotated to allow the compiler to see
the sizes of objects, and with FORTIFY_SOURCE, we see:

In file included from drivers/misc/altera-stapl/altera.c:14:0:
In function ‘strlcpy’,
    inlined from ‘altera_init’ at drivers/misc/altera-stapl/altera.c:2189:5:
include/linux/string.h:378:4: error: call to ‘__write_overflow’ declared with attribute error: detected write beyond size of object passed as 1st parameter
    __write_overflow();
    ^~~~~~~~~~~~~~~~~~

That refers to this code in altera_get_note:

    if (key != NULL)
            strlcpy(key, &p[note_strings +
                            get_unaligned_be32(
                            &p[note_table + (8 * i)])],
                    length);

The error triggers because the length of 'key' is 33, but the copy
uses length supplied as the 'length' parameter, which is always
256. Split the size parameter into key_len and val_len, and use the
appropriate length depending on what is being copied.

Detected by compiler error, only compile-tested.

Cc: "Igor M. Liplianin" <liplianin@netup.ru>
Signed-off-by: default avatarDaniel Axtens <dja@axtens.net>
Link: https://lore.kernel.org/r/20200120074344.504-2-dja@axtens.netSigned-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/202002251042.D898E67AC@keescookSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 2669b8b0
...@@ -2112,8 +2112,8 @@ static int altera_execute(struct altera_state *astate, ...@@ -2112,8 +2112,8 @@ static int altera_execute(struct altera_state *astate,
return status; return status;
} }
static int altera_get_note(u8 *p, s32 program_size, static int altera_get_note(u8 *p, s32 program_size, s32 *offset,
s32 *offset, char *key, char *value, int length) char *key, char *value, int keylen, int vallen)
/* /*
* Gets key and value of NOTE fields in the JBC file. * Gets key and value of NOTE fields in the JBC file.
* Can be called in two modes: if offset pointer is NULL, * Can be called in two modes: if offset pointer is NULL,
...@@ -2170,7 +2170,7 @@ static int altera_get_note(u8 *p, s32 program_size, ...@@ -2170,7 +2170,7 @@ static int altera_get_note(u8 *p, s32 program_size,
&p[note_table + (8 * i) + 4])]; &p[note_table + (8 * i) + 4])];
if (value != NULL) if (value != NULL)
strlcpy(value, value_ptr, length); strlcpy(value, value_ptr, vallen);
} }
} }
...@@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size, ...@@ -2189,13 +2189,13 @@ static int altera_get_note(u8 *p, s32 program_size,
strlcpy(key, &p[note_strings + strlcpy(key, &p[note_strings +
get_unaligned_be32( get_unaligned_be32(
&p[note_table + (8 * i)])], &p[note_table + (8 * i)])],
length); keylen);
if (value != NULL) if (value != NULL)
strlcpy(value, &p[note_strings + strlcpy(value, &p[note_strings +
get_unaligned_be32( get_unaligned_be32(
&p[note_table + (8 * i) + 4])], &p[note_table + (8 * i) + 4])],
length); vallen);
*offset = i + 1; *offset = i + 1;
} }
...@@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw) ...@@ -2449,7 +2449,7 @@ int altera_init(struct altera_config *config, const struct firmware *fw)
__func__, (format_version == 2) ? "Jam STAPL" : __func__, (format_version == 2) ? "Jam STAPL" :
"pre-standardized Jam 1.1"); "pre-standardized Jam 1.1");
while (altera_get_note((u8 *)fw->data, fw->size, while (altera_get_note((u8 *)fw->data, fw->size,
&offset, key, value, 256) == 0) &offset, key, value, 32, 256) == 0)
printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n", printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
__func__, key, value); __func__, key, value);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment