db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: sr: pass down correctly sized SCSI sense buffer

We're casting the CDROM layer request_sense to the SCSI sense
buffer, but the former is 64 bytes and the latter is 96 bytes.
As we generally allocate these on the stack, we end up blowing
up the stack.

Fix this by wrapping the scsi_execute() call with a properly
sized sense buffer, and copying back the bits for the CDROM
layer.

Cc: stable@vger.kernel.org
Reported-by: Piotr Gabriel Kosinski <pg.kosinski@gmail.com>
Reported-by: Daniel Shapira <daniel@twistlock.com>
Tested-by: Kees Cook <keescook@chromium.org>
Fixes: 82ed4db499b8 ("block: split scsi_request out of struct request")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
CVE: CVE-2018-11506
CWE: CWE-119
Vulnerability description: The sr_do_ioctl function in drivers/scsi/sr_ioctl.c in the Linux kernel through 4.16.12 allows local users to cause a denial of service (stack-based buffer overflow) or possibly have unspecified other impact because sense buffers have different sizes at the CDROM layer and the SCSI layer, as demonstrated by a CDROMREADMODE2 ioctl call.

Project: linux
File: sr_ioctl.c

int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc)
{
 	struct scsi_device *SDev;
 	struct scsi_sense_hdr sshdr;
 	int result, err = 0, retries = 0;
	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE], *senseptr = NULL;
 
 	SDev = cd->device;
 
	if (cgc->sense)
		senseptr = sense_buffer;

       retry:
 	if (!scsi_block_when_processing_errors(SDev)) {
 		err = -ENODEV;
 		goto out;
 	}
 
 	result = scsi_execute(SDev, cgc->cmd, cgc->data_direction,
			      cgc->buffer, cgc->buflen, senseptr, &sshdr,
 			      cgc->timeout, IOCTL_RETRIES, 0, 0, NULL);
 
	if (cgc->sense)
		memcpy(cgc->sense, sense_buffer, sizeof(*cgc->sense));

 	/* Minimal error checking.  Ignore cases we know about, and report the rest. */
 	if (driver_byte(result) != 0) {
 		switch (sshdr.sense_key) {
		case UNIT_ATTENTION:
			SDev->changed = 1;
			if (!cgc->quiet)
				sr_printk(KERN_INFO, cd,
					  "disc change detected.\n");
			if (retries++ < 10)
				goto retry;
			err = -ENOMEDIUM;
			break;
		case NOT_READY:	/* This happens if there is no disc in drive */
			if (sshdr.asc == 0x04 &&
			    sshdr.ascq == 0x01) {
				/* sense: Logical unit is in process of becoming ready */
				if (!cgc->quiet)
					sr_printk(KERN_INFO, cd,
						  "CDROM not ready yet.\n");
				if (retries++ < 10) {
					/* sleep 2 sec and try again */
					ssleep(2);
					goto retry;
				} else {
					/* 20 secs are enough? */
					err = -ENOMEDIUM;
					break;
				}
			}
			if (!cgc->quiet)
				sr_printk(KERN_INFO, cd,
					  "CDROM not ready.  Make sure there "
					  "is a disc in the drive.\n");
			err = -ENOMEDIUM;
			break;
		case ILLEGAL_REQUEST:
			err = -EIO;
			if (sshdr.asc == 0x20 &&
			    sshdr.ascq == 0x00)
				/* sense: Invalid command operation code */
				err = -EDRIVE_CANT_DO_THIS;
			break;
		default:
			err = -EIO;
		}
	}

	/* Wake up a process waiting for device */
      out:
	cgc->stat = err;
	return err;
}
Commit message: Fixed CVE-2018-8788

Thanks to Eyal Itkin from Check Point Software Technologies.
CVE: CVE-2018-8788
CWE: CWE-787
Vulnerability description: FreeRDP prior to version 2.0.0-rc4 contains an Out-Of-Bounds Write of up to 4 bytes in function nsc_rle_decode() that results in a memory corruption and possibly even a remote code execution.

