db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: * libtiff/tif_pixarlog.c: fix potential buffer write overrun in
PixarLogDecode() on corrupted/unexpected images (reported by Mathias Svensson)
CVE: CVE-2016-5314
CWE: CWE-787
Vulnerability description: Buffer overflow in the PixarLogDecode function in tif_pixarlog.c in LibTIFF 4.0.6 and earlier allows remote attackers to cause a denial of service (application crash) or possibly have unspecified other impact via a crafted TIFF image, as demonstrated by overwriting the vgetparent function pointer with rgb2ycbcr.

Project: libtiff

PixarLogEncode(TIFF* tif, uint8* bp, tmsize_t cc, uint16 s)
{
	static const char module[] = "PixarLogEncode";
	TIFFDirectory *td = &tif->tif_dir;
	PixarLogState *sp = EncoderState(tif);
	tmsize_t i;
	tmsize_t n;
	int llen;
	unsigned short * up;

	(void) s;

	switch (sp->user_datafmt) {
	case PIXARLOGDATAFMT_FLOAT:
		n = cc / sizeof(float);		/* XXX float == 32 bits */
		break;
	case PIXARLOGDATAFMT_16BIT:
	case PIXARLOGDATAFMT_12BITPICIO:
	case PIXARLOGDATAFMT_11BITLOG:
		n = cc / sizeof(uint16);	/* XXX uint16 == 16 bits */
		break;
	case PIXARLOGDATAFMT_8BIT:
	case PIXARLOGDATAFMT_8BITABGR:
		n = cc;
		break;
	default:
		TIFFErrorExt(tif->tif_clientdata, module,
			"%d bit input not supported in PixarLog",
			td->td_bitspersample);
		return 0;
	}

	llen = sp->stride * td->td_imagewidth;

	for (i = 0, up = sp->tbuf; i < n; i += llen, up += llen) {
		switch (sp->user_datafmt)  {
		case PIXARLOGDATAFMT_FLOAT:
			horizontalDifferenceF((float *)bp, llen, 
				sp->stride, up, sp->FromLT2);
			bp += llen * sizeof(float);
			break;
		case PIXARLOGDATAFMT_16BIT:
			horizontalDifference16((uint16 *)bp, llen, 
				sp->stride, up, sp->From14);
			bp += llen * sizeof(uint16);
			break;
		case PIXARLOGDATAFMT_8BIT:
			horizontalDifference8((unsigned char *)bp, llen, 
				sp->stride, up, sp->From8);
			bp += llen * sizeof(unsigned char);
			break;
		default:
			TIFFErrorExt(tif->tif_clientdata, module,
				"%d bit input not supported in PixarLog",
				td->td_bitspersample);
			return 0;
		}
	}
 
	sp->stream.next_in = (unsigned char *) sp->tbuf;
	assert(sizeof(sp->stream.avail_in)==4);  /* if this assert gets raised,
	    we need to simplify this code to reflect a ZLib that is likely updated
	    to deal with 8byte memory sizes, though this code will respond
	    appropriately even before we simplify it */
	sp->stream.avail_in = (uInt) (n * sizeof(uint16));
	if ((sp->stream.avail_in / sizeof(uint16)) != (uInt) n)
	{
		TIFFErrorExt(tif->tif_clientdata, module,
			     "ZLib cannot deal with buffers this size");
		return (0);
	}

	do {
		if (deflate(&sp->stream, Z_NO_FLUSH) != Z_OK) {
			TIFFErrorExt(tif->tif_clientdata, module, "Encoder error: %s",
			    sp->stream.msg ? sp->stream.msg : "(null)");
			return (0);
		}
		if (sp->stream.avail_out == 0) {
			tif->tif_rawcc = tif->tif_rawdatasize;
			TIFFFlushData1(tif);
			sp->stream.next_out = tif->tif_rawdata;
			sp->stream.avail_out = (uInt) tif->tif_rawdatasize;  /* this is a safe typecast, as check is made already in PixarLogPreEncode */
		}
	} while (sp->stream.avail_in > 0);
	return (1);
}
Commit message: fix #147: Stack Exhaustion Problem caused by some parsing functions in regcomp.c making recursive calls to themselves.
CVE: CVE-2019-16163
CWE: CWE-399
Vulnerability description: Oniguruma before 6.9.3 allows Stack Exhaustion in regcomp.c because of recursion in regparse.c.

