db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: gpg: Avoid infinite loop in uncompressing garbled packets.

* g10/compress.c (do_uncompress): Limit the number of extra FF bytes.
--

A packet like (a3 01 5b ff) leads to an infinite loop.  Using
--max-output won't help if it is a partial packet.  This patch
actually fixes a regression introduced on 1999-05-31 (c34c6769).
Actually it would be sufficient to stuff just one extra 0xff byte.
Given that this problem popped up only after 15 years, I feel safer to
allow for a very few FF bytes.

Thanks to Olivier Levillain and Florian Maury for their detailed
report.
CVE: CVE-2014-4617
CWE: CWE-20
Vulnerability description: The do_uncompress function in g10/compress.c in GnuPG 1.x before 1.4.17 and 2.x before 2.0.24 allows context-dependent attackers to cause a denial of service (infinite loop) via malformed compressed packets, as demonstrated by an a3 01 5b ff byte sequence.

Project: gnupg
File: compress.c

do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
	       IOBUF a, size_t *ret_len )
{
    int zrc;
    int rc=0;
    size_t n;
    int nread, count;
    int refill = !zs->avail_in;

    if( DBG_FILTER )
	log_debug("begin inflate: avail_in=%u, avail_out=%u, inbuf=%u\n",
		(unsigned)zs->avail_in, (unsigned)zs->avail_out,
		(unsigned)zfx->inbufsize );
    do {
	if( zs->avail_in < zfx->inbufsize && refill ) {
	    n = zs->avail_in;
	    if( !n )
            zs->next_in = BYTEF_CAST (zfx->inbuf);
	    count = zfx->inbufsize - n;
	    nread = iobuf_read( a, zfx->inbuf + n, count );
	    if( nread == -1 ) nread = 0;
	    n += nread;
	    /* If we use the undocumented feature to suppress
	     * the zlib header, we have to give inflate an
	     * extra dummy byte to read */
	    if( nread < count && zfx->algo == 1 ) {
		*(zfx->inbuf + n) = 0xFF; /* is it really needed ? */
		zfx->algo1hack = 1;
		n++;
	    }
	    zs->avail_in = n;
	}
	refill = 1;
	if( DBG_FILTER )
	    log_debug("enter inflate: avail_in=%u, avail_out=%u\n",
		    (unsigned)zs->avail_in, (unsigned)zs->avail_out);
	zrc = inflate ( zs, Z_SYNC_FLUSH );
	if( DBG_FILTER )
	    log_debug("leave inflate: avail_in=%u, avail_out=%u, zrc=%d\n",
		   (unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
	if( zrc == Z_STREAM_END )
	    rc = -1; /* eof */
	else if( zrc != Z_OK && zrc != Z_BUF_ERROR ) {
	    if( zs->msg )
		log_fatal("zlib inflate problem: %s\n", zs->msg );
	    else
		log_fatal("zlib inflate problem: rc=%d\n", zrc );
	}
    } while( zs->avail_out && zrc != Z_STREAM_END && zrc != Z_BUF_ERROR );

    *ret_len = zfx->outbufsize - zs->avail_out;
    if( DBG_FILTER )
	log_debug("do_uncompress: returning %u bytes (%u ignored)\n",
                  (unsigned int)*ret_len, (unsigned int)zs->avail_in );
    return rc;
}
Commit message: vrend: fix a leak in context create internal

Create a context more than once causes memory leak issue.
Juest return if the context exists.

Signed-off-by: Li Qiang <liq3ea@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
CVE: CVE-2016-10163
CWE: CWE-399
Vulnerability description: Memory leak in the vrend_renderer_context_create_internal function in vrend_decode.c in virglrenderer before 0.6.0 allows local guest OS users to cause a denial of service (host memory consumption) by repeatedly creating a decode context.

Project: virglrenderer
File: vrend_decode.c

void vrend_renderer_context_create_internal(uint32_t handle, uint32_t nlen,
                                            const char *debug_name)
{
   struct vrend_decode_ctx *dctx;

   if (handle >= VREND_MAX_CTX)
      return;

   dctx = malloc(sizeof(struct vrend_decode_ctx));
   if (!dctx)
      return;

   dctx->grctx = vrend_create_context(handle, nlen, debug_name);
   if (!dctx->grctx) {
      free(dctx);
      return;
   }

   dctx->ds = &dctx->ids;

   dec_ctx[handle] = dctx;
}
Commit message: Avoid a crash (double-free) when SSH connection fails
CVE: CVE-2017-18594
CWE: CWE-415
Vulnerability description: nse_libssh2.cc in Nmap 7.70 is subject to a denial of service condition due to a double free when an SSH connection fails, as demonstrated by a leading \n character to ssh-brute.nse or ssh-auth-methods.nse.

Project: nmap
File: nse_libssh2.cc

static int do_session_handshake (lua_State *L, int status, lua_KContext ctx) {
    int rc;
    struct ssh_userdata *sshu = NULL;

    assert(lua_gettop(L) == 4);
    sshu = (struct ssh_userdata *) nseU_checkudata(L, 3, SSH2_UDATA, "ssh2");

    while ((rc = libssh2_session_handshake(sshu->session, sshu->sp[0])) == LIBSSH2_ERROR_EAGAIN) {
        luaL_getmetafield(L, 3, "filter");
        lua_pushvalue(L, 3);

        assert(lua_status(L) == LUA_OK);
        lua_callk(L, 1, 0, 0, do_session_handshake);
    }

    if (rc) {
        libssh2_session_free(sshu->session);
        return luaL_error(L, "Unable to complete libssh2 handshake.");
    }

    // lua_pushvalue(L, 3);
    lua_settop(L, 3);

    return 1;
}
Commit message: Revert "arm64: Introduce execute-only page access permissions"

This reverts commit bc07c2c6e9ed125d362af0214b6313dca180cb08.

While the aim is increased security for --x memory maps, it does not
protect against kernel level reads. Until SECCOMP is implemented for
arm64, revert this patch to avoid giving a false idea of execute-only
mappings.

Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
CVE: CVE-2014-9803
CWE: CWE-19
Vulnerability description: arch/arm64/include/asm/pgtable.h in the Linux kernel before 3.15-rc5-next-20140519, as used in Android before 2016-07-05 on Nexus 5X and 6P devices, mishandles execute-only pages, which allows attackers to gain privileges via a crafted application, aka Android internal bug 28557020.

Project: linux

static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
			      pte_t *ptep, pte_t pte)
{
	if (pte_valid_ng(pte)) {
		if (!pte_special(pte) && pte_exec(pte))
			__sync_icache_dcache(pte, addr);
		if (pte_dirty(pte) && pte_write(pte))
			pte_val(pte) &= ~PTE_RDONLY;
		else
			pte_val(pte) |= PTE_RDONLY;
	}

	set_pte(ptep, pte);
}
Commit message: fs: prevent page refcount overflow in pipe_buf_get

Change pipe_buf_get() to return a bool indicating whether it succeeded
in raising the refcount of the page (if the thing in the pipe is a page).
This removes another mechanism for overflowing the page refcount.  All
callers converted to handle a failure.

Reported-by: Jann Horn <jannh@google.com>
Signed-off-by: Matthew Wilcox <willy@infradead.org>
Cc: stable@kernel.org
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
CVE: CVE-2019-11487
CWE: CWE-416
Vulnerability description: The Linux kernel before 5.1-rc5 allows page->_refcount reference count overflow, with resultant use-after-free issues, if about 140 GiB of RAM exists. This is related to fs/fuse/dev.c, fs/pipe.c, fs/splice.c, include/linux/mm.h, include/linux/pipe_fs_i.h, kernel/trace/trace.c, mm/gup.c, and mm/hugetlb.c. It can occur with FUSE requests.

Project: linux
File: pipe_fs_i.h

static inline void pipe_buf_get(struct pipe_inode_info *pipe,
				struct pipe_buffer *buf)
{
	buf->ops->get(pipe, buf);
}
Commit message: Added an extra check to MLU bounds

Thanks to Ibrahim el-sayed for spotting the bug
CVE: CVE-2016-10165
CWE: CWE-125
Vulnerability description: The Type_MLU_Read function in cmstypes.c in Little CMS (aka lcms2) allows remote attackers to obtain sensitive information or cause a denial of service via an image with a crafted ICC profile, which triggers an out-of-bounds heap read.

Project: Little-CMS
File: cmstypes.c

void *Type_MLU_Read(struct _cms_typehandler_struct* self, cmsIOHANDLER* io, cmsUInt32Number* nItems, cmsUInt32Number SizeOfTag)
{
    cmsMLU* mlu;
    cmsUInt32Number Count, RecLen, NumOfWchar;
    cmsUInt32Number SizeOfHeader;
    cmsUInt32Number  Len, Offset;
    cmsUInt32Number  i;
    wchar_t*         Block;
    cmsUInt32Number  BeginOfThisString, EndOfThisString, LargestPosition;

    *nItems = 0;
    if (!_cmsReadUInt32Number(io, &Count)) return NULL;
    if (!_cmsReadUInt32Number(io, &RecLen)) return NULL;

    if (RecLen != 12) {

        cmsSignalError(self->ContextID, cmsERROR_UNKNOWN_EXTENSION, "multiLocalizedUnicodeType of len != 12 is not supported.");
        return NULL;
    }

    mlu = cmsMLUalloc(self ->ContextID, Count);
    if (mlu == NULL) return NULL;

    mlu ->UsedEntries = Count;

    SizeOfHeader = 12 * Count + sizeof(_cmsTagBase);
    LargestPosition = 0;

    for (i=0; i < Count; i++) {

        if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Language)) goto Error;
        if (!_cmsReadUInt16Number(io, &mlu ->Entries[i].Country))  goto Error;

        // Now deal with Len and offset.
        if (!_cmsReadUInt32Number(io, &Len)) goto Error;
        if (!_cmsReadUInt32Number(io, &Offset)) goto Error;

        // Check for overflow
        if (Offset < (SizeOfHeader + 8)) goto Error;

        // True begin of the string
        BeginOfThisString = Offset - SizeOfHeader - 8;

        // Ajust to wchar_t elements
        mlu ->Entries[i].Len = (Len * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
        mlu ->Entries[i].StrW = (BeginOfThisString * sizeof(wchar_t)) / sizeof(cmsUInt16Number);

        // To guess maximum size, add offset + len
        EndOfThisString = BeginOfThisString + Len;
        if (EndOfThisString > LargestPosition)
            LargestPosition = EndOfThisString;
    }

    // Now read the remaining of tag and fill all strings. Subtract the directory
    SizeOfTag   = (LargestPosition * sizeof(wchar_t)) / sizeof(cmsUInt16Number);
    if (SizeOfTag == 0)
    {
        Block = NULL;
        NumOfWchar = 0;

    }
    else
    {
        Block = (wchar_t*) _cmsMalloc(self ->ContextID, SizeOfTag);
        if (Block == NULL) goto Error;
        NumOfWchar = SizeOfTag / sizeof(wchar_t);
        if (!_cmsReadWCharArray(io, NumOfWchar, Block)) goto Error;
    }

    mlu ->MemPool  = Block;
    mlu ->PoolSize = SizeOfTag;
    mlu ->PoolUsed = SizeOfTag;

    *nItems = 1;
    return (void*) mlu;

Error:
    if (mlu) cmsMLUfree(mlu);
    return NULL;
}
Commit message: CVE-2013-2168: _dbus_printf_string_upper_bound: copy the va_list for each use

