summaryrefslogtreecommitdiff
path: root/rts/Stats.c
diff options
context:
space:
mode:
authorGreg Steuck <greg@nest.cx>2021-11-22 21:38:47 -0800
committerMarge Bot <ben+marge-bot@smart-cactus.org>2021-11-25 08:36:09 -0500
commite2c48b98c6a201eae09b4c84e73bb77608d03ec8 (patch)
treef45e4cfc42b3c473b21ecd6f8088ac8f48bcb419 /rts/Stats.c
parent20101d9ca016fca17605dd4f641640a60bdadca4 (diff)
downloadhaskell-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.c16
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