Bug 2062340
| Summary: | aide detects SIGBUS then exits in error when a file gets truncated | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Renaud Métrich <rmetrich> |
| Component: | aide | Assignee: | Radovan Sroka <rsroka> |
| Status: | CLOSED MIGRATED | QA Contact: | Martin Zelený <mzeleny> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 8.5 | CC: | dapospis |
| Target Milestone: | rc | Keywords: | MigratedToJIRA, Triaged |
| Target Release: | --- | Flags: | pm-rhel:
mirror+
|
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2023-08-16 15:19:47 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
This was fixed Upstream recently: https://github.com/aide/aide/commit/667fb9427000c7203df5f396f6762f3e9a53dec8 This bug is going to be migrated. Contact point for migration questions or issues: rsroka Guidance for Bugzilla users to test their Jira account or create one if needed: https://redhat.service-now.com/help?id=kb_article_view&sysparm_article=KB0016394 https://redhat.service-now.com/help?id=kb_article_view&sysparm_article=KB0016694 https://redhat.service-now.com/help?id=kb_article_view&sysparm_article=KB0016774 |
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) 332 error(4,"Caught SIGBUS/SEGV while mmapping. File was truncated while aide was running?\n"); (gdb) Caught SIGBUS/SEGV while mmapping. File was truncated while aide was running? 333 conf->catch_mmap=0; (gdb) 359 error(220,"Caught signal %d\n",signum); (gdb) 363 } (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.