Skip to content

Out-of-bounds read in parser #20

@lukaswittmann

Description

@lukaswittmann

While working on moist I had a interesting crash as detected by the sanitizer.

Details

==252082==ERROR: AddressSanitizer: global-buffer-overflow on address 0x5a79eead93a4 at pc 0x7e5739094658 bp 0x7fffe3099fe0 sp 0x7fffe3099788
READ of size 14 at 0x5a79eead93a4 thread T0
    #0 0x7e5739094657 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long) ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:860
    #1 0x7e5739094bc6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:892
    #2 0x7e5739094bc6 in __interceptor_memcmp ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:887
    #3 0x5a79ee99c1a5 in __fclap_parser_MOD_parser_add_argument ../subprojects/fclap/src/fclap/fclap_parser.f90:571
    #4 0x5a79ee9c0bd9 in __fclap_parser_MOD_parser_init ../subprojects/fclap/src/fclap/fclap_parser.f90:398
    #5 0x5a79ee7f1642 in __moist_cli_MOD_get_arguments ../app/cli.f90:100
    #6 0x5a79ee7dc67e in driver ../app/main.f90:15
    #7 0x5a79ee7dcd67 in main ../app/main.f90:6
    #8 0x7e5736c29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #9 0x7e5736c29e3f in __libc_start_main_impl ../csu/libc-start.c:392
    #10 0x5a79ee7db964 in _start (/home/wittmann/Documents/projects/software-programs/moist/build/app/moist+0x45964)

0x5a79eead93a4 is located 60 bytes to the left of global variable '*.LC396' defined in '../subprojects/fclap/src/fclap/fclap_parser.f90' (0x5a79eead93e0) of size 6
0x5a79eead93a4 is located 0 bytes to the right of global variable '*.LC395' defined in '../subprojects/fclap/src/fclap/fclap_parser.f90' (0x5a79eead93a0) of size 4
SUMMARY: AddressSanitizer: global-buffer-overflow ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:860 in MemcmpInterceptorCommon(void*, int (*)(void const*, void const*, unsigned long), void const*, void const*, unsigned long)
Shadow bytes around the buggy address:
  0x0b4fbdd53220: f9 f9 f9 f9 00 00 00 00 00 00 00 00 04 f9 f9 f9
  0x0b4fbdd53230: f9 f9 f9 f9 00 00 00 00 00 00 00 00 04 f9 f9 f9
  0x0b4fbdd53240: f9 f9 f9 f9 00 00 00 00 00 00 00 00 04 f9 f9 f9
  0x0b4fbdd53250: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 03 f9 f9
  0x0b4fbdd53260: f9 f9 f9 f9 00 00 00 00 00 00 00 00 04 f9 f9 f9
=>0x0b4fbdd53270: f9 f9 f9 f9[04]f9 f9 f9 f9 f9 f9 f9 06 f9 f9 f9
  0x0b4fbdd53280: f9 f9 f9 f9 02 f9 f9 f9 f9 f9 f9 f9 00 00 00 07
  0x0b4fbdd53290: f9 f9 f9 f9 07 f9 f9 f9 f9 f9 f9 f9 00 01 f9 f9
  0x0b4fbdd532a0: f9 f9 f9 f9 02 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0b4fbdd532b0: 06 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 00
  0x0b4fbdd532c0: 00 00 00 00 00 00 00 00 00 00 00 04 f9 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==252082==ABORTING

This is due to line

if (len(action) > 14 .and. action(1:14) == "not_less_than:") then
as the operand order is not specified. This yields an out-of-bounds error.
Also, I think it should be => as you allow a len of 14.
Minimal safe fix example:

            if (len(action) >= 14) then
                if (action(1:14) == "not_less_than:") then
                    act_type = ACT_NOT_LESS_THAN
                    handled = .true.
                end if
            end if

The same applies to the other occurances of such a pattern, e.g.:

else if (len(action) > 16 .and. action(1:16) == "not_bigger_than:") then

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions