Bug 55417 - [4.8 Regression] AddressSanitizer reports stack-buffer-overflow in profiling code
Summary: [4.8 Regression] AddressSanitizer reports stack-buffer-overflow in profiling ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: gcov-profile (show other bugs)
Version: 4.8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
: 55407 (view as bug list)
Depends on:
Blocks:
 
Reported: 2012-11-20 18:51 UTC by Markus Trippelsdorf
Modified: 2012-11-21 16:06 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2012-11-21 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2012-11-20 18:51:26 UTC
% g++ -fprofile-generate -O3 -march=native tramp3d-v4.cpp
 % ./a.out --cartvis 1.0 0.0 --rhomin 1e-8 -n 20
...

(gcc built with gcc's address-sanitizer)
 % /var/tmp/gcc_sani_gcc/usr/local/bin/g++ -w -fprofile-use -O3 -march=native tramp3d-v4.cpp 2>&1 | asan_symbolize.py | c++filt
=================================================================
==12985== ERROR: AddressSanitizer stack-buffer-overflow on address 0x7ffff9616080 at pc 0x12c1613 bp 0x7ffff9615b60 sp 0x7ffff9615b58
READ of size 8 at 0x7ffff9616080 thread T0
    #0 0x12c1612 in compute_working_sets /home/markus/gcc/gcc/profile.c:294
Address 0x7ffff9616080 is located at offset 1184 in frame <compute_branch_probabilities> of T0's stack:
  This frame has 2 object(s):
    [32, 112) 'hist_br_prob'
    [160, 1184) 'working_set_cum_values'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism
      (longjmp and C++ exceptions *are* supported)
Shadow byte and word:
  0x1fffff2c2c10: f3
  0x1fffff2c2c10: f3 f3 f3 f3 00 00 00 00
More shadow bytes:
  0x1fffff2c2bf0: 00 00 00 00 00 00 00 00
  0x1fffff2c2bf8: 00 00 00 00 00 00 00 00
  0x1fffff2c2c00: 00 00 00 00 00 00 00 00
  0x1fffff2c2c08: 00 00 00 00 00 00 00 00
=>0x1fffff2c2c10: f3 f3 f3 f3 00 00 00 00
  0x1fffff2c2c18: 00 00 00 00 00 00 00 00
  0x1fffff2c2c20: 00 00 00 00 00 00 00 00
  0x1fffff2c2c28: 00 00 00 00 00 00 00 00
  0x1fffff2c2c30: 00 00 00 00 00 00 00 00
Stats: 6791M malloced (6303M for red zones) by 9376941 calls
Stats: 56M realloced by 304143 calls
Stats: 6701M freed by 9250298 calls
Stats: 6668M really freed by 9204559 calls
Stats: 323M (82726 full pages) mmaped in 620 calls
  mmaps   by size class: 7:139230; 8:26611; 9:7161; 10:2044; 11:3060; 12:16256; 13:19264; 14:576; 15:1184; 16:96; 17:16; 18:6; 19:3; 20:3; 21:4; 22:1;
  mallocs by size class: 7:5705562; 8:1531884; 9:365712; 10:67535; 11:73243; 12:1213506; 13:240088; 14:40078; 15:139014; 16:242; 17:39; 18:18; 19:7; 20:5; 21:7; 22:1;
  frees   by size class: 7:5603422; 8:1521617; 9:365436; 10:67516; 11:73162; 12:1212827; 13:226955; 14:40078; 15:139010; 16:204; 17:39; 18:16; 19:7; 20:5; 21:4;
  rfrees  by size class: 7:5575038; 8:1513474; 9:363702; 10:67156; 11:72856; 12:1208081; 13:225869; 14:39895; 15:138214; 16:204; 17:39; 18:16; 19:7; 20:5; 21:3;
Stats: malloc large: 139333 small slow: 278410
==12985== ABORTING

(gcc built with clang's address-sanitizer)
 % /var/tmp/gcc_sani_clang/usr/local/bin/g++ -w -fprofile-use -O3 -march=native tramp3d-v4.cpp 2>&1 | asan_symbolize.py | c++filt
=================================================================
==13020== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff6d236680 at pc 0x1393105 bp 0x7fff6d236090 sp 0x7fff6d236088
READ of size 8 at 0x7fff6d236680 thread T0
    #0 0x1393104 in get_exec_counts(unsigned int, unsigned int) /home/markus/gcc/gcc/profile.c:294
    #1 0x16de490 in tree_profiling() /home/markus/gcc/gcc/tree-profile.c:483
Address 0x7fff6d236680 is located at offset 1312 in frame <branch_prob()> of T0's stack:
  This frame has 15 object(s):
    [32, 60) 'n_histogram_counters.i'
    [96, 152) 'histogram_counts.i'
    [192, 248) 'act_count.i'
    [288, 1312) 'working_set_cum_values.i.i.i'
    [1344, 1424) 'hist_br_prob.i'
    [1472, 1504) ''
    [1536, 1568) ''
    [1600, 1608) 'values'
    [1664, 1696) ''
    [1728, 1760) ''
    [1792, 1824) ''
    [1856, 1888) ''
    [1920, 1924) 'offset8'
    [1984, 2016) 'curr_location'
    [2048, 2080) 'curr_location9'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism
      (longjmp and C++ exceptions *are* supported)
Shadow byte and word:
  0x1fffeda46cd0: f2
  0x1fffeda46cd0: f2 f2 f2 f2 00 00 00 00
More shadow bytes:
  0x1fffeda46cb0: 00 00 00 00 00 00 00 00
  0x1fffeda46cb8: 00 00 00 00 00 00 00 00
  0x1fffeda46cc0: 00 00 00 00 00 00 00 00
  0x1fffeda46cc8: 00 00 00 00 00 00 00 00
=>0x1fffeda46cd0: f2 f2 f2 f2 00 00 00 00
  0x1fffeda46cd8: 00 00 00 00 00 00 f4 f4
  0x1fffeda46ce0: f2 f2 f2 f2 00 00 00 00
  0x1fffeda46ce8: f2 f2 f2 f2 00 00 00 00
  0x1fffeda46cf0: f2 f2 f2 f2 00 f4 f4 f4
Stats: 6791M malloced (6302M for red zones) by 9367325 calls
Stats: 56M realloced by 303356 calls
Stats: 6701M freed by 9242907 calls
Stats: 6668M really freed by 9197073 calls
Stats: 322M (82470 full pages) mmaped in 618 calls
  mmaps   by size class: 7:135135; 8:24564; 9:7161; 10:2044; 11:3060; 12:16256; 13:19264; 14:576; 15:1184; 16:96; 17:16; 18:6; 19:3; 20:3; 21:4; 22:1;
  mallocs by size class: 7:5696469; 8:1531371; 9:365711; 10:67535; 11:73244; 12:1213506; 13:240081; 14:40076; 15:139014; 16:241; 17:39; 18:18; 19:7; 20:5; 21:7; 22:1;
  frees   by size class: 7:5594161; 8:1523495; 9:365437; 10:67516; 11:73162; 12:1212827; 13:226948; 14:40076; 15:139010; 16:204; 17:39; 18:16; 19:7; 20:5; 21:4;
  rfrees  by size class: 7:5565685; 8:1515347; 9:363703; 10:67156; 11:72856; 12:1208083; 13:225862; 14:39893; 15:138214; 16:204; 17:39; 18:16; 19:7; 20:5; 21:3;
Stats: malloc large: 139332 small slow: 278368
==13020== ABORTING
Comment 1 Markus Trippelsdorf 2012-11-20 21:06:46 UTC
Valgrind shows:

 % /var/tmp/gcc_valgrind/usr/local/bin/g++ -w -fprofile-use -O3 /home/markus/bench.cpp                                   
==522== Conditional jump or move depends on uninitialised value(s)
==522==    at 0x9E082B: compute_branch_probabilities(unsigned int, unsigned int) (profile.c:294)
==522==    by 0x9E2544: branch_prob() (profile.c:1371)
==522==    by 0xAFF5F5: tree_profiling() (tree-profile.c:483)
==522==    by 0x9CBD2A: execute_one_pass(opt_pass*) (passes.c:2327)
==522==    by 0x9CC789: execute_ipa_pass_list(opt_pass*) (passes.c:2692)
==522==    by 0x79429F: compile() (cgraphunit.c:1869)
==522==    by 0x794B99: finalize_compilation_unit() (cgraphunit.c:2120)
==522==    by 0x5B4A0E: cp_write_global_declarations() (decl2.c:4287)
==522==    by 0xA6D5BC: compile_file() (toplev.c:559)
==522==    by 0xA6F479: toplev_main(int, char**) (toplev.c:1881)
==522==    by 0x4ECD894: (below main) (libc-start.c:258)
==522== 
 %
Comment 2 Teresa Johnson 2012-11-21 05:51:12 UTC
The following patch should fix it. I am running regression testing
now, but am leaving town imminently for several days and can send the
patch for review when I get back Sunday.

Teresa

2012-11-20  Teresa Johnson  <tejohnson@google.com>

        PR gcov-profile/55417
        * profile.c (compute_working_sets): Check index first
        to avoid out-of-bounds array access.

Index: profile.c
===================================================================
--- profile.c   (revision 193614)
+++ profile.c   (working copy)
@@ -291,8 +291,8 @@ compute_working_sets (void)
           /* Next walk through successive working set entries and fill in
             the statistics for any whose size we have reached by accumulating
             this histogram counter.  */
-          while (tmp_cum >= working_set_cum_values[ws_ix]
-                 && ws_ix < NUM_GCOV_WORKING_SETS)
+          while (ws_ix < NUM_GCOV_WORKING_SETS
+                 && tmp_cum >= working_set_cum_values[ws_ix])
             {
               gcov_working_sets[ws_ix].num_counters = count;
               gcov_working_sets[ws_ix].min_counter

On Tue, Nov 20, 2012 at 1:06 PM, markus at trippelsdorf dot de
<gcc-bugzilla@gcc.gnu.org> wrote:
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=55417
>
> --- Comment #1 from Markus Trippelsdorf <markus at trippelsdorf dot de> 2012-11-20 21:06:46 UTC ---
> Valgrind shows:
>
>  % /var/tmp/gcc_valgrind/usr/local/bin/g++ -w -fprofile-use -O3
> /home/markus/bench.cpp
> ==522== Conditional jump or move depends on uninitialised value(s)
> ==522==    at 0x9E082B: compute_branch_probabilities(unsigned int, unsigned
> int) (profile.c:294)
> ==522==    by 0x9E2544: branch_prob() (profile.c:1371)
> ==522==    by 0xAFF5F5: tree_profiling() (tree-profile.c:483)
> ==522==    by 0x9CBD2A: execute_one_pass(opt_pass*) (passes.c:2327)
> ==522==    by 0x9CC789: execute_ipa_pass_list(opt_pass*) (passes.c:2692)
> ==522==    by 0x79429F: compile() (cgraphunit.c:1869)
> ==522==    by 0x794B99: finalize_compilation_unit() (cgraphunit.c:2120)
> ==522==    by 0x5B4A0E: cp_write_global_declarations() (decl2.c:4287)
> ==522==    by 0xA6D5BC: compile_file() (toplev.c:559)
> ==522==    by 0xA6F479: toplev_main(int, char**) (toplev.c:1881)
> ==522==    by 0x4ECD894: (below main) (libc-start.c:258)
> ==522==
>  %
>
> --
> Configure bugmail: http://gcc.gnu.org/bugzilla/userprefs.cgi?tab=email
> ------- You are receiving this mail because: -------
> You are on the CC list for the bug.
Comment 3 H.J. Lu 2012-11-21 14:28:01 UTC
*** Bug 55407 has been marked as a duplicate of this bug. ***
Comment 4 H.J. Lu 2012-11-21 14:29:02 UTC
There is a simple testcase in PR 55407.
Comment 5 Markus Trippelsdorf 2012-11-21 14:34:24 UTC
Teresa, your patch fixes the issue.
Happy Thanksgiving.
Comment 6 Jakub Jelinek 2012-11-21 15:04:58 UTC
Author: jakub
Date: Wed Nov 21 15:04:45 2012
New Revision: 193697

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193697
Log:
	PR gcov-profile/55417
	* profile.c (compute_working_sets): Check index first
	to avoid out-of-bounds array access.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/profile.c
Comment 7 Markus Trippelsdorf 2012-11-21 16:06:41 UTC
Fixed.