Using a va_list more than once is non-portable: it happens to work
under the ABI of (for instance) x86 Linux, but not x86-64 Linux.

This led to _dbus_printf_string_upper_bound() crashing if it should
have returned exactly 1024 bytes. Many system services can be induced
to process a caller-controlled string in ways that
end up using _dbus_printf_string_upper_bound(), so this is a denial of
service.

Reviewed-by: Thiago Macieira <thiago@kde.org>
CVE: CVE-2013-2168
CWE: CWE-20
Vulnerability description: The _dbus_printf_string_upper_bound function in dbus/dbus-sysdeps-unix.c in D-Bus (aka DBus) 1.4.x before 1.4.26, 1.6.x before 1.6.12, and 1.7.x before 1.7.4 allows local users to cause a denial of service (service crash) via a crafted message.

Project: dbus
File: dbus-sysdeps-unix.c

_dbus_printf_string_upper_bound (const char *format,
                                 va_list     args)
{
  char static_buf[1024];
  int bufsize = sizeof (static_buf);
  int len;

  len = vsnprintf (static_buf, bufsize, format, args);

  /* If vsnprintf() returned non-negative, then either the string fits in
   * static_buf, or this OS has the POSIX and C99 behaviour where vsnprintf
   * returns the number of characters that were needed, or this OS returns the
   * truncated length.
   *
   * We ignore the possibility that snprintf might just ignore the length and
   * overrun the buffer (64-bit Solaris 7), because that's pathological.
   * If your libc is really that bad, come back when you have a better one. */
  if (len == bufsize)
    {
      /* This could be the truncated length (Tru64 and IRIX have this bug),
       * or the real length could be coincidentally the same. Which is it?
       * If vsnprintf returns the truncated length, we'll go to the slow
       * path. */
      if (vsnprintf (static_buf, 1, format, args) == 1)
        len = -1;
    }

  /* If vsnprintf() returned negative, we have to do more work.
   * HP-UX returns negative. */
  while (len < 0)
    {
      char *buf;

      bufsize *= 2;

      buf = dbus_malloc (bufsize);

      if (buf == NULL)
        return -1;

      len = vsnprintf (buf, bufsize, format, args);
      dbus_free (buf);

      /* If the reported length is exactly the buffer size, round up to the
       * next size, in case vsnprintf has been returning the truncated
       * length */
      if (len == bufsize)
        len = -1;
    }

  return len;
}
Commit message: None
CVE: CVE-2018-1000037
CWE: CWE-20
Vulnerability description: In MuPDF 1.12.0 and earlier, multiple reachable assertions in the PDF parser allow an attacker to cause a denial of service (assert crash) via a crafted file.

