db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: Fixed memory leak reported in #1558 and fixed other leak.
CVE: CVE-2019-16713
CWE: CWE-401
Vulnerability description: ImageMagick 7.0.8-43 has a memory leak in coders/dot.c, as demonstrated by PingImage in MagickCore/constitute.c.

Project: ImageMagick6
File: dot.c

static Image *ReadDOTImage(const ImageInfo *image_info,ExceptionInfo *exception)
{
  char
    command[MaxTextExtent];

  const char
    *option;

  graph_t
    *graph;

  Image
    *image;

  ImageInfo
    *read_info;

  MagickBooleanType
    status;

  /*
    Open image file.
  */
  assert(image_info != (const ImageInfo *) NULL);
  assert(image_info->signature == MagickCoreSignature);
  if (image_info->debug != MagickFalse)
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
      image_info->filename);
  assert(exception != (ExceptionInfo *) NULL);
  assert(exception->signature == MagickCoreSignature);
  assert(graphic_context != (GVC_t *) NULL);
  image=AcquireImage(image_info);
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  if (status == MagickFalse)
    {
      image=DestroyImageList(image);
      return((Image *) NULL);
    }
  read_info=CloneImageInfo(image_info);
  SetImageInfoBlob(read_info,(void *) NULL,0);
  (void) CopyMagickString(read_info->magick,"SVG",MaxTextExtent);
  (void) AcquireUniqueFilename(read_info->filename);
  (void) FormatLocaleString(command,MaxTextExtent,"-Tsvg -o%s %s",
    read_info->filename,image_info->filename);
#if !defined(WITH_CGRAPH)
  graph=agread(GetBlobFileHandle(image));
#else
  graph=agread(GetBlobFileHandle(image),(Agdisc_t *) NULL);
#endif
  if (graph == (graph_t *) NULL)
    {
      (void) RelinquishUniqueFileResource(read_info->filename);
      return ((Image *) NULL);
    }
  option=GetImageOption(image_info,"dot:layout-engine");
  if (option == (const char *) NULL)
    gvLayout(graphic_context,graph,(char *) "dot");
  else
    gvLayout(graphic_context,graph,(char *) option);
  gvRenderFilename(graphic_context,graph,(char *) "svg",read_info->filename);
  gvFreeLayout(graphic_context,graph);
  agclose(graph);
  /*
    Read SVG graph.
  */
  (void) CopyMagickString(read_info->magick,"SVG",MaxTextExtent);
  image=ReadImage(read_info,exception);
  (void) RelinquishUniqueFileResource(read_info->filename);
  read_info=DestroyImageInfo(read_info);
  if (image == (Image *) NULL)
    return((Image *) NULL);
  return(GetFirstImageInList(image));
}
Commit message: media: go7007: fix a miss of snd_card_free

go7007_snd_init() misses a snd_card_free() in an error path.
Add the missed call to fix it.

Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
CVE: CVE-2019-20810
CWE: CWE-401
Vulnerability description: go7007_snd_init in drivers/media/usb/go7007/snd-go7007.c in the Linux kernel before 5.6 does not call snd_card_free for a failure path, which causes a memory leak, aka CID-9453264ef586.

Project: linux
File: snd-go7007.c

int go7007_snd_init(struct go7007 *go)
{
	static int dev;
	struct go7007_snd *gosnd;
	int ret;

	if (dev >= SNDRV_CARDS)
		return -ENODEV;
	if (!enable[dev]) {
		dev++;
		return -ENOENT;
	}
	gosnd = kmalloc(sizeof(struct go7007_snd), GFP_KERNEL);
	if (gosnd == NULL)
		return -ENOMEM;
	spin_lock_init(&gosnd->lock);
	gosnd->hw_ptr = gosnd->w_idx = gosnd->avail = 0;
	gosnd->capturing = 0;
	ret = snd_card_new(go->dev, index[dev], id[dev], THIS_MODULE, 0,
			   &gosnd->card);
	if (ret < 0) {
		kfree(gosnd);
		return ret;
	}
	ret = snd_device_new(gosnd->card, SNDRV_DEV_LOWLEVEL, go,
			&go7007_snd_device_ops);
	if (ret < 0) {
		kfree(gosnd);
		return ret;
	}
	ret = snd_pcm_new(gosnd->card, "go7007", 0, 0, 1, &gosnd->pcm);
	if (ret < 0) {
		snd_card_free(gosnd->card);
		kfree(gosnd);
		return ret;
	}
	strscpy(gosnd->card->driver, "go7007", sizeof(gosnd->card->driver));
	strscpy(gosnd->card->shortname, go->name, sizeof(gosnd->card->shortname));
	strscpy(gosnd->card->longname, gosnd->card->shortname,
		sizeof(gosnd->card->longname));

	gosnd->pcm->private_data = go;
	snd_pcm_set_ops(gosnd->pcm, SNDRV_PCM_STREAM_CAPTURE,
			&go7007_snd_capture_ops);

	ret = snd_card_register(gosnd->card);
	if (ret < 0) {
		snd_card_free(gosnd->card);
		kfree(gosnd);
		return ret;
	}

	gosnd->substream = NULL;
	go->snd_context = gosnd;
	v4l2_device_get(&go->v4l2_dev);
	++dev;

	return 0;
}
Commit message: Replaced illegal-number-of-channel assertions with run-time exception
CVE: CVE-2018-14044
CWE: CWE-617
Vulnerability description: The RateTransposer::setChannels function in RateTransposer.cpp in libSoundTouch.a in Olli Parviainen SoundTouch 2.0 allows remote attackers to cause a denial of service (assertion failure and application exit), as demonstrated by SoundStretch.

Project: soundtouch
File: SoundTouch.cpp

void SoundTouch::setChannels(uint numChannels)
{
    /*if (numChannels != 1 && numChannels != 2) 
    {
        //ST_THROW_RT_ERROR("Illegal number of channels");
        return;
    }*/
    channels = numChannels;
    pRateTransposer->setChannels((int)numChannels);
    pTDStretch->setChannels((int)numChannels);
}

Project: soundtouch
File: RateTransposer.cpp

void RateTransposer::setChannels(int nChannels)
{
    assert(nChannels > 0);

    if (pTransposer->numChannels == nChannels) return;
    pTransposer->setChannels(nChannels);

    inputBuffer.setChannels(nChannels);
    midBuffer.setChannels(nChannels);
    outputBuffer.setChannels(nChannels);
}

Project: soundtouch
File: FIFOSampleBuffer.cpp

void FIFOSampleBuffer::setChannels(int numChannels)
{
    uint usedBytes;

    assert(numChannels > 0);
    usedBytes = channels * samplesInBuffer;
    channels = (uint)numChannels;
    samplesInBuffer = usedBytes / channels;
}

Project: soundtouch
File: TDStretch.cpp

void TDStretch::setChannels(int numChannels)
{
    assert(numChannels > 0);
    if (channels == numChannels) return;
//    assert(numChannels == 1 || numChannels == 2);

    channels = numChannels;
    inputBuffer.setChannels(channels);
    outputBuffer.setChannels(channels);

    // re-init overlap/buffer
    overlapLength=0;
    setParameters(sampleRate);
}
Commit message: Bug 757711: heap-buffer-overflow in xmlFAParsePosCharGroup <https://bugzilla.gnome.org/show_bug.cgi?id=757711>

* xmlregexp.c:
(xmlFAParseCharRange): Only advance to the next character if
there is no error.  Advancing to the next character in case of
an error while parsing regexp leads to an out of bounds access.
CVE: CVE-2016-1840
CWE: CWE-119
Vulnerability description: Heap-based buffer overflow in the xmlFAParsePosCharGroup function in libxml2 before 2.9.4, as used in Apple iOS before 9.3.2, OS X before 10.11.5, tvOS before 9.2.1, and watchOS before 2.2.1, allows remote attackers to execute arbitrary code or cause a denial of service (memory corruption) via a crafted XML document.

