Skip to content
  • Leo Yan's avatar
    af8490eb
    perf tests: Fix out of bounds memory access · af8490eb
    Leo Yan authored
    
    
    The test case 'Read backward ring buffer' failed on 32-bit architectures
    which were found by LKFT perf testing.  The test failed on arm32 x15
    device, qemu_arm32, qemu_i386, and found intermittent failure on i386;
    the failure log is as below:
    
      50: Read backward ring buffer                  :
      --- start ---
      test child forked, pid 510
      Using CPUID GenuineIntel-6-9E-9
      mmap size 1052672B
      mmap size 8192B
      Finished reading overwrite ring buffer: rewind
      free(): invalid next size (fast)
      test child interrupted
      ---- end ----
      Read backward ring buffer: FAILED!
    
    The log hints there have issue for memory usage, thus free() reports
    error 'invalid next size' and directly exit for the case.  Finally, this
    issue is root caused as out of bounds memory access for the data array
    'evsel->id'.
    
    The backward ring buffer test invokes do_test() twice.  'evsel->id' is
    allocated at the first call with the flow:
    
      test__backward_ring_buffer()
        `-> do_test()
    	  `-> evlist__mmap()
    	        `-> evlist__mmap_ex()
    	              `-> perf_evsel__alloc_id()
    
    So 'evsel->id' is allocated with one item, and it will be used in
    function perf_evlist__id_add():
    
       evsel->id[0] = id
       evsel->ids   = 1
    
    At the second call for do_test(), it skips to initialize 'evsel->id'
    and reuses the array which is allocated in the first call.  But
    'evsel->ids' contains the stale value.  Thus:
    
       evsel->id[1] = id    -> out of bound access
       evsel->ids   = 2
    
    To fix this issue, we will use evlist__open() and evlist__close() pair
    functions to prepare and cleanup context for evlist; so 'evsel->id' and
    'evsel->ids' can be initialized properly when invoke do_test() and avoid
    the out of bounds memory access.
    
    Fixes: ee74701e ("perf tests: Add test to check backward ring buffer")
    Signed-off-by: default avatarLeo Yan <leo.yan@linaro.org>
    Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Naresh Kamboju <naresh.kamboju@linaro.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Wang Nan <wangnan0@huawei.com>
    Cc: stable@vger.kernel.org # v4.10+
    Link: http://lore.kernel.org/lkml/20191107020244.2427-1-leo.yan@linaro.org
    
    
    Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    af8490eb
    perf tests: Fix out of bounds memory access
    Leo Yan authored
    
    
    The test case 'Read backward ring buffer' failed on 32-bit architectures
    which were found by LKFT perf testing.  The test failed on arm32 x15
    device, qemu_arm32, qemu_i386, and found intermittent failure on i386;
    the failure log is as below:
    
      50: Read backward ring buffer                  :
      --- start ---
      test child forked, pid 510
      Using CPUID GenuineIntel-6-9E-9
      mmap size 1052672B
      mmap size 8192B
      Finished reading overwrite ring buffer: rewind
      free(): invalid next size (fast)
      test child interrupted
      ---- end ----
      Read backward ring buffer: FAILED!
    
    The log hints there have issue for memory usage, thus free() reports
    error 'invalid next size' and directly exit for the case.  Finally, this
    issue is root caused as out of bounds memory access for the data array
    'evsel->id'.
    
    The backward ring buffer test invokes do_test() twice.  'evsel->id' is
    allocated at the first call with the flow:
    
      test__backward_ring_buffer()
        `-> do_test()
    	  `-> evlist__mmap()
    	        `-> evlist__mmap_ex()
    	              `-> perf_evsel__alloc_id()
    
    So 'evsel->id' is allocated with one item, and it will be used in
    function perf_evlist__id_add():
    
       evsel->id[0] = id
       evsel->ids   = 1
    
    At the second call for do_test(), it skips to initialize 'evsel->id'
    and reuses the array which is allocated in the first call.  But
    'evsel->ids' contains the stale value.  Thus:
    
       evsel->id[1] = id    -> out of bound access
       evsel->ids   = 2
    
    To fix this issue, we will use evlist__open() and evlist__close() pair
    functions to prepare and cleanup context for evlist; so 'evsel->id' and
    'evsel->ids' can be initialized properly when invoke do_test() and avoid
    the out of bounds memory access.
    
    Fixes: ee74701e ("perf tests: Add test to check backward ring buffer")
    Signed-off-by: default avatarLeo Yan <leo.yan@linaro.org>
    Reviewed-by: default avatarJiri Olsa <jolsa@kernel.org>
    Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Namhyung Kim <namhyung@kernel.org>
    Cc: Naresh Kamboju <naresh.kamboju@linaro.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Wang Nan <wangnan0@huawei.com>
    Cc: stable@vger.kernel.org # v4.10+
    Link: http://lore.kernel.org/lkml/20191107020244.2427-1-leo.yan@linaro.org
    
    
    Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Loading