Uploaded image for project: 'RHEL'
  1. RHEL
  2. RHEL-1569

aide detects SIGBUS then exits in error when a file gets truncated

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Normal Normal
    • None
    • rhel-7.9.z
    • aide
    • None
    • Moderate
    • rhel-sst-security-special-projects
    • ssg_security
    • None
    • False
    • Hide

      None

      Show
      None
    • None
    • None
      • aide does not exists with error when file gets truncated
    • None
    • None
    • If docs needed, set a value
    • 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< --------

      1. mkdir /foo
      2. 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< --------

      1. gdb --args aide --init
        (gdb) break do_md.c:362
        (gdb) run
                    • 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

      4. Once GDB stopped, truncate the file

      ~~~

      1. 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.

              rsroka@redhat.com Radovan Sroka
              rhn-support-rmetrich Renaud Métrich
              Radovan Sroka Radovan Sroka
              SSG Security QE SSG Security QE
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated: