-
Bug
-
Resolution: Unresolved
-
Normal
-
None
-
rhel-7.9.z
-
None
-
Moderate
-
rhel-sst-security-special-projects
-
ssg_security
-
None
-
False
-
-
None
-
None
-
- aide does not exists with error when file gets truncated
-
None
-
None
-
If docs needed, set a value
-
-
All
-
None
This bug was initially created as a copy of Bug #2062340
I am copying this bug because:
Also applies to RHEL7 (reproducer from RHEL7 actually)
Description of problem:
When aide is processing a file to compute its hash and the file gets truncated, SIGBUS signal pops up and aide prints a message:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
Caught SIGBUS/SEGV while mmapping. File was truncated while aide was running?
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
It then exits in error upon receiving a new SIGBUS again.
The root cause for this is aide internally maps the file in memory using mmap(), then the hash computation is done through calling libgcrypt routines which die upon accessing bad address (SIGBUS), due to the file being truncated.
Version-Release number of selected component (if applicable):
aide-0.15 (RHEL7) and 0.16 (RHEL8)
How reproducible:
Always
Steps to Reproduce: (RHEL7 code base, but similar, line numbers change a bit)
1. Create `/foo/file`
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
- mkdir /foo
- dd if=/dev/zero of=/foo/file bs=1M count=100
-
-
-
-
-
-
- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
-
-
-
-
-
-
2. Edit `/etc/aide.conf` to remove everything and add handling of `/foo`
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
[...]
#/boot/ CONTENT_EX
[... commented out until end ...]
/foo/ CONTENT_EX
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
3. Execute aide under GDB
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
- gdb --args aide --init
(gdb) break do_md.c:362
(gdb) run-
-
-
-
-
-
- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
-
-
-
-
-
-
4. Once GDB stopped, truncate the file
~~~
- truncate -s 0 /foo/file
~~~
5. Continue execution
~~~
(gdb) cont
~~~
Actual results:
SIGBUS caught once with proper message, but then again while `catch_mmap==0`, causing aide to exit:
~~~
Program received signal SIGBUS, Bus error.
transform (hd=hd@entry=0x7ffff7ff5290, data=0x7ffff4491001 <Address 0x7ffff4491001 out of bounds>,
data@entry=0x7ffff4491000 <Address 0x7ffff4491000 out of bounds>) at sha256.c:186
186 p2[3] = *data++;
(gdb) bt
#0 transform (hd=hd@entry=0x7ffff7ff5290, data=0x7ffff4491001 <Address 0x7ffff4491001 out of bounds>,
data@entry=0x7ffff4491000 <Address 0x7ffff4491000 out of bounds>) at sha256.c:186
#1 0x00007ffff789b04f in sha256_write (context=0x7ffff7ff5290, inbuf_arg=<optimized out>, inlen=16777216)
at sha256.c:291
#2 0x00007ffff7875f7f in md_write (a=0x7ffff7ff5008, inbuf=inbuf@entry=0x7ffff4491000, inlen=inlen@entry=16777216)
at md.c:800
#3 0x00007ffff7877145 in _gcry_md_write (hd=<optimized out>, inbuf=inbuf@entry=0x7ffff4491000,
inlen=inlen@entry=16777216) at md.c:808
#4 0x00007ffff7860772 in gcry_md_write (hd=<optimized out>, buffer=buffer@entry=0x7ffff4491000,
length=length@entry=16777216) at visibility.c:827
#5 0x000055555556ad43 in update_md (md=0x7fffffffdf50, data=0x7ffff4491000, size=16777216) at md.c:250
#6 0x0000555555567433 in calc_md (old_fs=old_fs@entry=0x7fffffffe190, line=line@entry=0x555555789850) at do_md.c:363
#7 0x000055555556a85b in get_file_attrs (filename=filename@entry=0x555555786d60 "/foo/file", attr=48320481308)
at gen_list.c:1365
#8 0x0000555555563d00 in db_readline_disk (db=db@entry=256) at db_disk.c:245
#9 0x0000555555563670 in db_readline (db=db@entry=256) at db.c:209
#10 0x000055555556a255 in populate_tree (tree=0x5555557857e0) at gen_list.c:1463
#11 0x00005555555577d0 in main (argc=<optimized out>, argv=<optimized out>) at aide.c:614
(gdb) break sig_handler
Breakpoint 6 at 0x55555556bef0: file util.c, line 326.
(gdb) cont
Continuing.
Breakpoint 6, sig_handler (signum=7) at util.c:326
326 {
(gdb) next
327 switch(signum){
(gdb)
330 error(200,"Caught SIGBUS/SIGSEGV\n");
(gdb)
331 if(conf->catch_mmap==1)
(gdb)
360 init_sighandler();
(gdb)
init_sighandler () at util.c:316
316 signal(SIGBUS,sig_handler);
(gdb)
315 {
(gdb)
316 signal(SIGBUS,sig_handler);
(gdb) cont
Continuing.
Program received signal SIGBUS, Bus error.
transform (hd=hd@entry=0x7ffff7ff5290, data=0x7ffff4491001 <Address 0x7ffff4491001 out of bounds>,
data@entry=0x7ffff4491000 <Address 0x7ffff4491000 out of bounds>) at sha256.c:186
186 p2[3] = *data++;
(gdb) bt
#0 transform (hd=hd@entry=0x7ffff7ff5290, data=0x7ffff4491001 <Address 0x7ffff4491001 out of bounds>,
data@entry=0x7ffff4491000 <Address 0x7ffff4491000 out of bounds>) at sha256.c:186
#1 0x00007ffff789b04f in sha256_write (context=0x7ffff7ff5290, inbuf_arg=<optimized out>, inlen=16777216)
at sha256.c:291
#2 0x00007ffff7875f7f in md_write (a=0x7ffff7ff5008, inbuf=inbuf@entry=0x7ffff4491000, inlen=inlen@entry=16777216)
at md.c:800
#3 0x00007ffff7877145 in _gcry_md_write (hd=<optimized out>, inbuf=inbuf@entry=0x7ffff4491000,
inlen=inlen@entry=16777216) at md.c:808
#4 0x00007ffff7860772 in gcry_md_write (hd=<optimized out>, buffer=buffer@entry=0x7ffff4491000,
length=length@entry=16777216) at visibility.c:827
#5 0x000055555556ad43 in update_md (md=0x7fffffffdf50, data=0x7ffff4491000, size=16777216) at md.c:250
#6 0x0000555555567433 in calc_md (old_fs=old_fs@entry=0x7fffffffe190, line=line@entry=0x555555789850) at do_md.c:363
#7 0x000055555556a85b in get_file_attrs (filename=filename@entry=0x555555786d60 "/foo/file", attr=48320481308)
at gen_list.c:1365
#8 0x0000555555563d00 in db_readline_disk (db=db@entry=256) at db_disk.c:245
#9 0x0000555555563670 in db_readline (db=db@entry=256) at db.c:209
#10 0x000055555556a255 in populate_tree (tree=0x5555557857e0) at gen_list.c:1463
#11 0x00005555555577d0 in main (argc=<optimized out>, argv=<optimized out>) at aide.c:614
(gdb) cont
Continuing.
Breakpoint 6, sig_handler (signum=7) at util.c:326
326 {
(gdb) next
327 switch(signum){
(gdb)
330 error(200,"Caught SIGBUS/SIGSEGV\n");
(gdb)
331 if(conf->catch_mmap==1){
(gdb)
335 error(0,"Caught SIGBUS/SEGV. Exiting\n");
(gdb)
Caught SIGBUS/SEGV. Exiting
336 exit(EXIT_FAILURE);
(gdb)
[Inferior 1 (process 3538) exited with code 01]
~~~
Expected results:
File rescanned and aide not exiting in error
Additional info:
To properly handle the signal, we would need to have aide code use some kind of `longjump` to restart the operation, it's not possible to continue executing the code being used (`gcry_xxx` functions which are not aware at all of the issue and just use the memory pointers as is). But I don't see how this can be done easily since there would be some memory deallocation to perform first or else aide would be leaking memory.