Project: libxml2
File: xmlregexp.c

xmlFAParseCharRange(xmlRegParserCtxtPtr ctxt) {
    int cur, len;
    int start = -1;
    int end = -1;

    if (CUR == '\0') {
        ERROR("Expecting ']'");
	return;
    }

    cur = CUR;
    if (cur == '\\') {
	NEXT;
	cur = CUR;
	switch (cur) {
	    case 'n': start = 0xA; break;
	    case 'r': start = 0xD; break;
	    case 't': start = 0x9; break;
	    case '\\': case '|': case '.': case '-': case '^': case '?':
	    case '*': case '+': case '{': case '}': case '(': case ')':
	    case '[': case ']':
		start = cur; break;
	    default:
		ERROR("Invalid escape value");
		return;
	}
	end = start;
        len = 1;
    } else if ((cur != 0x5B) && (cur != 0x5D)) {
        end = start = CUR_SCHAR(ctxt->cur, len);
    } else {
	ERROR("Expecting a char range");
	return;
    }
    /*
     * Since we are "inside" a range, we can assume ctxt->cur is past
     * the start of ctxt->string, and PREV should be safe
     */
    if ((start == '-') && (NXT(1) != ']') && (PREV != '[') && (PREV != '^')) {
	NEXTL(len);
	return;
    }
    NEXTL(len);
    cur = CUR;
    if ((cur != '-') || (NXT(1) == ']')) {
        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
		              XML_REGEXP_CHARVAL, start, end, NULL);
	return;
    }
    NEXT;
    cur = CUR;
    if (cur == '\\') {
	NEXT;
	cur = CUR;
	switch (cur) {
	    case 'n': end = 0xA; break;
	    case 'r': end = 0xD; break;
	    case 't': end = 0x9; break;
	    case '\\': case '|': case '.': case '-': case '^': case '?':
	    case '*': case '+': case '{': case '}': case '(': case ')':
	    case '[': case ']':
		end = cur; break;
	    default:
		ERROR("Invalid escape value");
		return;
	}
        len = 1;
    } else if ((cur != 0x5B) && (cur != 0x5D)) {
        end = CUR_SCHAR(ctxt->cur, len);
    } else {
	ERROR("Expecting the end of a char range");
	return;
    }
    NEXTL(len);
    /* TODO check that the values are acceptable character ranges for XML */
    if (end < start) {
	ERROR("End of range is before start of range");
    } else {
        xmlRegAtomAddRange(ctxt, ctxt->atom, ctxt->neg,
		           XML_REGEXP_CHARVAL, start, end, NULL);
    }
    return;
}
Commit message: FileSpec: Move the fileSpec.dictLookup call inside fileSpec.isDict if

Fixes #704
CVE: CVE-2018-20650
CWE: CWE-20
Vulnerability description: A reachable Object::dictLookup assertion in Poppler 0.72.0 allows attackers to cause a denial of service due to the lack of a check for the dict data type, as demonstrated by use of the FileSpec class (in FileSpec.cc) in pdfdetach.

Project: poppler
File: FileSpec.cc