Project: ghostscript
File: pdf-op-run.c

begin_softmask(fz_context *ctx, pdf_run_processor *pr, softmask_save *save)
{
	pdf_gstate *gstate = pr->gstate + pr->gtop;
	pdf_xobject *softmask = gstate->softmask;
	fz_rect mask_bbox;
	fz_matrix tos_save[2], save_ctm;
	fz_matrix mask_matrix;
	fz_colorspace *mask_colorspace;

	save->softmask = softmask;
	if (softmask == NULL)
		return gstate;
	save->page_resources = gstate->softmask_resources;
	save->ctm = gstate->softmask_ctm;
	save_ctm = gstate->ctm;

	pdf_xobject_bbox(ctx, softmask, &mask_bbox);
	pdf_xobject_matrix(ctx, softmask, &mask_matrix);

	pdf_tos_save(ctx, &pr->tos, tos_save);

	if (gstate->luminosity)
		mask_bbox = fz_infinite_rect;
	else
	{
		fz_transform_rect(&mask_bbox, &mask_matrix);
		fz_transform_rect(&mask_bbox, &gstate->softmask_ctm);
	}
	gstate->softmask = NULL;
	gstate->softmask_resources = NULL;
	gstate->ctm = gstate->softmask_ctm;

	mask_colorspace = pdf_xobject_colorspace(ctx, softmask);

	if (gstate->luminosity && !mask_colorspace)
		mask_colorspace = fz_keep_colorspace(ctx, fz_device_gray(ctx));

	fz_try(ctx)
	{
		fz_begin_mask(ctx, pr->dev, &mask_bbox, gstate->luminosity, mask_colorspace, gstate->softmask_bc, &gstate->fill.color_params);
		pdf_run_xobject(ctx, pr, softmask, save->page_resources, &fz_identity, 1);
	}
	fz_always(ctx)
		fz_drop_colorspace(ctx, mask_colorspace);
	fz_catch(ctx)
	{
		fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
		/* FIXME: Ignore error - nasty, but if we throw from
		 * here the clip stack would be messed up. */
		/* TODO: pass cookie here to increase the cookie error count */
	}

	fz_end_mask(ctx, pr->dev);

	pdf_tos_restore(ctx, &pr->tos, tos_save);

	gstate = pr->gstate + pr->gtop;
	gstate->ctm = save_ctm;

	return gstate;
}

