aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2012-12-15 10:28:00 +0000
committerWerner Koch <[email protected]>2012-12-15 10:28:00 +0000
commite33e74e3a4b2b4a0341f933410ddd5db7a12515e (patch)
tree3b84b86b658893f106a15c32e07091e141dc2fc9
parentUpdate README and po files for a release (diff)
downloadgnupg-e33e74e3a4b2b4a0341f933410ddd5db7a12515e.tar.gz
gnupg-e33e74e3a4b2b4a0341f933410ddd5db7a12515e.zip
Fix potential heap corruption in "gpg -v --version"
* g10/gpg.c (build_list): Rewrite to cope with buffer overflow in certain locales. * util/membuf.c (put_membuf_str): New. (get_membuf): Make LEN optional. -- This fixes an obvious bug in locales where the translated string is longer than the original. The bug could be exhibited by using LANG=ru_RU.utf8 gpg -v --version. En passant we also removed the trailing white space on continued lines. Reported-by: Dmitry V. Levin" <ldv at altlinux.org>
-rw-r--r--THANKS9
-rw-r--r--g10/gpg.c82
-rw-r--r--include/util.h1
-rw-r--r--util/membuf.c12
4 files changed, 55 insertions, 49 deletions
diff --git a/THANKS b/THANKS
index ae64d9fa9..791516ef5 100644
--- a/THANKS
+++ b/THANKS
@@ -49,6 +49,7 @@ David R. Bergstein [email protected]
David Shaw [email protected]
Detlef Lannert [email protected]
+Dmitry V. Levin ldv at altlinux dot org
Dirk Lattermann [email protected]
Dirk Meyer [email protected]
@@ -90,7 +91,7 @@ Ian McKellar [email protected]
Ingo Kl�cker [email protected]
Ivo Timmermans [email protected]
Jan Krueger [email protected]
-Jan Niehusmann [email protected]
+Jan Niehusmann [email protected]
Janusz A. Urbanowicz [email protected]
James Troup [email protected]
Jason Woodward jason dot woodward at timesys dot com
@@ -120,18 +121,18 @@ Karl Fogel [email protected]
Karsten Thygesen [email protected]
Katsuhiro Kondou [email protected]
Kazu Yamamoto [email protected]
-Kazuyoshi Kakihara
+Kazuyoshi Kakihara
Keith Clayton [email protected]
Kevin Ryde [email protected]
Klaus Singvogel [email protected]
Kurt Garloff [email protected]
Lars Kellogg-Stedman [email protected]
L. Sassaman [email protected]
Marcel Waldvogel [email protected]
Marco d'Itri [email protected]
Marco Parrone [email protected]
-Marcus Brinkmann [email protected]
+Marcus Brinkmann [email protected]
Mark Adler [email protected]
Mark Elbrecht [email protected]
Mark Pettit [email protected]
diff --git a/g10/gpg.c b/g10/gpg.c
index 573bb907b..96f908603 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -835,57 +835,53 @@ strusage( int level )
static char *
-build_list( const char *text, char letter,
- const char * (*mapf)(int), int (*chkf)(int) )
+build_list (const char *text, char letter,
+ const char * (*mapf)(int), int (*chkf)(int))
{
- int i;
- const char *s;
- size_t n=strlen(text)+2;
- char *list, *p, *line=NULL;
-
- if( maybe_setuid )
- secmem_init( 0 ); /* drop setuid */
-
- for(i=0; i <= 110; i++ )
- if( !chkf(i) && (s=mapf(i)) )
- n += strlen(s) + 7 + 2;
- list = xmalloc( 21 + n ); *list = 0;
- for(p=NULL, i=0; i <= 110; i++ ) {
- if( !chkf(i) && (s=mapf(i)) ) {
- if( !p ) {
- p = stpcpy( list, text );
- line=p;
- }
- else
- p = stpcpy( p, ", ");
+ membuf_t mb;
+ int indent;
+ int i, j, len;
+ const char *s;
+ char *string;
- if(strlen(line)>60) {
- int spaces=strlen(text);
+ if (maybe_setuid)
+ secmem_init (0); /* Drop setuid */
- list=xrealloc(list,n+spaces+1);
- /* realloc could move the block, so find the end again */
- p=list;
- while(*p)
- p++;
+ indent = strlen (text);
+ len = 0;
+ init_membuf (&mb, 512);
- p=stpcpy(p, "\n");
- line=p;
- for(;spaces;spaces--)
- p=stpcpy(p, " ");
+ for (i=0; i <= 110; i++ )
+ {
+ if (!chkf (i) && (s = mapf (i)))
+ {
+ if (mb.len - len > 60)
+ {
+ put_membuf_str (&mb, ",\n");
+ len = mb.len;
+ for (j=0; j < indent; j++)
+ put_membuf_str (&mb, " ");
}
+ else if (mb.len)
+ put_membuf_str (&mb, ", ");
+ else
+ put_membuf_str (&mb, text);
- p = stpcpy(p, s );
- if(opt.verbose && letter)
- {
- char num[8];
- sprintf(num," (%c%d)",letter,i);
- p = stpcpy(p,num);
- }
+ put_membuf_str (&mb, s);
+ if (opt.verbose && letter)
+ {
+ char num[20];
+ snprintf (num, sizeof num, " (%c%d)", letter, i);
+ put_membuf_str (&mb, num);
+ }
}
}
- if( p )
- p = stpcpy(p, "\n" );
- return list;
+ if (mb.len)
+ put_membuf_str (&mb, "\n");
+ put_membuf (&mb, "", 1);
+
+ string = get_membuf (&mb, NULL);
+ return xrealloc (string, strlen (string)+1);
}
diff --git a/include/util.h b/include/util.h
index 9303a50b1..3057b25e0 100644
--- a/include/util.h
+++ b/include/util.h
@@ -219,6 +219,7 @@ typedef struct private_membuf_s membuf_t;
void init_membuf (membuf_t *mb, int initiallen);
void put_membuf (membuf_t *mb, const void *buf, size_t len);
+void put_membuf_str (membuf_t *mb, const char *buf);
void *get_membuf (membuf_t *mb, size_t *len);
diff --git a/util/membuf.c b/util/membuf.c
index db3f5ac37..3f7a61ddd 100644
--- a/util/membuf.c
+++ b/util/membuf.c
@@ -52,7 +52,7 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
if (mb->len + len >= mb->size)
{
char *p;
-
+
mb->size += len + 1024;
p = xrealloc (mb->buf, mb->size);
mb->buf = p;
@@ -62,6 +62,13 @@ put_membuf (membuf_t *mb, const void *buf, size_t len)
}
+void
+put_membuf_str (membuf_t *mb, const char *buf)
+{
+ put_membuf (mb, buf, strlen (buf));
+}
+
+
void *
get_membuf (membuf_t *mb, size_t *len)
{
@@ -75,7 +82,8 @@ get_membuf (membuf_t *mb, size_t *len)
}
p = mb->buf;
- *len = mb->len;
+ if (len)
+ *len = mb->len;
mb->buf = NULL;
mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */
return p;