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.

258 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)