diff options
author | Greg Steuck <greg@nest.cx> | 2021-11-22 21:38:47 -0800 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2021-11-25 08:36:09 -0500 |
commit | e2c48b98c6a201eae09b4c84e73bb77608d03ec8 (patch) | |
tree | f45e4cfc42b3c473b21ecd6f8088ac8f48bcb419 /rts/Stats.c | |
parent | 20101d9ca016fca17605dd4f641640a60bdadca4 (diff) | |
download | haskell-e2c48b98c6a201eae09b4c84e73bb77608d03ec8.tar.gz |
Kill a use of %n format specifier
This format has been used as a security exploit vector for decades
now. Some operating systems (OpenBSD, Android, MSVC). It is targeted
for removal in C2X standard:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2834.htm
This requires extending the debug message function to return the
number of bytes written (like printf(3)), to permit %n format
specifier in one in one invocation of statsPrintf() in
report_summary().
Implemented by Matthias Kilian (kili<AT>outback.escape.de)
Diffstat (limited to 'rts/Stats.c')
-rw-r--r-- | rts/Stats.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/rts/Stats.c b/rts/Stats.c index 90e3e7b396..0c22f7e42b 100644 --- a/rts/Stats.c +++ b/rts/Stats.c @@ -69,7 +69,7 @@ static Time *GC_coll_cpu = NULL; static Time *GC_coll_elapsed = NULL; static Time *GC_coll_max_pause = NULL; -static void statsPrintf( char *s, ... ) GNUC3_ATTRIBUTE(format (PRINTF, 1, 2)); +static int statsPrintf( char *s, ... ) GNUC3_ATTRIBUTE(format (PRINTF, 1, 2)); static void statsFlush( void ); static void statsClose( void ); @@ -995,8 +995,10 @@ static void report_summary(const RTSSummaryStats* sum) for (g = 0; g < RtsFlags.GcFlags.generations; g++) { int prefix_length = 0; - statsPrintf("%*s" "gen[%" FMT_Word32 "%n", - col_width[0], "", g, &prefix_length); + prefix_length = statsPrintf("%*s" "gen[%" FMT_Word32, + col_width[0], "", g); + if (prefix_length < 0) + prefix_length = 0; prefix_length -= col_width[0]; int suffix_length = col_width[1] + prefix_length; suffix_length = @@ -1716,19 +1718,21 @@ void getRTSStats( RTSStats *s ) Dumping stuff in the stats file, or via the debug message interface -------------------------------------------------------------------------- */ -void +int statsPrintf( char *s, ... ) { + int ret = 0; FILE *sf = RtsFlags.GcFlags.statsFile; va_list ap; va_start(ap,s); if (sf == NULL) { - vdebugBelch(s,ap); + ret = vdebugBelch(s,ap); } else { - vfprintf(sf, s, ap); + ret = vfprintf(sf, s, ap); } va_end(ap); + return ret; } static void |