Closed
Description
If sadf utility reads following stat file, it causes memory corruption (SIGSEGV).
POC stat file
$ ./sadf ./memcorrupt_sadf.in
Segmentation Fault (core dumped)
A crash happens in following part in remap_struct():sa_common.c.
int remap_struct(unsigned int gtypes_nr[], unsigned int ftypes_nr[],
void *ps, unsigned int f_size, unsigned int g_size, size_t b_size)
{
if (d) {
n = MINIMUM(f_size - ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
g_size - gtypes_nr[0] * ULL_ALIGNMENT_WIDTH);
if ((ftypes_nr[0] * ULL_ALIGNMENT_WIDTH >= b_size) ||
(gtypes_nr[0] * ULL_ALIGNMENT_WIDTH + n > b_size) ||
(ftypes_nr[0] * ULL_ALIGNMENT_WIDTH + n > b_size))
return -1;
memmove(((char *) ps) + gtypes_nr[0] * ULL_ALIGNMENT_WIDTH,
((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH, n);
if (d > 0) {
memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
0, d * ULL_ALIGNMENT_WIDTH);
}
}If stat file has large file_magic->hdr_types_nr(ftypes_nr[0]), the calculation at ftypes_nr[0] * ULL_ALIGNMENT_WIDTH leads Integer Overflow and pass above size check,
then causes OOB access at memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH...)
Here is a crash log.
$ gdb -q ./sadf -c core
Program terminated with signal SIGSEGV, Segmentation fault.
(gdb) bt
#0 __memset_avx2_erms ()
at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:141
#1 0x00005631c893f919 in memset (__len=18446744073709551592, __ch=0,
__dest=<optimized out>)
at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:71
#2 remap_struct (gtypes_nr=gtypes_nr@entry=0x5631c8b59cb0 <hdr_types_nr>,
ftypes_nr=ftypes_nr@entry=0x7fff7f8bcf50, ps=ps@entry=0x5631c9916c90,
f_size=117, g_size=g_size@entry=328, b_size=117) at sa_common.c:1326
#3 0x00005631c8940628 in check_file_actlst (ifd=0x7fff7f8bcef0,
dfile=0x7fff7f8bd010 "./sadf_crash.in", act=0x5631c8b57060 <act>, flags=0,
file_magic=0x7fff7f8bcf40, file_hdr=0x5631c8b60c60 <file_hdr>,
file_actlst=0x7fff7f8bcef8, id_seq=0x5631c8b60dc0 <id_seq>, ignore=0,
endian_mismatch=0x5631c8b59da8 <endian_mismatch>,
arch_64=0x5631c8b59da4 <arch_64>) at sa_common.c:1881
#4 0x00005631c890c70f in read_stats_from_file (
dfile=0x7fff7f8bd010 "./sadf_crash.in", pcparchive=0x7fff7f8bd210 "")
at sadf.c:1443
#5 0x00005631c890964d in main (argc=2, argv=0x7fff7f8bd538) at sadf.c:1866
(gdb) up
#1 0x00005631c893f919 in memset (__len=18446744073709551592, __ch=0,
__dest=<optimized out>)
at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:71
71 return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
(gdb)
#2 remap_struct (gtypes_nr=gtypes_nr@entry=0x5631c8b59cb0 <hdr_types_nr>,
ftypes_nr=ftypes_nr@entry=0x7fff7f8bcf50, ps=ps@entry=0x5631c9916c90,
f_size=117, g_size=g_size@entry=328, b_size=117) at sa_common.c:1326
1326 memset(((char *) ps) + ftypes_nr[0] * ULL_ALIGNMENT_WIDTH,
(gdb) p/x ftypes_nr[0]
$1 = 0x80000004
(gdb) p/x ftypes_nr[0] * 8
$2 = 0x20
Thanks
Metadata
Metadata
Assignees
Labels
No labels