Project: ghostscript

	fz_always(ctx)
	{
		fz_drop_path(ctx, path);
	}

Project: ghostscript

	fz_catch(ctx)
	{
		fz_rethrow(ctx);
	}
Commit message: Did a mistake in the gmalloc -> gmallocn commit, it's a 4 here not a 3
CVE: CVE-2009-3605
CWE: CWE-189
Vulnerability description: Multiple integer overflows in Poppler 0.10.5 and earlier allow remote attackers to cause a denial of service (application crash) or possibly execute arbitrary code via a crafted PDF file, related to (1) glib/poppler-page.cc; (2) ArthurOutputDev.cc, (3) CairoOutputDev.cc, (4) GfxState.cc, (5) JBIG2Stream.cc, (6) PSOutputDev.cc, and (7) SplashOutputDev.cc in poppler/; and (8) SplashBitmap.cc, (9) Splash.cc, and (10) SplashFTFont.cc in splash/.  NOTE: this may overlap CVE-2009-0791.

Project: poppler

char *copyString(char *s) {
  char *s1;

  s1 = (char *)gmalloc(strlen(s) + 1);
  strcpy(s1, s);
  return s1;
}

Project: poppler

void gMemReport(FILE *f) {
  GMemHdr *p;

  fprintf(f, "%d memory allocations in all\n", gMemIndex);
  if (gMemAlloc > 0) {
    fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
    fprintf(f, " index     size\n");
    fprintf(f, "-------- --------\n");
    for (p = gMemHead; p; p = p->next) {
      fprintf(f, "%8d %8d\n", p->index, p->size);
    }
  } else {
    fprintf(f, "No memory blocks left allocated\n");
  }
}