Project: FreeRDP

void nsc_encode(NSC_CONTEXT* context, const BYTE* bmpdata, UINT32 rowstride)
BOOL nsc_encode(NSC_CONTEXT* context, const BYTE* bmpdata, UINT32 rowstride)
 {
	if (!context || !bmpdata || (rowstride == 0))
		return FALSE;

	if (!nsc_encode_argb_to_aycocg(context, bmpdata, rowstride))
		return FALSE;
 
 	if (context->ChromaSubsamplingLevel)
 	{
		if (!nsc_encode_subsampling(context))
			return FALSE;
 	}

	return TRUE;
 }

Project: FreeRDP

static UINT32 nsc_rle_encode(BYTE* in, BYTE* out, UINT32 originalSize)
static UINT32 nsc_rle_encode(const BYTE* in, BYTE* out, UINT32 originalSize)
 {
 	UINT32 left;
 	UINT32 runlength = 1;
	UINT32 planeSize = 0;
	left = originalSize;

	/**
	 * We quit the loop if the running compressed size is larger than the original.
	 * In such cases data will be sent uncompressed.
	 */
	while (left > 4 && planeSize < originalSize - 4)
	{
		if (left > 5 && *in == *(in + 1))
		{
			runlength++;
		}
		else if (runlength == 1)
		{
			*out++ = *in;
			planeSize++;
		}
		else if (runlength < 256)
		{
			*out++ = *in;
			*out++ = *in;
			*out++ = runlength - 2;
			runlength = 1;
			planeSize += 3;
		}
		else
		{
			*out++ = *in;
			*out++ = *in;
			*out++ = 0xFF;
			*out++ = (runlength & 0x000000FF);
			*out++ = (runlength & 0x0000FF00) >> 8;
			*out++ = (runlength & 0x00FF0000) >> 16;
			*out++ = (runlength & 0xFF000000) >> 24;
			runlength = 1;
			planeSize += 7;
		}

		in++;
		left--;
	}

	if (planeSize < originalSize - 4)
		CopyMemory(out, in, 4);

	planeSize += 4;
	return planeSize;
}
Commit message: Security fixes: expect final changes for release 1.75.3.
* Fixed a debian security issue with fscanf() reading a string with
  possible buffer overflow.
* There were also a few similar situations with sscanf().
CVE: CVE-2018-7186
CWE: CWE-119
Vulnerability description: Leptonica before 1.75.3 does not limit the number of characters in a %s format argument to fscanf or sscanf, which allows remote attackers to cause a denial of service (stack-based buffer overflow) or possibly have unspecified other impact via a long string, as demonstrated by the gplotRead and ptaReadStream functions.

Project: leptonica
File: gplot.c

