summaryrefslogtreecommitdiffstats
path: root/freebsd/contrib/tcpdump/smbutil.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/contrib/tcpdump/smbutil.c')
-rw-r--r--freebsd/contrib/tcpdump/smbutil.c42
1 files changed, 38 insertions, 4 deletions
diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c
index 5ed188b6..31ee99c4 100644
--- a/freebsd/contrib/tcpdump/smbutil.c
+++ b/freebsd/contrib/tcpdump/smbutil.c
@@ -484,12 +484,13 @@ smb_fdata1(netdissect_options *ndo,
case 'P':
{
- int l = atoi(fmt + 1);
+ int l = atoi(fmt + 1);
+ if(l <= 0) goto trunc; /* actually error in fmt string */
ND_TCHECK2(buf[0], l);
buf += l;
fmt++;
while (isdigit((unsigned char)*fmt))
- fmt++;
+ fmt++;
break;
}
case 'r':
@@ -803,17 +804,33 @@ smb_fdata(netdissect_options *ndo,
int unicodestr)
{
static int depth = 0;
+ const u_char *buf_start = buf;
char s[128];
char *p;
while (*fmt) {
switch (*fmt) {
case '*':
+ /*
+ * List of multiple instances of something described by the
+ * remainder of the string (which may itself include a list
+ * of multiple instances of something, so we recurse).
+ */
fmt++;
while (buf < maxbuf) {
const u_char *buf2;
depth++;
- buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
+ /*
+ * In order to avoid stack exhaustion recurse at most 10
+ * levels; that "should not happen", as no SMB structure
+ * should be nested *that* deeply, and we thus shouldn't
+ * have format strings with that level of nesting.
+ */
+ if (depth == 10) {
+ ND_PRINT((ndo, "(too many nested levels, not recursing)"));
+ buf2 = buf;
+ } else
+ buf2 = smb_fdata(ndo, buf, fmt, maxbuf, unicodestr);
depth--;
if (buf2 == NULL)
return(NULL);
@@ -824,22 +841,35 @@ smb_fdata(netdissect_options *ndo,
return(buf);
case '|':
+ /*
+ * Just do a bounds check.
+ */
fmt++;
if (buf >= maxbuf)
return(buf);
break;
case '%':
+ /*
+ * XXX - unused?
+ */
fmt++;
buf = maxbuf;
break;
case '#':
+ /*
+ * Done?
+ */
fmt++;
return(buf);
break;
case '[':
+ /*
+ * Format of an item, enclosed in square brackets; dissect
+ * the item with smb_fdata1().
+ */
fmt++;
if (buf >= maxbuf)
return(buf);
@@ -853,11 +883,15 @@ smb_fdata(netdissect_options *ndo,
s[p - fmt] = '\0';
fmt = p + 1;
buf = smb_fdata1(ndo, buf, s, maxbuf, unicodestr);
- if (buf == NULL)
+ if(buf < buf_start || buf == NULL) {
return(NULL);
+ }
break;
default:
+ /*
+ * Not a formatting character, so just print it.
+ */
ND_PRINT((ndo, "%c", *fmt));
fmt++;
break;