Project: poppler

char *gstrndup(const char *s, size_t n) {
  char *s1 = (char*)gmalloc(n + 1); /* cannot return NULL for size > 0 */
  s1[n] = '\0';
  memcpy(s1, s, n);
  return s1;
}
Commit message: None
CVE: CVE-2017-15994
CWE: CWE-354
Vulnerability description: rsync 3.1.3-development before 2017-10-24 mishandles archaic checksums, which makes it easier for remote attackers to bypass intended access restrictions. NOTE: the rsync development branch has significant use beyond the rsync developers, e.g., the code has been copied for use in various GitHub projects.

Project: samba
File: checksum.c

void sum_update(const char *p, int32 len)
{
	switch (cursum_type) {
	  case CSUM_MD5:
		md5_update(&md, (uchar *)p, len);
		break;
	  case CSUM_MD4:
	  case CSUM_MD4_OLD:
	  case CSUM_MD4_BUSTED:
		if (len + sumresidue < CSUM_CHUNK) {
			memcpy(md.buffer + sumresidue, p, len);
			sumresidue += len;
			break;
		}

		if (sumresidue) {
			int32 i = CSUM_CHUNK - sumresidue;
			memcpy(md.buffer + sumresidue, p, i);
			mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
			len -= i;
			p += i;
		}

		while (len >= CSUM_CHUNK) {
			mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
			len -= CSUM_CHUNK;
			p += CSUM_CHUNK;
		}

		sumresidue = len;
		if (sumresidue)
			memcpy(md.buffer, p, sumresidue);
		break;
	  case CSUM_NONE:
		break;
	}
}
Commit message: CVE-2015-5330: ldb_dn: simplify and fix ldb_dn_escape_internal()

Previously we relied on NUL terminated strings and jumped back and
forth between copying escaped bytes and memcpy()ing un-escaped chunks.
This simple version is easier to reason about and works with
unterminated strings. It may also be faster as it avoids reading the
string twice (first with strcspn, then with memcpy).

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Pair-programmed-with: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
CVE: CVE-2015-5330
CWE: CWE-200
Vulnerability description: ldb before 1.1.24, as used in the AD LDAP server in Samba 4.x before 4.1.22, 4.2.x before 4.2.7, and 4.3.x before 4.3.3, mishandles string lengths, which allows remote attackers to obtain sensitive information from daemon heap memory by sending crafted packets and then reading (1) an error message or (2) a database value.

Project: samba
File: ldb_dn.c