Project: oniguruma
File: regparse.c

add_ctype_to_cc(CClassNode* cc, int ctype, int not, ScanEnv* env)
{
#define ASCII_LIMIT    127

  int c, r;
  int ascii_mode;
  const OnigCodePoint *ranges;
  OnigCodePoint limit;
  OnigCodePoint sb_out;
  OnigEncoding enc = env->enc;

  ascii_mode = IS_ASCII_MODE_CTYPE_OPTION(ctype, env->options);

  r = ONIGENC_GET_CTYPE_CODE_RANGE(enc, ctype, &sb_out, &ranges);
  if (r == 0) {
    if (ascii_mode == 0)
      r = add_ctype_to_cc_by_range(cc, ctype, not, env->enc, sb_out, ranges);
    else
      r = add_ctype_to_cc_by_range_limit(cc, ctype, not, env->enc, sb_out,
                                         ranges, ASCII_LIMIT);
    return r;
  }
  else if (r != ONIG_NO_SUPPORT_CONFIG) {
    return r;
  }

  r = 0;
  limit = ascii_mode ? ASCII_LIMIT : SINGLE_BYTE_SIZE;

  switch (ctype) {
  case ONIGENC_CTYPE_ALPHA:
  case ONIGENC_CTYPE_BLANK:
  case ONIGENC_CTYPE_CNTRL:
  case ONIGENC_CTYPE_DIGIT:
  case ONIGENC_CTYPE_LOWER:
  case ONIGENC_CTYPE_PUNCT:
  case ONIGENC_CTYPE_SPACE:
  case ONIGENC_CTYPE_UPPER:
  case ONIGENC_CTYPE_XDIGIT:
  case ONIGENC_CTYPE_ASCII:
  case ONIGENC_CTYPE_ALNUM:
    if (not != 0) {
      for (c = 0; c < (int )limit; c++) {
        if (! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
          BITSET_SET_BIT(cc->bs, c);
      }
      for (c = limit; c < SINGLE_BYTE_SIZE; c++) {
        BITSET_SET_BIT(cc->bs, c);
      }

      ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    else {
      for (c = 0; c < (int )limit; c++) {
        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
          BITSET_SET_BIT(cc->bs, c);
      }
    }
    break;

  case ONIGENC_CTYPE_GRAPH:
  case ONIGENC_CTYPE_PRINT:
  case ONIGENC_CTYPE_WORD:
    if (not != 0) {
      for (c = 0; c < (int )limit; c++) {
        if (ONIGENC_CODE_TO_MBCLEN(enc, c) > 0 /* check invalid code point */
            && ! ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
          BITSET_SET_BIT(cc->bs, c);
      }
      for (c = limit; c < SINGLE_BYTE_SIZE; c++) {
        if (ONIGENC_CODE_TO_MBCLEN(enc, c) > 0)
          BITSET_SET_BIT(cc->bs, c);
      }
    }
    else {
      for (c = 0; c < (int )limit; c++) {
        if (ONIGENC_IS_CODE_CTYPE(enc, (OnigCodePoint )c, ctype))
          BITSET_SET_BIT(cc->bs, c);
      }
      if (ascii_mode == 0)
        ADD_ALL_MULTI_BYTE_RANGE(enc, cc->mbuf);
    }
    break;

  default:
    return ONIGERR_PARSER_BUG;
    break;
  }

  return r;
}
Commit message: xmlparse.c: Deny internal entities closing the doctype
CVE: CVE-2019-15903
CWE: CWE-611
Vulnerability description: In libexpat before 2.2.8, crafted XML input could fool the parser into changing from DTD parsing to document parsing too early; a consecutive call to XML_GetCurrentLineNumber (or XML_GetCurrentColumnNumber) then resulted in a heap-based buffer over-read.

Project: libexpat
File: xmlparse.c

copyString(const XML_Char *s, const XML_Memory_Handling_Suite *memsuite) {
  int charsRequired = 0;
  XML_Char *result;

  /* First determine how long the string is */
  while (s[charsRequired] != 0) {
    charsRequired++;
  }
  /* Include the terminator */
  charsRequired++;

  /* Now allocate space for the copy */
  result = memsuite->malloc_fcn(charsRequired * sizeof(XML_Char));
  if (result == NULL)
    return NULL;
  /* Copy the original into place */
  memcpy(result, s, charsRequired * sizeof(XML_Char));
  return result;
}

Project: libexpat
File: xmlparse.c

storeRawNames(XML_Parser parser) {
  TAG *tag = parser->m_tagStack;
  while (tag) {
    int bufSize;
    int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
    char *rawNameBuf = tag->buf + nameLen;
    /* Stop if already stored.  Since m_tagStack is a stack, we can stop
       at the first entry that has already been copied; everything
       below it in the stack is already been accounted for in a
       previous call to this function.
    */
    if (tag->rawName == rawNameBuf)
      break;
    /* For re-use purposes we need to ensure that the
       size of tag->buf is a multiple of sizeof(XML_Char).
    */
    bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
    if (bufSize > tag->bufEnd - tag->buf) {
      char *temp = (char *)REALLOC(parser, tag->buf, bufSize);
      if (temp == NULL)
        return XML_FALSE;
      /* if tag->name.str points to tag->buf (only when namespace
         processing is off) then we have to update it
      */
      if (tag->name.str == (XML_Char *)tag->buf)
        tag->name.str = (XML_Char *)temp;
      /* if tag->name.localPart is set (when namespace processing is on)
         then update it as well, since it will always point into tag->buf
      */
      if (tag->name.localPart)
        tag->name.localPart
            = (XML_Char *)temp + (tag->name.localPart - (XML_Char *)tag->buf);
      tag->buf = temp;
      tag->bufEnd = temp + bufSize;
      rawNameBuf = temp + nameLen;
    }
    memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
    tag->rawName = rawNameBuf;
    tag = tag->parent;
  }
  return XML_TRUE;
}
Commit message: mm: enforce min addr even if capable() in expand_downwards()

security_mmap_addr() does a capability check with current_cred(), but
we can reach this code from contexts like a VFS write handler where
current_cred() must not be used.

This can be abused on systems without SMAP to make NULL pointer
dereferences exploitable again.

Fixes: 8869477a49c3 ("security: protect from stack expansion into low vm addresses")
Cc: stable@kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
CVE: CVE-2019-9213
CWE: CWE-476
Vulnerability description: In the Linux kernel before 4.20.14, expand_downwards in mm/mmap.c lacks a check for the mmap minimum address, which makes it easier for attackers to exploit kernel NULL pointer dereferences on non-SMAP platforms. This is related to a capability check for the wrong task.

Project: linux
File: mmap.c

arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
			  const unsigned long len, const unsigned long pgoff,
			  const unsigned long flags)
{
	struct vm_area_struct *vma, *prev;
	struct mm_struct *mm = current->mm;
	unsigned long addr = addr0;
	struct vm_unmapped_area_info info;
	const unsigned long mmap_end = arch_get_mmap_end(addr);

	/* requested length too big for entire address space */
	if (len > mmap_end - mmap_min_addr)
		return -ENOMEM;

	if (flags & MAP_FIXED)
		return addr;

	/* requesting a specific address */
	if (addr) {
		addr = PAGE_ALIGN(addr);
		vma = find_vma_prev(mm, addr, &prev);
		if (mmap_end - len >= addr && addr >= mmap_min_addr &&
				(!vma || addr + len <= vm_start_gap(vma)) &&
				(!prev || addr >= vm_end_gap(prev)))
			return addr;
	}

	info.flags = VM_UNMAPPED_AREA_TOPDOWN;
	info.length = len;
	info.low_limit = max(PAGE_SIZE, mmap_min_addr);
	info.high_limit = arch_get_mmap_base(addr, mm->mmap_base);
	info.align_mask = 0;
	addr = vm_unmapped_area(&info);

	/*
	 * A failed mmap() very likely causes application failure,
	 * so fall back to the bottom-up function here. This scenario
	 * can happen with large stack limits and large mmap()
	 * allocations.
	 */
	if (offset_in_page(addr)) {
		VM_BUG_ON(addr != -ENOMEM);
		info.flags = 0;
		info.low_limit = TASK_UNMAPPED_BASE;
		info.high_limit = mmap_end;
		addr = vm_unmapped_area(&info);
	}

	return addr;
}

Project: linux
File: mmap.c

static void vma_gap_update(struct vm_area_struct *vma)
{
	/*
	 * As it turns out, RB_DECLARE_CALLBACKS() already created a callback
	 * function that does exacltly what we want.
	 */
	vma_gap_callbacks_propagate(&vma->vm_rb, NULL);
}
Commit message: netfilter: nf_nat_snmp_basic: add missing length checks in ASN.1 cbs

The generic ASN.1 decoder infrastructure doesn't guarantee that callbacks
will get as much data as they expect; callbacks have to check the `datalen`
parameter before looking at `data`. Make sure that snmp_version() and
snmp_helper() don't read/write beyond the end of the packet data.

(Also move the assignment to `pdata` down below the check to make it clear
that it isn't necessarily a pointer we can use before the `datalen` check.)

Fixes: cc2d58634e0f ("netfilter: nf_nat_snmp_basic: use asn1 decoder library")
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
CVE: CVE-2019-9162
CWE: CWE-129
Vulnerability description: In the Linux kernel before 4.20.12, net/ipv4/netfilter/nf_nat_snmp_basic_main.c in the SNMP NAT module has insufficient ASN.1 length checks (aka an array index error), making out-of-bounds read and write operations possible, leading to an OOPS or local privilege escalation. This affects snmp_version and snmp_helper.

Project: linux
File: nf_nat_snmp_basic_main.c

static void fast_csum(struct snmp_ctx *ctx, unsigned char offset)
{
	unsigned char s[12] = {0,};
	int size;

	if (offset & 1) {
		memcpy(&s[1], &ctx->from, 4);
		memcpy(&s[7], &ctx->to, 4);
		s[0] = ~0;
		s[1] = ~s[1];
		s[2] = ~s[2];
		s[3] = ~s[3];
		s[4] = ~s[4];
		s[5] = ~0;
		size = 12;
	} else {
		memcpy(&s[0], &ctx->from, 4);
		memcpy(&s[4], &ctx->to, 4);
		s[0] = ~s[0];
		s[1] = ~s[1];
		s[2] = ~s[2];
		s[3] = ~s[3];
		size = 8;
	}
	*ctx->check = csum_fold(csum_partial(s, size,
					     ~csum_unfold(*ctx->check)));
}

Project: linux
File: nf_nat_snmp_basic_main.c

static void __exit nf_nat_snmp_basic_fini(void)
{
	RCU_INIT_POINTER(nf_nat_snmp_hook, NULL);
	synchronize_rcu();
	nf_conntrack_helper_unregister(&snmp_trap_helper);
}

Project: linux
File: nf_nat_snmp_basic_main.c

static int __init nf_nat_snmp_basic_init(void)
{
	BUG_ON(nf_nat_snmp_hook != NULL);
	RCU_INIT_POINTER(nf_nat_snmp_hook, help);

	return nf_conntrack_helper_register(&snmp_trap_helper);
}

Project: linux
File: nf_nat_snmp_basic_main.c

static int snmp_translate(struct nf_conn *ct, int dir, struct sk_buff *skb)
{
	struct iphdr *iph = ip_hdr(skb);
	struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
	u16 datalen = ntohs(udph->len) - sizeof(struct udphdr);
	char *data = (unsigned char *)udph + sizeof(struct udphdr);
	struct snmp_ctx ctx;
	int ret;

	if (dir == IP_CT_DIR_ORIGINAL) {
		ctx.from = ct->tuplehash[dir].tuple.src.u3.ip;
		ctx.to = ct->tuplehash[!dir].tuple.dst.u3.ip;
	} else {
		ctx.from = ct->tuplehash[!dir].tuple.src.u3.ip;
		ctx.to = ct->tuplehash[dir].tuple.dst.u3.ip;
	}

	if (ctx.from == ctx.to)
		return NF_ACCEPT;

	ctx.begin = (unsigned char *)udph + sizeof(struct udphdr);
	ctx.check = &udph->check;
	ret = asn1_ber_decoder(&nf_nat_snmp_basic_decoder, &ctx, data, datalen);
	if (ret < 0) {
		nf_ct_helper_log(skb, ct, "parser failed\n");
		return NF_DROP;
	}

	return NF_ACCEPT;
}
Commit message: (for 4.9.3) CVE-2018-16452/SMB: prevent stack exhaustion

Enforce a limit on how many times smb_fdata() can recurse.

This fixes a stack exhaustion discovered by Include Security working
under the Mozilla SOS program in 2018 by means of code audit.
CVE: CVE-2018-16452
CWE: CWE-674
Vulnerability description: The SMB parser in tcpdump before 4.9.3 has stack exhaustion in smbutil.c:smb_fdata() via recursion.

Project: tcpdump
File: smbutil.c

name_len(netdissect_options *ndo,
         const unsigned char *s, const unsigned char *maxbuf)
{
    const unsigned char *s0 = s;
    unsigned char c;

    if (s >= maxbuf)
	return(-1);	/* name goes past the end of the buffer */
    ND_TCHECK2(*s, 1);
    c = *s;
    if ((c & 0xC0) == 0xC0)
	return(2);
    while (*s) {
	if (s >= maxbuf)
	    return(-1);	/* name goes past the end of the buffer */
	ND_TCHECK2(*s, 1);
	s += (*s) + 1;
	ND_TCHECK2(*s, 1);
    }
    return(PTR_DIFF(s, s0) + 1);

trunc:
    return(-1);	/* name goes past the end of the buffer */
}
Commit message: (for 4.9.3) CVE-2018-16229/DCCP: Fix printing "Timestamp" and "Timestamp Echo" options

Add some comments.

Moreover:
Put a function definition name at the beginning of the line.

(This change was ported from commit 6df4852 in the master branch.)

Ryan Ackroyd had independently identified this buffer over-read later by
means of fuzzing and provided the packet capture file for the test.
CVE: CVE-2018-16229
CWE: CWE-125
Vulnerability description: The DCCP parser in tcpdump before 4.9.3 has a buffer over-read in print-dccp.c:dccp_print_option().

Project: tcpdump
File: print-dccp.c

static int dccp6_cksum(netdissect_options *ndo, const struct ip6_hdr *ip6,
	const struct dccp_hdr *dh, u_int len)
{
	return nextproto6_cksum(ndo, ip6, (const uint8_t *)(const void *)dh, len,
				dccp_csum_coverage(dh, len), IPPROTO_DCCP);
}

Project: tcpdump
File: print-dccp.c

static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh)
{
	return DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : sizeof(struct dccp_hdr);
}

Project: tcpdump
File: print-dccp.c

static int dccp_cksum(netdissect_options *ndo, const struct ip *ip,
	const struct dccp_hdr *dh, u_int len)
{
	return nextproto4_cksum(ndo, ip, (const uint8_t *)(const void *)dh, len,
				dccp_csum_coverage(dh, len), IPPROTO_DCCP);
}

Project: tcpdump
File: print-dccp.c

static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len)
{
	u_int cov;

	if (DCCPH_CSCOV(dh) == 0)
		return len;
	cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(uint32_t);
	return (cov > len)? len : cov;
}

Project: tcpdump
File: print-dccp.c

static void dccp_print_ack_no(netdissect_options *ndo, const u_char *bp)
{
	const struct dccp_hdr *dh = (const struct dccp_hdr *)bp;
	const u_char *ackp = bp + dccp_basic_hdr_len(dh);
	uint64_t ackno;

	if (DCCPH_X(dh) != 0) {
		ND_TCHECK2(*ackp, 8);
		ackno = EXTRACT_48BITS(ackp + 2);
	} else {
		ND_TCHECK2(*ackp, 4);
		ackno = EXTRACT_24BITS(ackp + 1);
	}

	ND_PRINT((ndo, "(ack=%" PRIu64 ") ", ackno));
trunc:
	return;
}

Project: tcpdump
File: print-dccp.c

static const char *dccp_reset_code(uint8_t code)
{
	if (code >= __DCCP_RESET_CODE_LAST)
		return "invalid";
	return dccp_reset_codes[code];
}

Project: tcpdump
File: print-dccp.c

static uint64_t dccp_seqno(const u_char *bp)
{
	const struct dccp_hdr *dh = (const struct dccp_hdr *)bp;
	uint64_t seqno;

	if (DCCPH_X(dh) != 0) {
		const struct dccp_hdr_ext *dhx = (const struct dccp_hdr_ext *)bp;
		seqno = EXTRACT_48BITS(dhx->dccph_seq);
	} else {
		seqno = EXTRACT_24BITS(dh->dccph_seq);
	}

	return seqno;
}
Commit message: (for 4.9.3) CVE-2018-16228/HNCP: make buffer access safer

print_prefix() has a buffer and does not initialize it. It may call
decode_prefix6(), which also does not initialize the buffer on invalid
input. When that happens, make sure to return from print_prefix() before
trying to print the [still uninitialized] buffer.

This fixes a buffer over-read discovered by Wang Junjie of 360 ESG
Codesafe Team.

Add a test using the capture file supplied by the reporter(s).
CVE: CVE-2018-16228
CWE: CWE-125
Vulnerability description: The HNCP parser in tcpdump before 4.9.3 has a buffer over-read in print-hncp.c:print_prefix().

Project: tcpdump
File: print-hncp.c

dhcpv4_print(netdissect_options *ndo,
             const u_char *cp, u_int length, int indent)
{
    u_int i, t;
    const u_char *tlv, *value;
    uint8_t type, optlen;

    i = 0;
    while (i < length) {
        if (i + 2 > length)
            return -1;
        tlv = cp + i;
        type = (uint8_t)tlv[0];
        optlen = (uint8_t)tlv[1];
        value = tlv + 2;

        ND_PRINT((ndo, "\n"));
        for (t = indent; t > 0; t--)
            ND_PRINT((ndo, "\t"));

        ND_PRINT((ndo, "%s", tok2str(dh4opt_str, "Unknown", type)));
        ND_PRINT((ndo," (%u)", optlen + 2 ));
        if (i + 2 + optlen > length)
            return -1;

        switch (type) {
        case DH4OPT_DNS_SERVERS:
        case DH4OPT_NTP_SERVERS: {
            if (optlen < 4 || optlen % 4 != 0) {
                return -1;
            }
            for (t = 0; t < optlen; t += 4)
                ND_PRINT((ndo, " %s", ipaddr_string(ndo, value + t)));
        }
            break;
        case DH4OPT_DOMAIN_SEARCH: {
            const u_char *tp = value;
            while (tp < value + optlen) {
                ND_PRINT((ndo, " "));
                if ((tp = ns_nprint(ndo, tp, value + optlen)) == NULL)
                    return -1;
            }
        }
            break;
        }

        i += 2 + optlen;
    }
    return 0;
}
Commit message: (for 4.9.3) CVE-2018-14881/BGP: Fix BGP_CAPCODE_RESTART.

Add a bounds check and a comment to bgp_capabilities_print().

This fixes a buffer over-read discovered by Bhargava Shastry,
SecT/TU Berlin.

Add a test using the capture file supplied by the reporter(s).
CVE: CVE-2018-14881
CWE: CWE-125
Vulnerability description: The BGP parser in tcpdump before 4.9.3 has a buffer over-read in print-bgp.c:bgp_capabilities_print() (BGP_CAPCODE_RESTART).

Project: tcpdump
File: print-bgp.c

bgp_notification_print(netdissect_options *ndo,
                       const u_char *dat, int length)
{
	struct bgp_notification bgpn;
	const u_char *tptr;

	ND_TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
	memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);

        /* some little sanity checking */
        if (length<BGP_NOTIFICATION_SIZE)
            return;

	ND_PRINT((ndo, ", %s (%u)",
	       tok2str(bgp_notify_major_values, "Unknown Error",
			  bgpn.bgpn_major),
	       bgpn.bgpn_major));

        switch (bgpn.bgpn_major) {

        case BGP_NOTIFY_MAJOR_MSG:
            ND_PRINT((ndo, ", subcode %s (%u)",
		   tok2str(bgp_notify_minor_msg_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));
            break;
        case BGP_NOTIFY_MAJOR_OPEN:
            ND_PRINT((ndo, ", subcode %s (%u)",
		   tok2str(bgp_notify_minor_open_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));
            break;
        case BGP_NOTIFY_MAJOR_UPDATE:
            ND_PRINT((ndo, ", subcode %s (%u)",
		   tok2str(bgp_notify_minor_update_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));
            break;
        case BGP_NOTIFY_MAJOR_FSM:
            ND_PRINT((ndo, " subcode %s (%u)",
		   tok2str(bgp_notify_minor_fsm_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));
            break;
        case BGP_NOTIFY_MAJOR_CAP:
            ND_PRINT((ndo, " subcode %s (%u)",
		   tok2str(bgp_notify_minor_cap_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));
            break;
        case BGP_NOTIFY_MAJOR_CEASE:
            ND_PRINT((ndo, ", subcode %s (%u)",
		   tok2str(bgp_notify_minor_cease_values, "Unknown",
			      bgpn.bgpn_minor),
		   bgpn.bgpn_minor));

	    /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
             * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
             */
	    if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) {
		tptr = dat + BGP_NOTIFICATION_SIZE;
		ND_TCHECK2(*tptr, 7);
		ND_PRINT((ndo, ", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
		       tok2str(af_values, "Unknown",
				  EXTRACT_16BITS(tptr)),
		       EXTRACT_16BITS(tptr),
		       tok2str(bgp_safi_values, "Unknown", *(tptr+2)),
		       *(tptr+2),
		       EXTRACT_32BITS(tptr+3)));
	    }
            break;
        default:
            break;
        }

	return;
trunc:
	ND_PRINT((ndo, "[|BGP]"));
}
Commit message: (for 4.9.3) CVE-2018-14461/LDP: Fix a bounds check

In ldp_tlv_print(), the FT Session TLV length must be 12, not 8 (RFC3479)

This fixes a buffer over-read discovered by Konrad Rieck and
Bhargava Shastry.

Add a test using the capture file supplied by the reporter(s).

Moreover:
Add and use tstr[].
Add a comment.
CVE: CVE-2018-14461
CWE: CWE-125
Vulnerability description: The LDP parser in tcpdump before 4.9.3 has a buffer over-read in print-ldp.c:ldp_tlv_print().

Project: tcpdump
File: print-ldp.c

ldp_print(netdissect_options *ndo,
          register const u_char *pptr, register u_int len)
{
    u_int processed;
    while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
        processed = ldp_pdu_print(ndo, pptr);
        if (processed == 0)
            return;
        if (len < processed) {
            ND_PRINT((ndo, " [remaining length %u < %u]", len, processed));
            ND_PRINT((ndo, "%s", istr));
            break;

        }
        len -= processed;
        pptr += processed;
    }
}