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.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@6618
This commit is contained in:
Josef Weidendorfer 2007-02-26 00:16:09 +00:00
parent 9a4164c5f3
commit e06ac31db4
2 changed files with 53 additions and 36 deletions

View File

@ -128,41 +128,26 @@ static void setup_control(void)
if (fd>=0) {
Char buf[512];
Int i;
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));
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, "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 @@ static Int dump_info(Int fd)
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);

View File

@ -121,6 +121,43 @@ struct _CommandLineOptions {
#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 ---*/