You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
257 lines
7.0 KiB
257 lines
7.0 KiB
autofs-5.1.7 - add some buffer length checks to master map parser
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Add some checks for buffer overflow to the master map parser.
|
|
|
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
|
---
|
|
CHANGELOG | 1 +
|
|
daemon/master_parse.y | 38 +++++++++++++++-----------
|
|
daemon/master_tok.l | 73 ++++++++++++++++++++++++++++++++++++++++++++-----
|
|
3 files changed, 88 insertions(+), 24 deletions(-)
|
|
|
|
diff --git a/CHANGELOG b/CHANGELOG
|
|
index be0b9d85..ded0f00f 100644
|
|
--- a/CHANGELOG
|
|
+++ b/CHANGELOG
|
|
@@ -85,6 +85,7 @@
|
|
- fix incorrect print format specifiers in get_pkt().
|
|
- add mapent path length check in handle_packet_expire_direct().
|
|
- add copy length check in umount_autofs_indirect().
|
|
+- add some buffer length checks to master map parser.
|
|
|
|
25/01/2021 autofs-5.1.7
|
|
- make bind mounts propagation slave by default.
|
|
diff --git a/daemon/master_parse.y b/daemon/master_parse.y
|
|
index 7480c36a..2d78f082 100644
|
|
--- a/daemon/master_parse.y
|
|
+++ b/daemon/master_parse.y
|
|
@@ -29,6 +29,7 @@
|
|
#include "master.h"
|
|
|
|
#define MAX_ERR_LEN 512
|
|
+#define STRTYPE_LEN 2048
|
|
|
|
extern struct master *master_list;
|
|
|
|
@@ -79,6 +80,7 @@ static int local_argc;
|
|
static unsigned int propagation;
|
|
|
|
static char errstr[MAX_ERR_LEN];
|
|
+static int errlen;
|
|
|
|
static unsigned int verbose;
|
|
static unsigned int debug;
|
|
@@ -521,10 +523,11 @@ dnattrs: DNATTR EQUAL DNNAME
|
|
strcasecmp($1, "ou") &&
|
|
strcasecmp($1, "automountMapName") &&
|
|
strcasecmp($1, "nisMapName")) {
|
|
- strcpy(errstr, $1);
|
|
- strcat(errstr, "=");
|
|
- strcat(errstr, $3);
|
|
- master_notify(errstr);
|
|
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|
+ if (errlen < MAX_ERR_LEN)
|
|
+ master_notify(errstr);
|
|
+ else
|
|
+ master_notify("error string too long");
|
|
YYABORT;
|
|
}
|
|
strcpy($$, $1);
|
|
@@ -537,10 +540,11 @@ dnattrs: DNATTR EQUAL DNNAME
|
|
strcasecmp($1, "ou") &&
|
|
strcasecmp($1, "automountMapName") &&
|
|
strcasecmp($1, "nisMapName")) {
|
|
- strcpy(errstr, $1);
|
|
- strcat(errstr, "=");
|
|
- strcat(errstr, $3);
|
|
- master_notify(errstr);
|
|
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|
+ if (errlen < MAX_ERR_LEN)
|
|
+ master_notify(errstr);
|
|
+ else
|
|
+ master_notify("error string too long");
|
|
YYABORT;
|
|
}
|
|
strcpy($$, $1);
|
|
@@ -565,10 +569,11 @@ dnattr: DNATTR EQUAL DNNAME
|
|
{
|
|
if (!strcasecmp($1, "automountMapName") ||
|
|
!strcasecmp($1, "nisMapName")) {
|
|
- strcpy(errstr, $1);
|
|
- strcat(errstr, "=");
|
|
- strcat(errstr, $3);
|
|
- master_notify(errstr);
|
|
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|
+ if (errlen < MAX_ERR_LEN)
|
|
+ master_notify(errstr);
|
|
+ else
|
|
+ master_notify("error string too long");
|
|
YYABORT;
|
|
}
|
|
strcpy($$, $1);
|
|
@@ -579,10 +584,11 @@ dnattr: DNATTR EQUAL DNNAME
|
|
{
|
|
if (!strcasecmp($1, "automountMapName") ||
|
|
!strcasecmp($1, "nisMapName")) {
|
|
- strcpy(errstr, $1);
|
|
- strcat(errstr, "=");
|
|
- strcat(errstr, $3);
|
|
- master_notify(errstr);
|
|
+ errlen = snprintf(errstr, MAX_ERR_LEN, "%s=%s", $1, $3);
|
|
+ if (errlen < MAX_ERR_LEN)
|
|
+ master_notify(errstr);
|
|
+ else
|
|
+ master_notify("error string too long");
|
|
YYABORT;
|
|
}
|
|
strcpy($$, $1);
|
|
diff --git a/daemon/master_tok.l b/daemon/master_tok.l
|
|
index 87a6b958..e2d15bce 100644
|
|
--- a/daemon/master_tok.l
|
|
+++ b/daemon/master_tok.l
|
|
@@ -23,6 +23,7 @@
|
|
#endif /* ECHO */
|
|
static void master_echo(void); /* forward definition */
|
|
#define ECHO master_echo()
|
|
+static void master_error(char *s);
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
@@ -80,6 +81,8 @@ char *bptr;
|
|
char *optr = buff;
|
|
unsigned int tlen;
|
|
|
|
+#define STRTYPE_LEN 2048
|
|
+
|
|
%}
|
|
|
|
%option nounput
|
|
@@ -217,7 +220,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
bptr += tlen;
|
|
yyless(tlen);
|
|
} else {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (tlen <= STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("MULTITYPE: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return(MULTITYPE);
|
|
}
|
|
}
|
|
@@ -239,7 +248,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
bptr += tlen;
|
|
yyless(tlen);
|
|
} else {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (tlen <= STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("MAPTYPE: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return(MAPTYPE);
|
|
}
|
|
}
|
|
@@ -327,12 +342,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
{OPTWS}\\\n{OPTWS} {}
|
|
|
|
{DNSERVERSTR} {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("DNSERVER: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return DNSERVER;
|
|
}
|
|
|
|
{DNATTRSTR}/"=" {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("DNATTR: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return DNATTR;
|
|
}
|
|
|
|
@@ -341,12 +368,24 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
}
|
|
|
|
{DNNAMESTR1}/","{DNATTRSTR}"=" {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("DNNAME: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return DNNAME;
|
|
}
|
|
|
|
{DNNAMESTR2} {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("DNNAME: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return DNNAME;
|
|
}
|
|
|
|
@@ -357,7 +396,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
{WS}"=" |
|
|
"="{WS} {
|
|
BEGIN(INITIAL);
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("SPACE: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return SPACE;
|
|
}
|
|
|
|
@@ -419,7 +464,13 @@ MODE (--mode{OPTWS}|--mode{OPTWS}={OPTWS})
|
|
}
|
|
|
|
{OPTIONSTR} {
|
|
- strcpy(master_lval.strtype, master_text);
|
|
+ if (master_leng < STRTYPE_LEN)
|
|
+ strcpy(master_lval.strtype, master_text);
|
|
+ else {
|
|
+ master_error("OPTION: value too large, truncated");
|
|
+ strncpy(master_lval.strtype, master_text, STRTYPE_LEN - 2);
|
|
+ master_lval.strtype[STRTYPE_LEN - 1] = 0;
|
|
+ }
|
|
return(OPTION);
|
|
}
|
|
|
|
@@ -459,6 +510,12 @@ static void master_echo(void)
|
|
return;
|
|
}
|
|
|
|
+static void master_error(char *s)
|
|
+{
|
|
+ logmsg("%s");
|
|
+ return;
|
|
+}
|
|
+
|
|
#ifdef FLEX_SCANNER
|
|
|
|
void master_set_scan_buffer(const char *buffer)
|
|
|