FileSpec::FileSpec(const Object *fileSpecA)
{
  ok = true;
  fileName = nullptr;
  platformFileName = nullptr;
  embFile = nullptr;
  desc = nullptr;
  fileSpec = fileSpecA->copy();

  Object obj1 = getFileSpecName(fileSpecA);
  if (!obj1.isString()) {
    ok = false;
    error(errSyntaxError, -1, "Invalid FileSpec");
    return;
  }

  fileName = obj1.getString()->copy();

  if (fileSpec.isDict()) {
    obj1 = fileSpec.dictLookup("EF");
    if (obj1.isDict()) {
      fileStream = obj1.dictLookupNF("F");
      if (!fileStream.isRef()) {
        ok = false;
        fileStream.setToNull();
        error(errSyntaxError, -1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
        return;
      }
    }
  }

  obj1 = fileSpec.dictLookup("Desc");
  if (obj1.isString())
    desc = obj1.getString()->copy();
}
Commit message: Fix uudecode buffer overflow.

mutt_decode_uuencoded() used each line's initial "length character"
without any validation.  It would happily read past the end of the
input line, and with a suitable value even past the length of the
input buffer.

As I noted in ticket 404, there are several other changes that could
be added to make the parser more robust.  However, to avoid
accidentally introducing another bug or regression, I'm restricting
this patch to simply addressing the overflow.

Thanks to Tavis Ormandy for reporting the issue, along with a sample
message demonstrating the problem.
CVE: CVE-2022-1328
CWE: CWE-120
Vulnerability description: Buffer Overflow in uudecoder in Mutt affecting all versions starting from 0.94.13 before 2.2.3 allows read past end of input line

Project: mutt
File: handler.c

static void mutt_decode_uuencoded (STATE *s, LOFF_T len, int istext, iconv_t cd)
{
  char tmps[SHORT_STRING];
  char linelen, c, l, out;
  char *pt;
  char bufi[BUFI_SIZE];
  size_t k = 0;

  if (istext)
    state_set_prefix(s);

  while (len > 0)
  {
    if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL)
      return;
    len -= mutt_strlen(tmps);
    if ((!mutt_strncmp (tmps, "begin", 5)) && ISSPACE (tmps[5]))
      break;
  }
  while (len > 0)
  {
    if ((fgets(tmps, sizeof(tmps), s->fpin)) == NULL)
      return;
    len -= mutt_strlen(tmps);
    if (!mutt_strncmp (tmps, "end", 3))
      break;
    pt = tmps;
    linelen = decode_byte (*pt);
    pt++;
    for (c = 0; c < linelen;)
    {
      for (l = 2; l <= 6; l += 2)
      {
	out = decode_byte (*pt) << l;
	pt++;
	out |= (decode_byte (*pt) >> (6 - l));
	bufi[k++] = out;
	c++;
	if (c == linelen)
	  break;
      }
      mutt_convert_to_state (cd, bufi, &k, s);
      pt++;
    }
  }

  mutt_convert_to_state (cd, bufi, &k, s);
  mutt_convert_to_state (cd, 0, 0, s);

  state_reset_prefix(s);
}
Commit message: handshake: set a maximum number of warning messages that can be received per handshake

That is to avoid DoS due to the assymetry of cost of sending an alert vs the cost
of processing.
CVE: CVE-2016-8610
CWE: CWE-400
Vulnerability description: A denial of service flaw was found in OpenSSL 0.9.8, 1.0.1, 1.0.2 through 1.0.2h, and 1.1.0 in the way the TLS/SSL protocol defined processing of ALERT packets during a connection handshake. A remote attacker could use this flaw to make a TLS/SSL server consume an excessive amount of CPU and fail to accept connections from other clients.

Project: gnutls
File: state.c

static void _gnutls_handshake_internal_state_init(gnutls_session_t session)
{
	/* by default no selected certificate */
	session->internals.adv_version_major = 0;
	session->internals.adv_version_minor = 0;
	session->internals.direction = 0;

	/* use out of band data for the last
	 * handshake messages received.
	 */
	session->internals.last_handshake_in = -1;
	session->internals.last_handshake_out = -1;

	session->internals.resumable = RESUME_TRUE;

	session->internals.handshake_large_loops = 0;
	session->internals.dtls.hsk_read_seq = 0;
	session->internals.dtls.hsk_write_seq = 0;
}
Commit message: Ensure UID in fetch_uidl.
CVE: CVE-2018-14356
CWE: CWE-824
Vulnerability description: An issue was discovered in Mutt before 1.10.1 and NeoMutt before 2018-07-16. pop.c mishandles a zero-length UID.

Project: mutt
File: pop.c

