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