|
From: <sv...@va...> - 2007-02-26 00:16:19
|
Author: weidendo
Date: 2007-02-26 00:16:09 +0000 (Mon, 26 Feb 2007)
New Revision: 6618
Log:
Callgrind: Fix potential buffer overruns with user provided strings
This introduces some macros to shorten the code for output of
strings to a file descriptor. I could use this a lot,
but this commit limits itself to the potential buffer overruns
(to ease backporting - provided we want to do this)
Heavy use of the macros probably blows up the code. Perhaps
it would be better to provide e.g. a VG_(write_str3) function
in the tool API.
Modified:
trunk/callgrind/command.c
trunk/callgrind/global.h
Modified: trunk/callgrind/command.c
===================================================================
--- trunk/callgrind/command.c 2007-02-25 17:13:19 UTC (rev 6617)
+++ trunk/callgrind/command.c 2007-02-26 00:16:09 UTC (rev 6618)
@@ -128,41 +128,26 @@
if (fd>=0) {
Char buf[512];
Int i;
+
+ WRITE_STR3(fd,
+ "# This file is generated by Callgrind-" VERSION ".\n"
+ "# It is used to enable controlling the supervision of\n"
+ "# '", VG_(args_the_exename), "'\n"
+ "# by external tools.\n\n");
- VG_(sprintf)(buf,
- "# This file is generated by Callgrind-" VERSION ".\n"
- "# It is used to enable controlling the supervision of\n"
- "# '%s'\n"
- "# by external tools.\n\n",
- VG_(args_the_exename)
- );
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
VG_(sprintf)(buf, "version: " COMMAND_VERSION "\n");
VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
- VG_(sprintf)(buf, "base: %s\n", dir);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
- VG_(sprintf)(buf, "dumps: %s\n", dump_filename);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
- VG_(sprintf)(buf, "control: %s\n", command_file);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
- VG_(sprintf)(buf, "result: %s\n", result_file);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
-
- VG_(strcpy)(buf, "cmd:");
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
- VG_(sprintf)(buf, " %s", VG_(args_the_exename));
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ WRITE_STR3(fd, "base: ", dir, "\n");
+ WRITE_STR3(fd, "dumps: ", dump_filename, "\n");
+ WRITE_STR3(fd, "control: ", command_file, "\n");
+ WRITE_STR3(fd, "result: ", result_file, "\n");
+
+ WRITE_STR2(fd, "cmd: ", VG_(args_the_exename));
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i );
if (!arg) continue;
- tl_assert( VG_(strlen)(arg) < 512-4 ); /* see [512] above */
- VG_(sprintf)(buf, " %s", arg);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ WRITE_STR2(fd, " ", arg);
}
VG_(write)(fd, "\n", 1);
VG_(close)(fd);
@@ -224,19 +209,14 @@
VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
/* "base:" line */
- VG_(sprintf)(buf, "base: %s\n", dump_base);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ WRITE_STR3(fd, "base: ", dump_base, "\n");
/* "cmd:" line */
- VG_(strcpy)(buf, "cmd:");
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
- VG_(sprintf)(buf, " %s", VG_(args_the_exename));
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ WRITE_STR2(fd, "cmd: ", VG_(args_the_exename));
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
HChar* arg = * (HChar**)VG_(indexXA)( VG_(args_for_client), i );
if (!arg) continue;
- VG_(sprintf)(buf, " %s", arg);
- VG_(write)(fd, (void*)buf, VG_(strlen)(buf));
+ WRITE_STR2(fd, " ", arg);
}
VG_(write)(fd, "\n", 1);
Modified: trunk/callgrind/global.h
===================================================================
--- trunk/callgrind/global.h 2007-02-25 17:13:19 UTC (rev 6617)
+++ trunk/callgrind/global.h 2007-02-26 00:16:09 UTC (rev 6618)
@@ -121,7 +121,44 @@
#define LINE_BUF_LEN 64
+/* Convenience macros */
+/* Use this only when size of sprintf args are known to fit into
+ * given buffer; for strings of unknown length, use WRITE_STR below
+ */
+#define WRITE_SPRINTF(fd, zz_buf, fmt, args...) \
+ do { Int len = VG_(sprintf)(zz_buf, fmt, ## args); \
+ VG_(write)(fd, (void*)zz_buf, len); \
+ } while (0)
+
+#define WRITE_STR(fd, str) \
+ do { if (str) { Int len = VG_(strlen)(str); \
+ VG_(write)(fd, (void*)str, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ } while (0)
+
+#define WRITE_STR2(fd, str1, str2) \
+ do { if (str1) { Int len = VG_(strlen)(str1); \
+ VG_(write)(fd, (void*)str1, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ if (str2) { Int len = VG_(strlen)(str2); \
+ VG_(write)(fd, (void*)str2, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ } while (0)
+
+#define WRITE_STR3(fd, str1, str2, str3) \
+ do { if (str1) { Int len = VG_(strlen)(str1); \
+ VG_(write)(fd, (void*)str1, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ if (str2) { Int len = VG_(strlen)(str2); \
+ VG_(write)(fd, (void*)str2, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ if (str3) { Int len = VG_(strlen)(str3); \
+ VG_(write)(fd, (void*)str3, len); } \
+ else VG_(write)(fd, "(null)", 6); \
+ } while (0)
+
+
/*------------------------------------------------------------*/
/*--- Statistics ---*/
/*------------------------------------------------------------*/
|