static int fetch_uidl (char *line, void *data)
{
  int i, index;
  CONTEXT *ctx = (CONTEXT *)data;
  POP_DATA *pop_data = (POP_DATA *)ctx->data;
  char *endp;

  errno = 0;
  index = strtol(line, &endp, 10);
  if (errno)
      return -1;
  while (*endp == ' ')
      endp++;
  memmove(line, endp, strlen(endp) + 1);

  for (i = 0; i < ctx->msgcount; i++)
    if (!mutt_strcmp (line, ctx->hdrs[i]->data))
      break;

  if (i == ctx->msgcount)
  {
    dprint (1, (debugfile, "pop_fetch_headers: new header %d %s\n", index, line));

    if (i >= ctx->hdrmax)
      mx_alloc_memory(ctx);

    ctx->msgcount++;
    ctx->hdrs[i] = mutt_new_header ();
    ctx->hdrs[i]->data = safe_strdup (line);
  }
  else if (ctx->hdrs[i]->index != index - 1)
    pop_data->clear_cache = 1;

  ctx->hdrs[i]->refno = index;
  ctx->hdrs[i]->index = index - 1;

  return 0;
}
Commit message: Avoid some code duplication

Apply some adjustments to recent patches based off of review by Nils
Goroll at UPLEX (@nigoroll)
CVE: CVE-2019-15892
CWE: CWE-617
Vulnerability description: An issue was discovered in Varnish Cache before 6.0.4 LTS, and 6.1.x and 6.2.x before 6.2.1. An HTTP/1 parsing failure allows a remote attacker to trigger an assert by sending crafted HTTP/1 requests. The assert will cause an automatic restart with a clean cache, which makes it a Denial of Service attack.

Project: varnish-cache
File: cache_http1_proto.c

http1_dissect_hdrs(struct http *hp, char *p, struct http_conn *htc,
    unsigned maxhdr)
{
	char *q, *r, *s;
	int i;

	assert(p > htc->rxbuf_b);
	assert(p <= htc->rxbuf_e);
	hp->nhd = HTTP_HDR_FIRST;
	r = NULL;		/* For FlexeLint */
	for (; p < htc->rxbuf_e; p = r) {

		/* Find end of next header */
		q = r = p;
		if (vct_iscrlf(p, htc->rxbuf_e))
			break;
		while (r < htc->rxbuf_e) {
			if (!vct_isctl(*r) || vct_issp(*r)) {
				r++;
				continue;
			}
			if (!vct_iscrlf(r, htc->rxbuf_e)) {
				VSLb(hp->vsl, SLT_BogoHeader,
				    "Header has ctrl char 0x%02x", *r);
				return (400);
			}
			q = r;
			assert(r < htc->rxbuf_e);
			r = vct_skipcrlf(r, htc->rxbuf_e);
			if (r >= htc->rxbuf_e)
				break;
			if (vct_iscrlf(r, htc->rxbuf_e))
				break;
			/* If line does not continue: got it. */
			if (!vct_issp(*r))
				break;

			/* Clear line continuation LWS to spaces */
			while (q < r)
				*q++ = ' ';
			while (q < htc->rxbuf_e && vct_issp(*q))
				*q++ = ' ';
		}

		/* Empty header = end of headers */
		if (p == q)
			break;

		if (q - p > maxhdr) {
			VSLb(hp->vsl, SLT_BogoHeader, "Header too long: %.*s",
			    (int)(q - p > 20 ? 20 : q - p), p);
			return (400);
		}

		if (vct_islws(*p)) {
			VSLb(hp->vsl, SLT_BogoHeader,
			    "1st header has white space: %.*s",
			    (int)(q - p > 20 ? 20 : q - p), p);
			return (400);
		}

		if (*p == ':') {
			VSLb(hp->vsl, SLT_BogoHeader,
			    "Missing header name: %.*s",
			    (int)(q - p > 20 ? 20 : q - p), p);
			return (400);
		}

		while (q > p && vct_issp(q[-1]))
			q--;
		*q = '\0';

		for (s = p; *s != ':' && s < q; s++) {
			if (!vct_istchar(*s)) {
				VSLb(hp->vsl, SLT_BogoHeader,
				    "Illegal char 0x%02x in header name", *s);
				return (400);
			}
		}
		if (*s != ':') {
			VSLb(hp->vsl, SLT_BogoHeader, "Header without ':' %.*s",
			    (int)(q - p > 20 ? 20 : q - p), p);
			return (400);
		}

		if (hp->nhd < hp->shd) {
			hp->hdf[hp->nhd] = 0;
			hp->hd[hp->nhd].b = p;
			hp->hd[hp->nhd].e = q;
			hp->nhd++;
		} else {
			VSLb(hp->vsl, SLT_BogoHeader, "Too many headers: %.*s",
			    (int)(q - p > 20 ? 20 : q - p), p);
			return (400);
		}
	}
	i = vct_iscrlf(p, htc->rxbuf_e);
	assert(i > 0);		/* HTTP1_Complete guarantees this */
	p += i;
	HTC_RxPipeline(htc, p);
	htc->rxbuf_e = p;
	return (0);
}
Commit message: vhost: check log mmap offset and size overflow