gplotCreate(const char  *rootname,
            l_int32      outformat,
            const char  *title,
            const char  *xlabel,
             const char  *ylabel)
 {
 char    *newroot;
char     buf[L_BUFSIZE];
 l_int32  badchar;
 GPLOT   *gplot;
 
    PROCNAME("gplotCreate");

    if (!rootname)
        return (GPLOT *)ERROR_PTR("rootname not defined", procName, NULL);
    if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
        outformat != GPLOT_EPS && outformat != GPLOT_LATEX)
        return (GPLOT *)ERROR_PTR("outformat invalid", procName, NULL);
    stringCheckForChars(rootname, "`;&|><\"?*", &badchar);
    if (badchar)  /* danger of command injection */
        return (GPLOT *)ERROR_PTR("invalid rootname", procName, NULL);

    if ((gplot = (GPLOT *)LEPT_CALLOC(1, sizeof(GPLOT))) == NULL)
        return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL);
    gplot->cmddata = sarrayCreate(0);
    gplot->datanames = sarrayCreate(0);
    gplot->plotdata = sarrayCreate(0);
    gplot->plottitles = sarrayCreate(0);
    gplot->plotstyles = numaCreate(0);

        /* Save title, labels, rootname, outformat, cmdname, outname */
     newroot = genPathname(rootname, NULL);
     gplot->rootname = newroot;
     gplot->outformat = outformat;
    snprintf(buf, L_BUFSIZE, "%s.cmd", rootname);
     gplot->cmdname = stringNew(buf);
     if (outformat == GPLOT_PNG)
        snprintf(buf, L_BUFSIZE, "%s.png", newroot);
     else if (outformat == GPLOT_PS)
        snprintf(buf, L_BUFSIZE, "%s.ps", newroot);
     else if (outformat == GPLOT_EPS)
        snprintf(buf, L_BUFSIZE, "%s.eps", newroot);
     else if (outformat == GPLOT_LATEX)
        snprintf(buf, L_BUFSIZE, "%s.tex", newroot);
     gplot->outname = stringNew(buf);
     if (title) gplot->title = stringNew(title);
     if (xlabel) gplot->xlabel = stringNew(xlabel);
    if (ylabel) gplot->ylabel = stringNew(ylabel);

    return gplot;
}
Commit message: stream: fix false negative on bad RST

If a bad RST was received the stream inspection would not happen
for that packet, but it would still move the 'raw progress' tracker
forward. Following good packets would then fail to detect anything
before the 'raw progress' position.

Bug #2770

