mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdump/dfi_vmcoreinfo: Validate vmcoreinfo value length before memcpy
vmcoreinfo_item() copies a key's value string from the vmcoreinfo heap blob into the caller's buffer using memcpy() without checking the source length. The length is derived from the distance between the '=' separator and the next '\n' (or '\0') in the blob, which is bounded only by the total vmcoreinfo size. A crafted dump with a vmcoreinfo value >= 1024 bytes would overflow the buffer. Additionally, the len parameter of vmcoreinfo_item() was declared UNUSED and never checked. Fix by computing val_len before the copy and returning -1 if val_len >= len. Change len type from int to size_t, which is natural for a buffer size, drops the need for a negativity guard, and makes the call site passing sizeof(str) type-consistent. Write directly into the caller's buf, instead of going through the intermediate str[]. Replace two strchr() calls with a single strchrnul(). Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com> Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
d3ac9f3365
commit
405b2da3f3
@@ -169,13 +169,14 @@ const char *dfi_vmcoreinfo_get(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic function: Return vmcoreinfo item (-1 on failure)
|
* Generic function: Return vmcoreinfo item (-1 on failure).
|
||||||
*/
|
*/
|
||||||
static int vmcoreinfo_item(char *buf, int UNUSED(len), const char *fmt,
|
static int vmcoreinfo_item(char *buf, size_t len, const char *fmt,
|
||||||
const char *sym)
|
const char *sym)
|
||||||
{
|
{
|
||||||
|
|
||||||
char str[1024], *sym_str, *sym_str_end;
|
char str[1024], *sym_str, *sym_str_end;
|
||||||
|
size_t val_len;
|
||||||
|
|
||||||
if (!l.vmcoreinfo)
|
if (!l.vmcoreinfo)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -187,12 +188,12 @@ static int vmcoreinfo_item(char *buf, int UNUSED(len), const char *fmt,
|
|||||||
if (!sym_str)
|
if (!sym_str)
|
||||||
return -1;
|
return -1;
|
||||||
sym_str += strlen(str);
|
sym_str += strlen(str);
|
||||||
sym_str_end = strchr(sym_str, '\n');
|
sym_str_end = strchrnul(sym_str, '\n');
|
||||||
if (!sym_str_end)
|
val_len = (size_t)(sym_str_end - sym_str);
|
||||||
sym_str_end = strchr(sym_str, '\0');
|
if (val_len >= len)
|
||||||
memset(str, 0, sizeof(str));
|
return -1;
|
||||||
memcpy(str, sym_str, (unsigned long) (sym_str_end - sym_str));
|
memcpy(buf, sym_str, val_len);
|
||||||
strcpy(buf, str);
|
buf[val_len] = '\0';
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +217,7 @@ static int vmcoreinfo_item_ulong(unsigned long *val, const char *fmt,
|
|||||||
/*
|
/*
|
||||||
* Return vmcoreinfo tag (-1 on failure)
|
* Return vmcoreinfo tag (-1 on failure)
|
||||||
*/
|
*/
|
||||||
int dfi_vmcoreinfo_tag(char *str, int len, const char *sym)
|
int dfi_vmcoreinfo_tag(char *str, size_t len, const char *sym)
|
||||||
{
|
{
|
||||||
return vmcoreinfo_item(str, len, NULL, sym);
|
return vmcoreinfo_item(str, len, NULL, sym);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
void dfi_vmcoreinfo_init(void);
|
void dfi_vmcoreinfo_init(void);
|
||||||
const char *dfi_vmcoreinfo_get(void);
|
const char *dfi_vmcoreinfo_get(void);
|
||||||
int dfi_vmcoreinfo_tag(char *str, int len, const char *sym);
|
int dfi_vmcoreinfo_tag(char *str, size_t len, const char *sym);
|
||||||
int dfi_vmcoreinfo_symbol(unsigned long *val, const char *sym);
|
int dfi_vmcoreinfo_symbol(unsigned long *val, const char *sym);
|
||||||
int dfi_vmcoreinfo_offset(unsigned long *offs, const char *sym);
|
int dfi_vmcoreinfo_offset(unsigned long *offs, const char *sym);
|
||||||
int dfi_vmcoreinfo_size(unsigned long *size, const char *sym);
|
int dfi_vmcoreinfo_size(unsigned long *size, const char *sym);
|
||||||
|
|||||||
Reference in New Issue
Block a user