vhost_user_set_log_base() is a message handler that is
called to handle the VHOST_USER_SET_LOG_BASE message.
Its payload contains a 64 bit size and offset. Both are
added up and used as a size when calling mmap().

There is no integer overflow check. If an integer overflow
occurs a smaller memory map would be created than
requested. Since the returned mapping is mapped as writable
and used for logging, a memory corruption could occur.

CVE-2020-10722
Fixes: fbc4d248b198 ("vhost: fix offset while mmaping log base address")
Cc: stable@dpdk.org

Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
Reviewed-by: Xiaolong Ye <xiaolong.ye@intel.com>
Reviewed-by: Ilja Van Sprundel <ivansprundel@ioactive.com>
CVE: CVE-2020-10722
CWE: CWE-190
Vulnerability description: A vulnerability was found in DPDK versions 18.05 and above. A missing check for an integer overflow in vhost_user_set_log_base() could result in a smaller memory map than requested, possibly allowing memory corruption.

Project: dpdk
File: vhost_user.c

vhost_user_set_log_base(struct virtio_net **pdev, struct VhostUserMsg *msg,
			int main_fd __rte_unused)
{
	struct virtio_net *dev = *pdev;
	int fd = msg->fds[0];
	uint64_t size, off;
	void *addr;

	if (validate_msg_fds(msg, 1) != 0)
		return RTE_VHOST_MSG_RESULT_ERR;

	if (fd < 0) {
		VHOST_LOG_CONFIG(ERR, "invalid log fd: %d\n", fd);
		return RTE_VHOST_MSG_RESULT_ERR;
	}

	if (msg->size != sizeof(VhostUserLog)) {
		VHOST_LOG_CONFIG(ERR,
			"invalid log base msg size: %"PRId32" != %d\n",
			msg->size, (int)sizeof(VhostUserLog));
		return RTE_VHOST_MSG_RESULT_ERR;
	}

	size = msg->payload.log.mmap_size;
	off  = msg->payload.log.mmap_offset;

	/* Don't allow mmap_offset to point outside the mmap region */
	if (off > size) {
		VHOST_LOG_CONFIG(ERR,
			"log offset %#"PRIx64" exceeds log size %#"PRIx64"\n",
			off, size);
		return RTE_VHOST_MSG_RESULT_ERR;
	}

	VHOST_LOG_CONFIG(INFO,
		"log mmap size: %"PRId64", offset: %"PRId64"\n",
		size, off);

	/*
	 * mmap from 0 to workaround a hugepage mmap bug: mmap will
	 * fail when offset is not page size aligned.
	 */
	addr = mmap(0, size + off, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	close(fd);
	if (addr == MAP_FAILED) {
		VHOST_LOG_CONFIG(ERR, "mmap log base failed!\n");
		return RTE_VHOST_MSG_RESULT_ERR;
	}

	/*
	 * Free previously mapped log memory on occasionally
	 * multiple VHOST_USER_SET_LOG_BASE.
	 */
	if (dev->log_addr) {
		munmap((void *)(uintptr_t)dev->log_addr, dev->log_size);
	}
	dev->log_addr = (uint64_t)(uintptr_t)addr;
	dev->log_base = dev->log_addr + off;
	dev->log_size = size;

	/*
	 * The spec is not clear about it (yet), but QEMU doesn't expect
	 * any payload in the reply.
	 */
	msg->size = 0;
	msg->fd_num = 0;

	return RTE_VHOST_MSG_RESULT_REPLY;
}
Commit message: Fix bug #78222 (heap-buffer-overflow on exif_scan_thumbnail)

(cherry picked from commit dea2989ab8ba87a6180af497b2efaf0527e985c5)
CVE: CVE-2019-11041
CWE: CWE-125
Vulnerability description: When PHP EXIF extension is parsing EXIF information from an image, e.g. via exif_read_data() function, in PHP versions 7.1.x below 7.1.31, 7.2.x below 7.2.21 and 7.3.x below 7.3.8 it is possible to supply it with data what will cause it to read past the allocated buffer. This may lead to information disclosure or crash.

Project: php-src
File: exif.c

static int exif_scan_thumbnail(image_info_type *ImageInfo)
{
	uchar           c, *data = (uchar*)ImageInfo->Thumbnail.data;
	int             n, marker;
	size_t          length=2, pos=0;
	jpeg_sof_info   sof_info;

	if (!data) {
		return FALSE; /* nothing to do here */
	}
	if (memcmp(data, "\xFF\xD8\xFF", 3)) {
		if (!ImageInfo->Thumbnail.width && !ImageInfo->Thumbnail.height) {
			exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Thumbnail is not a JPEG image");
		}
		return FALSE;
	}
	for (;;) {
		pos += length;
		if (pos>=ImageInfo->Thumbnail.size)
			return FALSE;
		c = data[pos++];
		if (pos>=ImageInfo->Thumbnail.size)
			return FALSE;
		if (c != 0xFF) {
			return FALSE;
		}
		n = 8;
		while ((c = data[pos++]) == 0xFF && n--) {
			if (pos+3>=ImageInfo->Thumbnail.size)
				return FALSE;
			/* +3 = pos++ of next check when reaching marker + 2 bytes for length */
		}
		if (c == 0xFF)
			return FALSE;
		marker = c;
		if (pos>=ImageInfo->Thumbnail.size)
			return FALSE;
		length = php_jpg_get16(data+pos);
		if (length > ImageInfo->Thumbnail.size || pos >= ImageInfo->Thumbnail.size - length) {
			return FALSE;
		}
#ifdef EXIF_DEBUG
		exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Thumbnail: process section(x%02X=%s) @ x%04X + x%04X", marker, exif_get_markername(marker), pos, length);
#endif
		switch (marker) {
			case M_SOF0:
			case M_SOF1:
			case M_SOF2:
			case M_SOF3:
			case M_SOF5:
			case M_SOF6:
			case M_SOF7:
			case M_SOF9:
			case M_SOF10:
			case M_SOF11:
			case M_SOF13:
			case M_SOF14:
			case M_SOF15:
				/* handle SOFn block */
				if (length < 8 || ImageInfo->Thumbnail.size - 8 < pos) {
					/* exif_process_SOFn needs 8 bytes */
					return FALSE;
				}
				exif_process_SOFn(data+pos, marker, &sof_info);
				ImageInfo->Thumbnail.height   = sof_info.height;
				ImageInfo->Thumbnail.width    = sof_info.width;
#ifdef EXIF_DEBUG
				exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Thumbnail: size: %d * %d", sof_info.width, sof_info.height);
#endif
				return TRUE;

			case M_SOS:
			case M_EOI:
				exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Could not compute size of thumbnail");
				return FALSE;
				break;

			default:
				/* just skip */
				break;
		}
	}

	exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Could not compute size of thumbnail");
	return FALSE;
}