struct ldb_dn *ldb_dn_from_ldb_val(TALLOC_CTX *mem_ctx,
                                   struct ldb_context *ldb,
                                   const struct ldb_val *strdn)
{
	struct ldb_dn *dn;

	if (! ldb) return NULL;

	if (strdn && strdn->data
	    && (strnlen((const char*)strdn->data, strdn->length) != strdn->length)) {
		/* The RDN must not contain a character with value 0x0 */
		return NULL;
	}

	dn = talloc_zero(mem_ctx, struct ldb_dn);
	LDB_DN_NULL_FAILED(dn);

	dn->ldb = talloc_get_type(ldb, struct ldb_context);
	if (dn->ldb == NULL) {
		/* the caller probably got the arguments to
		   ldb_dn_new() mixed up */
		talloc_free(dn);
		return NULL;
	}

	if (strdn->data && strdn->length) {
		const char *data = (const char *)strdn->data;
		size_t length = strdn->length;

		if (data[0] == '@') {
			dn->special = true;
		}
		dn->ext_linearized = talloc_strndup(dn, data, length);
		LDB_DN_NULL_FAILED(dn->ext_linearized);

		if (data[0] == '<') {
			const char *p_save, *p = dn->ext_linearized;
			do {
				p_save = p;
				p = strstr(p, ">;");
				if (p) {
					p = p + 2;
				}
			} while (p);

			if (p_save == dn->ext_linearized) {
				dn->linearized = talloc_strdup(dn, "");
			} else {
				dn->linearized = talloc_strdup(dn, p_save);
			}
			LDB_DN_NULL_FAILED(dn->linearized);
		} else {
			dn->linearized = dn->ext_linearized;
			dn->ext_linearized = NULL;
		}
	} else {
		dn->linearized = talloc_strdup(dn, "");
		LDB_DN_NULL_FAILED(dn->linearized);
	}

	return dn;

failed:
	talloc_free(dn);
	return NULL;
}

Project: samba
File: ldb_dn.c

static void ldb_dn_mark_invalid(struct ldb_dn *dn)
{
	dn->invalid = true;
}

Project: samba
File: ldb_dn.c

struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx,
			      struct ldb_context *ldb,
			      const char *new_fmt, ...)
{
	char *strdn;
	va_list ap;

	if ( (! mem_ctx) || (! ldb)) return NULL;

	va_start(ap, new_fmt);
	strdn = talloc_vasprintf(mem_ctx, new_fmt, ap);
	va_end(ap);

	if (strdn) {
		struct ldb_dn *dn = ldb_dn_new(mem_ctx, ldb, strdn);
		talloc_free(strdn);
		return dn;
	}

	return NULL;
}
Commit message: CVE-2015-5330: ldb_dn_explode: copy strings by length, not terminators

That is, memdup(), not strdup(). The terminators might not be there.

But, we have to make sure we put the terminator on, because we tend to
assume the terminator is there in other places.

Use talloc_set_name_const() on the resulting chunk so talloc_report()
remains unchanged.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Pair-programmed-with: Andrew Bartlett <abartlet@samba.org>
Pair-programmed-with: Garming Sam <garming@catalyst.net.nz>
Pair-programmed-with: Stefan Metzmacher <metze@samba.org>
Pair-programmed-with: Ralph Boehme <slow@samba.org>
CVE: CVE-2015-5330
CWE: CWE-200
Vulnerability description: ldb before 1.1.24, as used in the AD LDAP server in Samba 4.x before 4.1.22, 4.2.x before 4.2.7, and 4.3.x before 4.3.3, mishandles string lengths, which allows remote attackers to obtain sensitive information from daemon heap memory by sending crafted packets and then reading (1) an error message or (2) a database value.

Project: samba
File: ldb_dn.c

static int ldb_dn_escape_internal(char *dst, const char *src, int len)
{
	char c;
	char *d;
	int i;
	d = dst;

	for (i = 0; i < len; i++){
		c = src[i];
		switch (c) {
		case ' ':
			if (i == 0 || i == len - 1) {
				/* if at the beginning or end
				 * of the string then escape */
				*d++ = '\\';
				*d++ = c;
			} else {
				/* otherwise don't escape */
				*d++ = c;
			}
			break;

		case '#':
			/* despite the RFC, windows escapes a #
			   anywhere in the string */
		case ',':
		case '+':
		case '"':
		case '\\':
		case '<':
		case '>':
		case '?':
			/* these must be escaped using \c form */
			*d++ = '\\';
			*d++ = c;
			break;

		case ';':
		case '\r':
		case '\n':
		case '=':
		case '\0': {
			/* any others get \XX form */
			unsigned char v;
			const char *hexbytes = "0123456789ABCDEF";
			v = (const unsigned char)c;
			*d++ = '\\';
			*d++ = hexbytes[v>>4];
			*d++ = hexbytes[v&0xF];
			break;
		}
		default:
			*d++ = c;
		}
	}

	/* return the length of the resulting string */
	return (d - dst);
}