summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-05-22 09:15:34 -0700
committerGuy Harris <guy@alum.mit.edu>2019-05-22 09:15:34 -0700
commit944a5e22aab5c62706df1acef419ac6432de8f29 (patch)
treea081479886c51606f2ca7386ce1d88c2b9695c8e
parentae693dc2121f6fe1c7f42ece00b54b16e84c400f (diff)
downloadtcpdump-944a5e22aab5c62706df1acef419ac6432de8f29.tar.gz
Don't use leftover string length values.
Before processing an SMB request or response, set the string length variable to 0, and set a flag indicating whether we *have* a string length variable to "false". Set the latter to "true" only if we explicitly set the string length, and if it's not set when we process a counted string, report an error. (That *shouldn't* happen, but *can* happen in a malformed packet, such as an NT Create AndX request with a zero word count, meaning "no word parameters" and thus "no string length word parameter".)
-rw-r--r--print-smb.c1
-rw-r--r--smb.h1
-rw-r--r--smbutil.c22
3 files changed, 24 insertions, 0 deletions
diff --git a/print-smb.c b/print-smb.c
index 5a66b67b..39125efa 100644
--- a/print-smb.c
+++ b/print-smb.c
@@ -867,6 +867,7 @@ print_smb(netdissect_options *ndo,
f2 = fn->descript.rep_f2;
}
+ smb_reset();
if (fn->descript.fn)
(*fn->descript.fn)(ndo, words, data, buf, maxbuf);
else {
diff --git a/smb.h b/smb.h
index d49c192f..b2ebcbbe 100644
--- a/smb.h
+++ b/smb.h
@@ -117,6 +117,7 @@
#define TRANSACT2_MKDIR 13
/* some protos */
+void smb_reset(void);
const u_char *smb_fdata(netdissect_options *, const u_char *, const char *, const u_char *, int);
extern const char *smb_errstr(int, int);
extern const char *nt_errstr(uint32_t);
diff --git a/smbutil.c b/smbutil.c
index 69d29c66..e567e0a1 100644
--- a/smbutil.c
+++ b/smbutil.c
@@ -20,10 +20,21 @@
#include "extract.h"
#include "smb.h"
+static int stringlen_is_set;
static uint32_t stringlen;
extern const u_char *startbuf;
/*
+ * Reset SMB state.
+ */
+void
+smb_reset(void)
+{
+ stringlen_is_set = 0;
+ stringlen = 0;
+}
+
+/*
* interpret a 32 bit dos packed date/time to some parameters
*/
static void
@@ -649,6 +660,7 @@ smb_fdata1(netdissect_options *ndo,
case 'b':
ND_TCHECK_1(buf);
stringlen = GET_U_1(buf);
+ stringlen_is_set = 1;
ND_PRINT("%u", stringlen);
buf += 1;
break;
@@ -658,6 +670,7 @@ smb_fdata1(netdissect_options *ndo,
ND_TCHECK_2(buf);
stringlen = reverse ? GET_BE_U_2(buf) :
GET_LE_U_2(buf);
+ stringlen_is_set = 1;
ND_PRINT("%u", stringlen);
buf += 2;
break;
@@ -667,6 +680,7 @@ smb_fdata1(netdissect_options *ndo,
ND_TCHECK_4(buf);
stringlen = reverse ? GET_BE_U_4(buf) :
GET_LE_U_4(buf);
+ stringlen_is_set = 1;
ND_PRINT("%u", stringlen);
buf += 4;
break;
@@ -723,6 +737,10 @@ smb_fdata1(netdissect_options *ndo,
}
case 'c':
{
+ if (!stringlen_is_set) {
+ ND_PRINT("{stringlen not set}");
+ goto trunc;
+ }
ND_TCHECK_LEN(buf, stringlen);
ND_PRINT("%-*.*s", (int)stringlen, (int)stringlen, buf);
buf += stringlen;
@@ -735,6 +753,10 @@ smb_fdata1(netdissect_options *ndo,
{
int result;
+ if (!stringlen_is_set) {
+ ND_PRINT("{stringlen not set}");
+ goto trunc;
+ }
result = unistr(ndo, &strbuf, buf, &stringlen, 0, unicodestr);
ND_PRINT("%s", strbuf);
if (result == -1)