mirror of https://gitee.com/Nocallback/glibc.git
Browse Source
A larger number of format specifiers coudld cause a stack overflow, potentially allowing to bypass _FORTIFY_SOURCE format string protection.rth/tramp
committed by
Florian Weimer
7 changed files with 207 additions and 8 deletions
@ -0,0 +1,70 @@ |
|||
#include <stdio.h> |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
|
|||
static const char expected[] = "\
|
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55\ |
|||
\n\ |
|||
a\n\ |
|||
abbcd55%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; |
|||
|
|||
static int |
|||
do_test (void) |
|||
{ |
|||
char *buf = malloc (strlen (expected) + 1); |
|||
snprintf (buf, strlen (expected) + 1, |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n", |
|||
"a", "b", "c", "d", 5); |
|||
return strcmp (buf, expected) != 0; |
|||
} |
|||
|
|||
#define TEST_FUNCTION do_test () |
|||
#include "../test-skeleton.c" |
|||
@ -0,0 +1,50 @@ |
|||
#include <stdio.h> |
|||
#include <string.h> |
|||
#include <stdlib.h> |
|||
|
|||
int |
|||
do_test (void) |
|||
{ |
|||
size_t instances = 16384; |
|||
#define X0 "\n%1$s\n" "%1$s" "%2$s" "%2$s" "%3$s" "%4$s" "%5$d" "%5$d" |
|||
const char *item = "\na\nabbcd55"; |
|||
#define X3 X0 X0 X0 X0 X0 X0 X0 X0 |
|||
#define X6 X3 X3 X3 X3 X3 X3 X3 X3 |
|||
#define X9 X6 X6 X6 X6 X6 X6 X6 X6 |
|||
#define X12 X9 X9 X9 X9 X9 X9 X9 X9 |
|||
#define X14 X12 X12 X12 X12 |
|||
#define TRAILER "%%%%%%%%%%%%%%%%%%%%%%%%%%" |
|||
#define TRAILER2 TRAILER TRAILER |
|||
size_t length = instances * strlen (item) + strlen (TRAILER) + 1; |
|||
|
|||
char *buf = malloc (length + 1); |
|||
snprintf (buf, length + 1, |
|||
X14 TRAILER2 "\n", |
|||
"a", "b", "c", "d", 5); |
|||
|
|||
const char *p = buf; |
|||
size_t i; |
|||
for (i = 0; i < instances; ++i) |
|||
{ |
|||
const char *expected; |
|||
for (expected = item; *expected; ++expected) |
|||
{ |
|||
if (*p != *expected) |
|||
{ |
|||
printf ("mismatch at offset %zu (%zu): expected %d, got %d\n", |
|||
(size_t) (p - buf), i, *expected & 0xFF, *p & 0xFF); |
|||
return 1; |
|||
} |
|||
++p; |
|||
} |
|||
} |
|||
if (strcmp (p, TRAILER "\n") != 0) |
|||
{ |
|||
printf ("mismatch at trailer: [%s]\n", p); |
|||
return 1; |
|||
} |
|||
free (buf); |
|||
return 0; |
|||
} |
|||
#define TEST_FUNCTION do_test () |
|||
#include "../test-skeleton.c" |
|||
@ -0,0 +1,31 @@ |
|||
#include <stdio.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <sys/resource.h> |
|||
|
|||
#define LIMIT 1000000 |
|||
|
|||
int |
|||
main (void) |
|||
{ |
|||
struct rlimit lim; |
|||
getrlimit (RLIMIT_STACK, &lim); |
|||
lim.rlim_cur = 1048576; |
|||
setrlimit (RLIMIT_STACK, &lim); |
|||
char *fmtstr = malloc (4 * LIMIT + 1); |
|||
if (fmtstr == NULL) |
|||
abort (); |
|||
char *output = malloc (LIMIT + 1); |
|||
if (output == NULL) |
|||
abort (); |
|||
for (size_t i = 0; i < LIMIT; i++) |
|||
memcpy (fmtstr + 4 * i, "%1$d", 4); |
|||
fmtstr[4 * LIMIT] = '\0'; |
|||
int ret = snprintf (output, LIMIT + 1, fmtstr, 0); |
|||
if (ret != LIMIT) |
|||
abort (); |
|||
for (size_t i = 0; i < LIMIT; i++) |
|||
if (output[i] != '0') |
|||
abort (); |
|||
return 0; |
|||
} |
|||
Loading…
Reference in new issue