The following commit has been merged in the master branch:
commit 141b8a46fae0a80313ca1968f55f45124ce70428
Author: Guillem Jover <[email protected]>
Date: Sun Oct 31 07:55:47 2010 +0100
libdpkg: Make str_escape_fmt buffer overflow safe
Make sure we do not write more to the destination buffer than it can
hold.
diff --git a/lib/dpkg/parsehelp.c b/lib/dpkg/parsehelp.c
index 70a4f8c..a2ed77b 100644
--- a/lib/dpkg/parsehelp.c
+++ b/lib/dpkg/parsehelp.c
@@ -52,7 +52,7 @@ parse_error(struct parsedb_state *ps,
char buf1[768], buf2[1000], *q;
parse_error_msg(ps, pigp, _("parse error"), buf1);
- q = str_escape_fmt(buf2, buf1);
+ q = str_escape_fmt(buf2, buf1, sizeof(buf2));
strcat(q,fmt);
va_start(args, fmt);
@@ -67,7 +67,7 @@ parse_warn(struct parsedb_state *ps,
char buf1[768], buf2[1000], *q;
parse_error_msg(ps, pigp, _("warning"), buf1);
- q = str_escape_fmt(buf2, buf1);
+ q = str_escape_fmt(buf2, buf1, sizeof(buf2));
strcat(q, fmt);
va_start(args, fmt);
diff --git a/lib/dpkg/string.c b/lib/dpkg/string.c
index 2a3fb63..cf53f4f 100644
--- a/lib/dpkg/string.c
+++ b/lib/dpkg/string.c
@@ -27,14 +27,22 @@
#include <dpkg/string.h>
char *
-str_escape_fmt(char *dst, const char *src)
+str_escape_fmt(char *dst, const char *src, size_t n)
{
char *d = dst;
const char *s = src;
+ if (n == 0)
+ return d;
+
while (*s) {
- if (*s == '%')
+ if (*s == '%') {
+ if (n-- <= 2)
+ break;
*d++ = '%';
+ }
+ if (n-- <= 1)
+ break;
*d++ = *s++;
}
diff --git a/lib/dpkg/string.h b/lib/dpkg/string.h
index e158356..af879e8 100644
--- a/lib/dpkg/string.h
+++ b/lib/dpkg/string.h
@@ -25,7 +25,7 @@
DPKG_BEGIN_DECLS
-char *str_escape_fmt(char *dest, const char *src);
+char *str_escape_fmt(char *dest, const char *src, size_t n);
char *str_strip_quotes(char *str);
DPKG_END_DECLS
diff --git a/lib/dpkg/test/t-string.c b/lib/dpkg/test/t-string.c
index eb651f1..689f387 100644
--- a/lib/dpkg/test/t-string.c
+++ b/lib/dpkg/test/t-string.c
@@ -32,24 +32,35 @@ test_str_escape_fmt(void)
char buf[1024], *q;
memset(buf, 'a', sizeof(buf));
- q = str_escape_fmt(buf, "");
+ q = str_escape_fmt(buf, "", sizeof(buf));
strcpy(q, " end");
test_str(buf, ==, " end");
memset(buf, 'a', sizeof(buf));
- q = str_escape_fmt(buf, "%");
+ q = str_escape_fmt(buf, "%", sizeof(buf));
strcpy(q, " end");
test_str(buf, ==, "%% end");
memset(buf, 'a', sizeof(buf));
- q = str_escape_fmt(buf, "%%%");
+ q = str_escape_fmt(buf, "%%%", sizeof(buf));
strcpy(q, " end");
test_str(buf, ==, "%%%%%% end");
memset(buf, 'a', sizeof(buf));
- q = str_escape_fmt(buf, "%b%b%c%c%%");
+ q = str_escape_fmt(buf, "%b%b%c%c%%", sizeof(buf));
strcpy(q, " end");
test_str(buf, ==, "%%b%%b%%c%%c%%%% end");
+
+ /* Test delimited buffer. */
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%%%", 5);
+ strcpy(q, " end");
+ test_str(buf, ==, "%%%% end");
+
+ memset(buf, 'a', sizeof(buf));
+ q = str_escape_fmt(buf, "%%%", 4);
+ strcpy(q, " end");
+ test_str(buf, ==, "%% end");
}
static void
--
dpkg's main repository
--
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]