Reported-by: Alexey Vishnyakov
CVE: CVE-2019-1010279
CWE: CWE-347
Vulnerability description: Open Information Security Foundation Suricata prior to version 4.1.3 is affected by: Denial of Service - TCP/HTTP detection bypass. The impact is: An attacker can evade a signature detection with a specialy formed sequence of network packets. The component is: detect.c (https://github.com/OISF/suricata/pull/3625/commits/d8634daf74c882356659addb65fb142b738a186b). The attack vector is: An attacker can trigger the vulnerability by a specifically crafted network TCP session. The fixed version is: 4.1.3.

Project: suricata
File: detect.c

static void DetectRunCleanup(DetectEngineThreadCtx *det_ctx,
        Packet *p, Flow * const pflow)
{
    PACKET_PROFILING_DETECT_START(p, PROF_DETECT_CLEANUP);
    /* cleanup pkt specific part of the patternmatcher */
    PacketPatternCleanup(det_ctx);
 
     if (pflow != NULL) {
         /* update inspected tracker for raw reassembly */
        if (p->proto == IPPROTO_TCP && pflow->protoctx != NULL &&
            (p->flags & PKT_STREAM_EST))
        {
             StreamReassembleRawUpdateProgress(pflow->protoctx, p,
                     det_ctx->raw_stream_progress);
 
            DetectEngineCleanHCBDBuffers(det_ctx);
        }
    }
    PACKET_PROFILING_DETECT_END(p, PROF_DETECT_CLEANUP);
    SCReturn;
}
Commit message: fetch map after DGifGetImageDesc()

Earlier refactoring broke GIF map fetch.
CVE: CVE-2019-17534
CWE: CWE-416
Vulnerability description: vips_foreign_load_gif_scan_image in foreign/gifload.c in libvips before 8.8.2 tries to access a color map before a DGifGetImageDesc call, leading to a use-after-free.

Project: libvips
File: gifload.c

vips_foreign_load_gif_scan_image( VipsForeignLoadGif *gif ) 
 {
 	VipsObjectClass *class = VIPS_OBJECT_GET_CLASS( gif );
 	GifFileType *file = gif->file;
 
	ColorMapObject *map;
 	GifByteType *extension;
 
 	if( DGifGetImageDesc( gif->file ) == GIF_ERROR ) {
		vips_foreign_load_gif_error( gif ); 
		return( -1 );
	}

	/* Check that the frame looks sane. Perhaps giflib checks
	 * this for us.
	 */
	if( file->Image.Left < 0 ||
		file->Image.Width < 1 ||
		file->Image.Width > 10000 ||
		file->Image.Left + file->Image.Width > file->SWidth ||
		file->Image.Top < 0 ||
		file->Image.Height < 1 ||
		file->Image.Height > 10000 ||
		file->Image.Top + file->Image.Height > file->SHeight ) {
		vips_error( class->nickname, "%s", _( "bad frame size" ) ); 
		return( -1 ); 
	}
 
 	/* Test for a non-greyscale colourmap for this frame.
 	 */
	map = file->Image.ColorMap ? file->Image.ColorMap : file->SColorMap;
 	if( !gif->has_colour &&
 		map ) {
 		int i;

		for( i = 0; i < map->ColorCount; i++ ) 
			if( map->Colors[i].Red != map->Colors[i].Green ||
				map->Colors[i].Green != map->Colors[i].Blue ) {
				gif->has_colour = TRUE;
				break;
			}
	}

	/* Step over compressed image data.
	 */
	do {
		if( vips_foreign_load_gif_code_next( gif, &extension ) ) 
			return( -1 );
	} while( extension != NULL );

	return( 0 );
}
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1553
CVE: CVE-2019-15139
CWE: CWE-125
Vulnerability description: The XWD image (X Window System window dumping file) parsing component in ImageMagick 7.0.8-41 Q16 allows attackers to cause a denial-of-service (application crash resulting from an out-of-bounds Read) in ReadXWDImage in coders/xwd.c by crafting a corrupted XWD image file, a different vulnerability than CVE-2019-11472.

Project: ImageMagick
File: xwd.c

ModuleExport size_t RegisterXWDImage(void)
{
  MagickInfo
    *entry;

  entry=AcquireMagickInfo("XWD","XWD","X Windows system window dump (color)");
#if defined(MAGICKCORE_X11_DELEGATE)
  entry->decoder=(DecodeImageHandler *) ReadXWDImage;
   entry->encoder=(EncodeImageHandler *) WriteXWDImage;
 #endif
   entry->magick=(IsImageFormatHandler *) IsXWD;
  entry->flags|=CoderDecoderSeekableStreamFlag;
   entry->flags^=CoderAdjoinFlag;
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
}
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1615
CVE: CVE-2019-13307
CWE: CWE-119
Vulnerability description: ImageMagick 7.0.8-50 Q16 has a heap-based buffer overflow at MagickCore/statistic.c in EvaluateImages because of mishandling rows.

Project: ImageMagick6

static MagickPixelPacket **AcquirePixelThreadSet(const Image *images)
{
  const Image
    *next;

  MagickPixelPacket
    **pixels;

  register ssize_t
    i,
    j;
 
   size_t
     columns,
    rows;
 
  rows=MagickMax(GetImageListLength(images),
    (size_t) GetMagickResourceLimit(ThreadResource));
  pixels=(MagickPixelPacket **) AcquireQuantumMemory(rows,sizeof(*pixels));
   if (pixels == (MagickPixelPacket **) NULL)
     return((MagickPixelPacket **) NULL);
   columns=images->columns;
   for (next=images; next != (Image *) NULL; next=next->next)
     columns=MagickMax(next->columns,columns);
  for (i=0; i < (ssize_t) rows; i++)
   {
     pixels[i]=(MagickPixelPacket *) AcquireQuantumMemory(columns,
       sizeof(**pixels));
    if (pixels[i] == (MagickPixelPacket *) NULL)
      return(DestroyPixelThreadSet(pixels));
    for (j=0; j < (ssize_t) columns; j++)
      GetMagickPixelPacket(images,&pixels[i][j]);
  }
  return(pixels);
}
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1602
CVE: CVE-2019-13136
CWE: CWE-190
Vulnerability description: ImageMagick before 7.0.8-50 has an integer overflow vulnerability in the function TIFFSeekCustomStream in coders/tiff.c.

Project: ImageMagick
File: tiff.c

static MagickOffsetType TIFFSeekCustomStream(const MagickOffsetType offset,
  const int whence,void *user_data)
{
  PhotoshopProfile
    *profile;

  profile=(PhotoshopProfile *) user_data;
  switch (whence)
  {
    case SEEK_SET:
    default:
    {
      if (offset < 0)
        return(-1);
      profile->offset=offset;
      break;
     }
     case SEEK_CUR:
     {
      if (((offset > 0) && (profile->offset > (SSIZE_MAX-offset))) ||
          ((offset < 0) && (profile->offset < (-SSIZE_MAX-offset))))
        {
          errno=EOVERFLOW;
          return(-1);
        }
       if ((profile->offset+offset) < 0)
         return(-1);
       profile->offset+=offset;
      break;
    }
    case SEEK_END:
    {
      if (((MagickOffsetType) profile->length+offset) < 0)
        return(-1);
      profile->offset=profile->length+offset;
      break;
    }
  }

  return(profile->offset);
}
Commit message: nfc: Ensure presence of required attributes in the deactivate_target handler

Check that the NFC_ATTR_TARGET_INDEX attributes (in addition to
NFC_ATTR_DEVICE_INDEX) are provided by the netlink client prior to
accessing them. This prevents potential unhandled NULL pointer dereference
exceptions which can be triggered by malicious user-mode programs,
if they omit one or both of these attributes.

Signed-off-by: Young Xiao <92siuyang@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
CVE: CVE-2019-12984
CWE: CWE-476
Vulnerability description: A NULL pointer dereference vulnerability in the function nfc_genl_deactivate_target() in net/nfc/netlink.c in the Linux kernel before 5.1.13 can be triggered by a malicious user-mode program that omits certain NFC attributes, leading to denial of service.

Project: linux
File: netlink.c

static int nfc_genl_deactivate_target(struct sk_buff *skb,
				      struct genl_info *info)
{
	struct nfc_dev *dev;
 	u32 device_idx, target_idx;
 	int rc;
 
	if (!info->attrs[NFC_ATTR_DEVICE_INDEX] ||
	    !info->attrs[NFC_ATTR_TARGET_INDEX])
 		return -EINVAL;
 
 	device_idx = nla_get_u32(info->attrs[NFC_ATTR_DEVICE_INDEX]);

	dev = nfc_get_device(device_idx);
	if (!dev)
		return -ENODEV;

	target_idx = nla_get_u32(info->attrs[NFC_ATTR_TARGET_INDEX]);

	rc = nfc_deactivate_target(dev, target_idx, NFC_TARGET_MODE_SLEEP);

	nfc_put_device(dev);
	return rc;
}
Commit message: upnp_event_prepare(): check the return value of snprintf()
CVE: CVE-2019-12107
CWE: CWE-200
Vulnerability description: The upnp_event_prepare function in upnpevents.c in MiniUPnP MiniUPnPd through 2.1 allows a remote attacker to leak information from the heap due to improper validation of an snprintf return value.

Project: miniupnp
File: upnpevents.c

static void upnp_event_prepare(struct upnp_event_notify * obj)
{
	static const char notifymsg[] =
		"NOTIFY %s HTTP/1.1\r\n"
		"Host: %s%s\r\n"
#if (UPNP_VERSION_MAJOR == 1) && (UPNP_VERSION_MINOR == 0)
		"Content-Type: text/xml\r\n"	/* UDA v1.0 */
#else
		"Content-Type: text/xml; charset=\"utf-8\"\r\n"	/* UDA v1.1 or later */
#endif
		"Content-Length: %d\r\n"
		"NT: upnp:event\r\n"
		"NTS: upnp:propchange\r\n"
		"SID: %s\r\n"
		"SEQ: %u\r\n"
		"Connection: close\r\n"
		"Cache-Control: no-cache\r\n"
		"\r\n"
		"%.*s\r\n";
	char * xml;
	int l;
	if(obj->sub == NULL) {
		obj->state = EError;
		return;
	}
	switch(obj->sub->service) {
	case EWanCFG:
		xml = getVarsWANCfg(&l);
		break;
	case EWanIPC:
		xml = getVarsWANIPCn(&l);
		break;
#ifdef ENABLE_L3F_SERVICE
	case EL3F:
		xml = getVarsL3F(&l);
		break;
#endif
#ifdef ENABLE_6FC_SERVICE
	case E6FC:
		xml = getVars6FC(&l);
		break;
#endif
#ifdef ENABLE_DP_SERVICE
	case EDP:
		xml = getVarsDP(&l);
		break;
#endif
	default:
		xml = NULL;
 		l = 0;
 	}
 	obj->buffersize = 1024;
	for (;;) {
		obj->buffer = malloc(obj->buffersize);
		if(!obj->buffer) {
			syslog(LOG_ERR, "%s: malloc returned NULL", "upnp_event_prepare");
			if(xml) {
				free(xml);
			}
			obj->state = EError;
			return;
 		}
		obj->tosend = snprintf(obj->buffer, obj->buffersize, notifymsg,
		                       obj->path, obj->addrstr, obj->portstr, l+2,
		                       obj->sub->uuid, obj->sub->seq,
		                       l, xml);
		if (obj->tosend < 0) {
			syslog(LOG_ERR, "%s: snprintf() failed", "upnp_event_prepare");
			if(xml) {
				free(xml);
			}
			obj->state = EError;
			return;
		} else if (obj->tosend < obj->buffersize) {
			break; /* the buffer was large enough */
		}
		/* Try again with a buffer big enough */
		free(obj->buffer);
		obj->buffersize = obj->tosend + 1;	/* reserve space for the final 0 */
 	}
 	if(xml) {
 		free(xml);
 		xml = NULL;
	}
	obj->state = ESending;
}
Commit message: [core] fix abort in http-parseopts (fixes #2945)

fix abort in server.http-parseopts with url-path-2f-decode enabled

(thx stze)

x-ref:
  "Security - SIGABRT during GET request handling with url-path-2f-decode enabled"
  https://redmine.lighttpd.net/issues/2945
CVE: CVE-2019-11072
CWE: CWE-190
Vulnerability description: lighttpd before 1.4.54 has a signed integer overflow, which might allow remote attackers to cause a denial of service (application crash) or possibly have unspecified other impact via a malicious HTTP GET request, as demonstrated by mishandling of /%2F? in burl_normalize_2F_to_slash_fix in burl.c. NOTE: The developer states "The feature which can be abused to cause the crash is a new feature in lighttpd 1.4.50, and is not enabled by default. It must be explicitly configured in the config file (e.g. lighttpd.conf). Certain input will trigger an abort() in lighttpd when that feature is enabled. lighttpd detects the underflow or realloc() will fail (in both 32-bit and 64-bit executables), also detected in lighttpd. Either triggers an explicit abort() by lighttpd. This is not exploitable beyond triggering the explicit abort() with subsequent application exit.

Project: lighttpd1.4
File: burl.c

static int burl_normalize_2F_to_slash_fix (buffer *b, int qs, int i)
{
    char * const s = b->ptr;
    const int blen = (int)buffer_string_length(b);
    const int used = qs < 0 ? blen : qs;
    int j = i;
    for (; i < used; ++i, ++j) {
        s[j] = s[i];
        if (s[i] == '%' && s[i+1] == '2' && s[i+2] == 'F') {
            s[j] = '/';
            i+=2;
         }
     }
     if (qs >= 0) {
        const int qslen = blen - qs;
        memmove(s+j, s+qs, (size_t)qslen);
        qs = j;
        j += qslen;
     }
     buffer_string_set_length(b, j);
     return qs;
}
Commit message: kvm: fix kvm_ioctl_create_device() reference counting (CVE-2019-6974)

kvm_ioctl_create_device() does the following:

1. creates a device that holds a reference to the VM object (with a borrowed
   reference, the VM's refcount has not been bumped yet)
2. initializes the device
3. transfers the reference to the device to the caller's file descriptor table
4. calls kvm_get_kvm() to turn the borrowed reference to the VM into a real
   reference

The ownership transfer in step 3 must not happen before the reference to the VM
becomes a proper, non-borrowed reference, which only happens in step 4.
After step 3, an attacker can close the file descriptor and drop the borrowed
reference, which can cause the refcount of the kvm object to drop to zero.

This means that we need to grab a reference for the device before
anon_inode_getfd(), otherwise the VM can disappear from under us.

Fixes: 852b6d57dc7f ("kvm: add device control API")
Cc: stable@kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
CVE: CVE-2019-6974
CWE: CWE-362
Vulnerability description: In the Linux kernel before 4.20.8, kvm_ioctl_create_device in virt/kvm/kvm_main.c mishandles reference counting because of a race condition, leading to a use-after-free.

Project: linux
File: kvm_main.c

static int kvm_ioctl_create_device(struct kvm *kvm,
				   struct kvm_create_device *cd)
{
	struct kvm_device_ops *ops = NULL;
	struct kvm_device *dev;
	bool test = cd->flags & KVM_CREATE_DEVICE_TEST;
	int ret;

	if (cd->type >= ARRAY_SIZE(kvm_device_ops_table))
		return -ENODEV;

	ops = kvm_device_ops_table[cd->type];
	if (ops == NULL)
		return -ENODEV;

	if (test)
		return 0;

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->ops = ops;
	dev->kvm = kvm;

	mutex_lock(&kvm->lock);
	ret = ops->create(dev, cd->type);
	if (ret < 0) {
		mutex_unlock(&kvm->lock);
		kfree(dev);
		return ret;
	}
	list_add(&dev->vm_node, &kvm->devices);
	mutex_unlock(&kvm->lock);

 	if (ops->init)
 		ops->init(dev);
 
	kvm_get_kvm(kvm);
 	ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
 	if (ret < 0) {
		kvm_put_kvm(kvm);
 		mutex_lock(&kvm->lock);
 		list_del(&dev->vm_node);
 		mutex_unlock(&kvm->lock);
 		ops->destroy(dev);
 		return ret;
 	}
 
 	cd->fd = ret;
 	return 0;
 }
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

print_prefix(netdissect_options *ndo, const u_char *prefix, u_int max_length)
{
    int plenbytes;
    char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx::/128")];

    if (prefix[0] >= 96 && max_length >= IPV4_MAPPED_HEADING_LEN + 1 &&
        is_ipv4_mapped_address(&prefix[1])) {
        struct in_addr addr;
        u_int plen;

        plen = prefix[0]-96;
        if (32 < plen)
            return -1;
        max_length -= 1;

        memset(&addr, 0, sizeof(addr));
        plenbytes = (plen + 7) / 8;
        if (max_length < (u_int)plenbytes + IPV4_MAPPED_HEADING_LEN)
            return -3;
        memcpy(&addr, &prefix[1 + IPV4_MAPPED_HEADING_LEN], plenbytes);
        if (plen % 8) {
		((u_char *)&addr)[plenbytes - 1] &=
			((0xff00 >> (plen % 8)) & 0xff);
	}
	snprintf(buf, sizeof(buf), "%s/%d", ipaddr_string(ndo, &addr), plen);
         plenbytes += 1 + IPV4_MAPPED_HEADING_LEN;
     } else {
         plenbytes = decode_prefix6(ndo, prefix, max_length, buf, sizeof(buf));
        if (plenbytes < 0)
            return plenbytes;
     }
 
     ND_PRINT((ndo, "%s", buf));
    return plenbytes;
}