|
|
6bbd11 |
autofs-5.1.0 - fix buffer size checks in merge_options()
|
|
|
6bbd11 |
|
|
|
6bbd11 |
From: Ian Kent <raven@themaw.net>
|
|
|
6bbd11 |
|
|
|
6bbd11 |
Fix some buffer size overflow checks in merge_options().
|
|
|
6bbd11 |
---
|
|
|
6bbd11 |
CHANGELOG | 1 +
|
|
|
6bbd11 |
lib/parse_subs.c | 25 +++++++++++++++++++++----
|
|
|
6bbd11 |
2 files changed, 22 insertions(+), 4 deletions(-)
|
|
|
6bbd11 |
|
|
|
6bbd11 |
--- autofs-5.0.7.orig/CHANGELOG
|
|
|
6bbd11 |
+++ autofs-5.0.7/CHANGELOG
|
|
|
6bbd11 |
@@ -137,6 +137,7 @@
|
|
|
6bbd11 |
- fix signed comparison in inet_fill_net().
|
|
|
6bbd11 |
- fix buffer size checks in get_network_proximity().
|
|
|
6bbd11 |
- fix leak in get_network_proximity().
|
|
|
6bbd11 |
+- fix buffer size checks in merge_options().
|
|
|
6bbd11 |
|
|
|
6bbd11 |
25/07/2012 autofs-5.0.7
|
|
|
6bbd11 |
=======================
|
|
|
6bbd11 |
--- autofs-5.0.7.orig/lib/parse_subs.c
|
|
|
6bbd11 |
+++ autofs-5.0.7/lib/parse_subs.c
|
|
|
6bbd11 |
@@ -886,11 +886,11 @@ static char *hasopt(const char *str, con
|
|
|
6bbd11 |
|
|
|
6bbd11 |
char *merge_options(const char *opt1, const char *opt2)
|
|
|
6bbd11 |
{
|
|
|
6bbd11 |
- char str[MAX_OPTIONS_LEN];
|
|
|
6bbd11 |
- char result[MAX_OPTIONS_LEN];
|
|
|
6bbd11 |
- char neg[MAX_OPTION_LEN];
|
|
|
6bbd11 |
+ char str[MAX_OPTIONS_LEN + 1];
|
|
|
6bbd11 |
+ char result[MAX_OPTIONS_LEN + 1];
|
|
|
6bbd11 |
+ char neg[MAX_OPTION_LEN + 1];
|
|
|
6bbd11 |
char *tok, *ptr = NULL;
|
|
|
6bbd11 |
- size_t len;
|
|
|
6bbd11 |
+ size_t resultlen, len;
|
|
|
6bbd11 |
|
|
|
6bbd11 |
if ((!opt1 || !*opt1) && (!opt2 || !*opt2))
|
|
|
6bbd11 |
return NULL;
|
|
|
6bbd11 |
@@ -910,9 +910,12 @@ char *merge_options(const char *opt1, co
|
|
|
6bbd11 |
if (!strcmp(opt1, opt2))
|
|
|
6bbd11 |
return strdup(opt1);
|
|
|
6bbd11 |
|
|
|
6bbd11 |
+ if (strlen(str) > MAX_OPTIONS_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
memset(result, 0, sizeof(result));
|
|
|
6bbd11 |
strcpy(str, opt1);
|
|
|
6bbd11 |
|
|
|
6bbd11 |
+ resultlen = 0;
|
|
|
6bbd11 |
tok = strtok_r(str, ",", &ptr);
|
|
|
6bbd11 |
while (tok) {
|
|
|
6bbd11 |
const char *this = (const char *) tok;
|
|
|
6bbd11 |
@@ -920,12 +923,15 @@ char *merge_options(const char *opt1, co
|
|
|
6bbd11 |
if (eq) {
|
|
|
6bbd11 |
*eq = '\0';
|
|
|
6bbd11 |
if (!hasopt(opt2, this)) {
|
|
|
6bbd11 |
+ if (resultlen + strlen(this) > MAX_OPTIONS_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
*eq = '=';
|
|
|
6bbd11 |
if (!*result)
|
|
|
6bbd11 |
strcpy(result, this);
|
|
|
6bbd11 |
else
|
|
|
6bbd11 |
strcat(result, this);
|
|
|
6bbd11 |
strcat(result, ",");
|
|
|
6bbd11 |
+ resultlen += strlen(this) + 1;
|
|
|
6bbd11 |
goto next;
|
|
|
6bbd11 |
}
|
|
|
6bbd11 |
}
|
|
|
6bbd11 |
@@ -946,10 +952,14 @@ char *merge_options(const char *opt1, co
|
|
|
6bbd11 |
goto next;
|
|
|
6bbd11 |
|
|
|
6bbd11 |
if (!strncmp(this, "no", 2)) {
|
|
|
6bbd11 |
+ if (strlen(this + 2) > MAX_OPTION_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
strcpy(neg, this + 2);
|
|
|
6bbd11 |
if (hasopt(opt2, neg))
|
|
|
6bbd11 |
goto next;
|
|
|
6bbd11 |
} else {
|
|
|
6bbd11 |
+ if ((strlen(this) + 2) > MAX_OPTION_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
strcpy(neg, "no");
|
|
|
6bbd11 |
strcat(neg, this);
|
|
|
6bbd11 |
if (hasopt(opt2, neg))
|
|
|
6bbd11 |
@@ -959,15 +969,22 @@ char *merge_options(const char *opt1, co
|
|
|
6bbd11 |
if (hasopt(opt2, tok))
|
|
|
6bbd11 |
goto next;
|
|
|
6bbd11 |
|
|
|
6bbd11 |
+ if (resultlen + strlen(this) + 1 > MAX_OPTIONS_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
+
|
|
|
6bbd11 |
if (!*result)
|
|
|
6bbd11 |
strcpy(result, this);
|
|
|
6bbd11 |
else
|
|
|
6bbd11 |
strcat(result, this);
|
|
|
6bbd11 |
strcat(result, ",");
|
|
|
6bbd11 |
+ resultlen =+ strlen(this) + 1;
|
|
|
6bbd11 |
next:
|
|
|
6bbd11 |
tok = strtok_r(NULL, ",", &ptr);
|
|
|
6bbd11 |
}
|
|
|
6bbd11 |
|
|
|
6bbd11 |
+ if (resultlen + strlen(opt2) > MAX_OPTIONS_LEN)
|
|
|
6bbd11 |
+ return NULL;
|
|
|
6bbd11 |
+
|
|
|
6bbd11 |
if (!*result)
|
|
|
6bbd11 |
strcpy(result, opt2);
|
|
|
6bbd11 |
else
|