db-d2/primevul-codebert-embeddings huggingface dataset:
Commit message: Clear err_code and err_reason at start of request handling

req->err_code and req->err_reason are set when going to synthetic
handling. From there the resp.reason HTTP field is set from
req->err_reason if set, or the generic code based on req->err_code is used
if it was NULL. This patch clears these members so that a value from the
handling of a previous request doesn't linger.

Fixes: VSV00004
CVE: CVE-2019-20637
CWE: CWE-212
Vulnerability description: An issue was discovered in Varnish Cache before 6.0.5 LTS, 6.1.x and 6.2.x before 6.2.2, and 6.3.x before 6.3.1. It does not clear a pointer between the handling of one client request and the next request within the same connection. This sometimes causes information to be disclosed from the connection workspace, such as data structures associated with previous requests within this connection or VCL-related temporary headers.

Project: varnish-cache
File: cache_req_fsm.c

cnt_recv_prep(struct req *req, const char *ci)
{
	const char *xff;

	if (req->restarts == 0) {
		/*
		 * This really should be done earlier, but we want to capture
		 * it in the VSL log.
		 */
		http_CollectHdr(req->http, H_X_Forwarded_For);
		if (http_GetHdr(req->http, H_X_Forwarded_For, &xff)) {
			http_Unset(req->http, H_X_Forwarded_For);
			http_PrintfHeader(req->http, "X-Forwarded-For: %s, %s",
			    xff, ci);
		} else {
			http_PrintfHeader(req->http, "X-Forwarded-For: %s", ci);
		}
		http_CollectHdr(req->http, H_Cache_Control);

		/* By default we use the first backend */
		req->director_hint = VCL_DefaultDirector(req->vcl);

		req->d_ttl = -1;
		req->d_grace = -1;
		req->disable_esi = 0;
		req->hash_always_miss = 0;
		req->hash_ignore_busy = 0;
		req->client_identity = NULL;
		req->storage = NULL;
	}

	req->vdc->retval = 0;
	req->is_hit = 0;
	req->is_hitmiss = 0;
	req->is_hitpass = 0;
}
Commit message: [Bug 2937] (NTPQ) nextvar() missing length check
CVE: CVE-2015-7975
CWE: CWE-119
Vulnerability description: The nextvar function in NTP before 4.2.8p6 and 4.3.x before 4.3.90 does not properly validate the length of its input, which allows an attacker to cause a denial of service (application crash).

Project: ntp
File: ntpq.c

nextvar(
	int *datalen,
	const char **datap,
	char **vname,
	char **vvalue
	)
{
	const char *cp;
	const char *np;
	const char *cpend;
	size_t srclen;
	size_t len;
	static char name[MAXVARLEN];
	static char value[MAXVALLEN];

	cp = *datap;
	cpend = cp + *datalen;

	/*
	 * Space past commas and white space
	 */
	while (cp < cpend && (*cp == ',' || isspace((int)*cp)))
		cp++;
	if (cp >= cpend)
		return 0;

	/*
	 * Copy name until we hit a ',', an '=', a '\r' or a '\n'.  Backspace
	 * over any white space and terminate it.
	 */
	srclen = strcspn(cp, ",=\r\n");
	srclen = min(srclen, (size_t)(cpend - cp));
	len = srclen;
	while (len > 0 && isspace((unsigned char)cp[len - 1]))
		len--;
	if (len > 0)
		memcpy(name, cp, len);
	name[len] = '\0';
	*vname = name;
	cp += srclen;

	/*
	 * Check if we hit the end of the buffer or a ','.  If so we are done.
	 */
	if (cp >= cpend || *cp == ',' || *cp == '\r' || *cp == '\n') {
		if (cp < cpend)
			cp++;
		*datap = cp;
		*datalen = cpend - cp;
		*vvalue = NULL;
		return 1;
	}

	/*
	 * So far, so good.  Copy out the value
	 */
	cp++;	/* past '=' */
	while (cp < cpend && (isspace((unsigned char)*cp) && *cp != '\r' && *cp != '\n'))
		cp++;
	np = cp;
	if ('"' == *np) {
		do {
			np++;
		} while (np < cpend && '"' != *np);
		if (np < cpend && '"' == *np)
			np++;
	} else {
		while (np < cpend && ',' != *np && '\r' != *np)
			np++;
	}
	len = np - cp;
	if (np > cpend || len >= sizeof(value) ||
	    (np < cpend && ',' != *np && '\r' != *np))
		return 0;
	memcpy(value, cp, len);
	/*
	 * Trim off any trailing whitespace
	 */
	while (len > 0 && isspace((unsigned char)value[len - 1]))
		len--;
	value[len] = '\0';

	/*
	 * Return this.  All done.
	 */
	if (np < cpend && ',' == *np)
		np++;
	*datap = np;
	*datalen = cpend - np;
	*vvalue = value;
	return 1;
}
Commit message: fs: Use game data path to resolve ./ in the absence of a current_dir

Fixes a file content disclosure bug (#22042) affecting functionality
relying on the get_wml_location() function and not passing a non-empty
value for the current_dir parameter.

See <https://gna.org/bugs/?22042> for details.

This is a candidate for the 1.10 and 1.12 branches.

(Backported from master, commit 314425ab0e57b32909d324f7d4bf213d62cbd3b5.)
CVE: CVE-2015-0844
CWE: CWE-200
Vulnerability description: The WML/Lua API in Battle for Wesnoth 1.7.x through 1.11.x and 1.12.x before 1.12.2 allows remote attackers to read arbitrary files via a crafted (1) campaign or (2) map file.

Project: wesnoth
File: filesystem.cpp

std::string get_wml_location(const std::string &filename, const std::string &current_dir)
{
	DBG_FS << "Looking for '" << filename << "'.\n";

	std::string result;

	if (filename.empty()) {
		LOG_FS << "  invalid filename\n";
		return result;
	}

	if (filename.find("..") != std::string::npos) {
		ERR_FS << "Illegal path '" << filename << "' (\"..\" not allowed).\n";
		return result;
	}

	bool already_found = false;

	if (filename[0] == '~')
	{
		// If the filename starts with '~', look in the user data directory.
		result = get_user_data_dir() + "/data/" + filename.substr(1);
		DBG_FS << "  trying '" << result << "'\n";

		already_found = file_exists(result) || is_directory(result);
	}
	else if (filename.size() >= 2 && filename[0] == '.' && filename[1] == '/')
	{
		// If the filename begins with a "./", look in the same directory
		// as the file currrently being preprocessed.
		result = current_dir + filename.substr(2);
	}
	else if (!game_config::path.empty())
		result = game_config::path + "/data/" + filename;

	DBG_FS << "  trying '" << result << "'\n";

	if (result.empty() ||
	    (!already_found && !file_exists(result) && !is_directory(result)))
	{
		DBG_FS << "  not found\n";
		result.clear();
	}
	else
		DBG_FS << "  found: '" << result << "'\n";

	return result;
}
Commit message: https://github.com/ImageMagick/ImageMagick/issues/1336
CVE: CVE-2018-18023
CWE: CWE-125
Vulnerability description: In ImageMagick 7.0.8-13 Q16, there is a heap-based buffer over-read in the SVGStripString function of coders/svg.c, which allows attackers to cause a denial of service via a crafted SVG image file.

Project: ImageMagick6

static void SVGStripString(const MagickBooleanType trim,char *message)
{
  register char
    *p,
    *q;

  size_t
    length;

  assert(message != (char *) NULL);
  if (*message == '\0')
    return;
  /*
    Remove comment.
  */
  q=message;
  for (p=message; *p != '\0'; p++)
  {
    if ((*p == '/') && (*(p+1) == '*'))
      {
        for ( ; *p != '\0'; p++)
          if ((*p == '*') && (*(p+1) == '/'))
            break;
        if (*p == '\0')
          break;
        p+=2;
      }
    *q++=(*p);
  }
  *q='\0';
  if (trim != MagickFalse)
    {
      /*
        Remove whitespace.
      */
      length=strlen(message);
      p=message;
      while (isspace((int) ((unsigned char) *p)) != 0)
        p++;
      if ((*p == '\'') || (*p == '"'))
        p++;
      q=message+length-1;
      while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
        q--;
      if (q > p)
        if ((*q == '\'') || (*q == '"'))
          q--;
      (void) memmove(message,p,(size_t) (q-p+1));
      message[q-p+1]='\0';
    }
  /*
    Convert newlines to a space.
  */
  for (p=message; *p != '\0'; p++)
    if (*p == '\n')
      *p=' ';
}
Commit message: v8: Interrupts must not mask stack overflow.

Backport of https://codereview.chromium.org/339883002
CVE: CVE-2014-5256
CWE: CWE-20
Vulnerability description: Node.js 0.8 before 0.8.28 and 0.10 before 0.10.30 does not consider the possibility of recursive processing that triggers V8 garbage collection in conjunction with a V8 interrupt, which allows remote attackers to cause a denial of service (memory corruption and application crash) via deep JSON objects whose parsing lets this interrupt mask an overflow of the program stack.

Project: node
File: isolate.h

  bool HasOverflowed() const {
    StackGuard* stack_guard = isolate_->stack_guard();
    // Stack has overflowed in C++ code only if stack pointer exceeds the C++
    // stack guard and the limits are not set to interrupt values.
    // TODO(214): Stack overflows are ignored if a interrupt is pending. This
    // code should probably always use the initial C++ limit.
    return (reinterpret_cast<uintptr_t>(this) < stack_guard->climit()) &&
           stack_guard->IsStackOverflow();
  }
Commit message: Redo minor cleanup in new_rbtree
CVE: CVE-2022-1444
CWE: CWE-416
Vulnerability description: heap-use-after-free in GitHub repository radareorg/radare2 prior to 5.7.0. This vulnerability is capable of inducing denial of service.

Project: radare2
File: new_rbtree.c

R_API bool r_crbtree_insert(RRBTree *tree, void *data, RRBComparator cmp, void *user) {
	r_return_val_if_fail (tree && data && cmp, false);
	bool inserted = false;

	if (tree->root == NULL) {
		tree->root = _node_new (data, NULL);
		if (tree->root == NULL) {
			return false;
		}
		inserted = true;
		goto out_exit;
	}

	RRBNode head; /* Fake tree root */
	memset (&head, 0, sizeof (RRBNode));
	RRBNode *g = NULL, *parent = &head; /* Grandparent & parent */
	RRBNode *p = NULL, *q = tree->root; /* Iterator & parent */
	int dir = 0, last = 0; /* Directions */

	_set_link (parent, q, 1);

	for (;;) {
		if (!q) {
			/* Insert a node at first null link(also set its parent link) */
			q = _node_new (data, p);
			if (!q) {
				return false;
			}
			p->link[dir] = q;
			inserted = true;
		} else if (IS_RED (q->link[0]) && IS_RED (q->link[1])) {
			/* Simple red violation: color flip */
			q->red = 1;
			q->link[0]->red = 0;
			q->link[1]->red = 0;
		}

		if (IS_RED (q) && IS_RED (p)) {
#if 0
			// coverity error, parent is never null
			/* Hard red violation: rotate */
			if (!parent) {
				return false;
			}
#endif
			int dir2 = parent->link[1] == g;
			if (q == p->link[last]) {
				_set_link (parent, _rot_once (g, !last), dir2);
			} else {
				_set_link (parent, _rot_twice (g, !last), dir2);
			}
		}

		if (inserted) {
			break;
		}

		last = dir;
		dir = cmp (data, q->data, user) >= 0;

		if (g) {
			parent = g;
		}

		g = p;
		p = q;
		q = q->link[dir];
	}

	/* Update root(it may different due to root rotation) */
	tree->root = head.link[1];

out_exit:
	/* Invariant: root is black */
	tree->root->red = 0;
	tree->root->parent = NULL;
	if (inserted) {
		tree->size++;
	}

	return inserted;
}
Commit message: Better check for sessions

Do not allow other users to hijack a session checking that
the process is launched by the owner of the session.

Signed-off-by: Frediano Ziglio <freddy77@gmail.com>
Acked-by: Uri Lublin <uril@redhat.com>
CVE: CVE-2020-25653
CWE: CWE-362
Vulnerability description: A race condition vulnerability was found in the way the spice-vdagentd daemon handled new client connections. This flaw may allow an unprivileged local guest user to become the active agent for spice-vdagentd, possibly resulting in a denial of service or information leakage from the host. The highest threat from this vulnerability is to data confidentiality as well as system availability. This flaw affects spice-vdagent versions 0.20 and prior.

Project: spice-vd_agent
File: vdagentd.c

static void agent_connect(UdscsConnection *conn)
{
    struct agent_data *agent_data;
    agent_data = g_new0(struct agent_data, 1);
    GError *err = NULL;

    if (session_info) {
        PidUid pid_uid = vdagent_connection_get_peer_pid_uid(VDAGENT_CONNECTION(conn), &err);
        if (err || pid_uid.pid <= 0) {
            static const char msg[] = "Could not get peer PID, disconnecting new client";
            if (err) {
                syslog(LOG_ERR, "%s: %s", msg, err->message);
                g_error_free(err);
            } else {
                syslog(LOG_ERR, "%s", msg);
            }
            agent_data_destroy(agent_data);
            udscs_server_destroy_connection(server, conn);
            return;
        }

        agent_data->session = session_info_session_for_pid(session_info, pid_uid.pid);

        /* Check that the UID of the PID did not change, this should be done after
         * computing the session to avoid race conditions.
         * This can happen as vdagent_connection_get_peer_pid_uid get information
         * from the time of creating the socket, but the process in the meantime
         * have been replaced */
        if (!check_uid_of_pid(pid_uid.pid, pid_uid.uid)) {
            agent_data_destroy(agent_data);
            udscs_server_destroy_connection(server, conn);
            return;
        }
    }

    g_object_set_data_full(G_OBJECT(conn), "agent_data", agent_data,
                           (GDestroyNotify) agent_data_destroy);
    udscs_write(conn, VDAGENTD_VERSION, 0, 0,
                (uint8_t *)VERSION, strlen(VERSION) + 1);
    update_active_session_connection(conn);

    if (device_info) {
        forward_data_to_session_agent(VDAGENTD_GRAPHICS_DEVICE_INFO,
                                      (uint8_t *) device_info, device_info_size);
    }
}
Commit message: ACPI: sbshc: remove raw pointer from printk() message

There's no need to be printing a raw kernel pointer to the kernel log at
every boot.  So just remove it, and change the whole message to use the
correct dev_info() call at the same time.

Reported-by: Wang Qize <wang_qize@venustech.com.cn>
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
CVE: CVE-2018-5750
CWE: CWE-200
Vulnerability description: The acpi_smbus_hc_add function in drivers/acpi/sbshc.c in the Linux kernel through 4.14.15 allows local users to obtain sensitive address information by reading dmesg data from an SBS HC printk call.

Project: linux
File: sbshc.c

static int acpi_smbus_hc_add(struct acpi_device *device)
{
	int status;
	unsigned long long val;
	struct acpi_smb_hc *hc;

	if (!device)
		return -EINVAL;

	status = acpi_evaluate_integer(device->handle, "_EC", NULL, &val);
	if (ACPI_FAILURE(status)) {
		printk(KERN_ERR PREFIX "error obtaining _EC.\n");
		return -EIO;
	}

	strcpy(acpi_device_name(device), ACPI_SMB_HC_DEVICE_NAME);
	strcpy(acpi_device_class(device), ACPI_SMB_HC_CLASS);

	hc = kzalloc(sizeof(struct acpi_smb_hc), GFP_KERNEL);
	if (!hc)
		return -ENOMEM;
	mutex_init(&hc->lock);
	init_waitqueue_head(&hc->wait);

	hc->ec = acpi_driver_data(device->parent);
	hc->offset = (val >> 8) & 0xff;
	hc->query_bit = val & 0xff;
	device->driver_data = hc;

	acpi_ec_add_query_handler(hc->ec, hc->query_bit, NULL, smbus_alarm, hc);
	printk(KERN_INFO PREFIX "SBS HC: EC = 0x%p, offset = 0x%0x, query_bit = 0x%0x\n",
		hc->ec, hc->offset, hc->query_bit);

	return 0;
}
Commit message: Prevent segfault due to buffer overflows in addMultirowsForm

Bug-Debian: https://github.com/tats/w3m/issues/21
Bug-Debian: https://github.com/tats/w3m/issues/26
CVE: CVE-2016-9425
CWE: CWE-119
Vulnerability description: An issue was discovered in the Tatsuya Kinoshita w3m fork before 0.5.3-31. Heap-based buffer overflow in the addMultirowsForm function in w3m allows remote attackers to cause a denial of service (crash) and possibly execute arbitrary code via a crafted HTML page.

Project: w3m
File: anchor.c

addMultirowsForm(Buffer *buf, AnchorList *al)
{
    int i, j, k, col, ecol, pos;
    Anchor a_form, *a;
    Line *l, *ls;

    if (al == NULL || al->nanchor == 0)
	return;
    for (i = 0; i < al->nanchor; i++) {
	a_form = al->anchors[i];
	al->anchors[i].rows = 1;
	if (a_form.hseq < 0 || a_form.rows <= 1)
	    continue;
	for (l = buf->firstLine; l != NULL; l = l->next) {
	    if (l->linenumber == a_form.y)
		break;
	}
	if (!l)
	    continue;
	if (a_form.y == a_form.start.line)
	    ls = l;
	else {
	    for (ls = l; ls != NULL;
		 ls = (a_form.y < a_form.start.line) ? ls->next : ls->prev) {
		if (ls->linenumber == a_form.start.line)
		    break;
	    }
	    if (!ls)
		continue;
	}
	col = COLPOS(ls, a_form.start.pos);
	ecol = COLPOS(ls, a_form.end.pos);
	for (j = 0; l && j < a_form.rows; l = l->next, j++) {
	    pos = columnPos(l, col);
	    if (j == 0) {
		buf->hmarklist->marks[a_form.hseq].line = l->linenumber;
		buf->hmarklist->marks[a_form.hseq].pos = pos;
	    }
	    if (a_form.start.line == l->linenumber)
		continue;
	    buf->formitem = putAnchor(buf->formitem, a_form.url,
				      a_form.target, &a, NULL, NULL, '\0',
				      l->linenumber, pos);
	    a->hseq = a_form.hseq;
	    a->y = a_form.y;
	    a->end.pos = pos + ecol - col;
	    l->lineBuf[pos - 1] = '[';
	    l->lineBuf[a->end.pos] = ']';
	    for (k = pos; k < a->end.pos; k++)
		l->propBuf[k] |= PE_FORM;
	}
    }
}
Commit message: qemu: Add missing lock in qemuProcessHandleMonitorEOF

qemuMonitorUnregister will be called in multiple threads (e.g. threads
in rpc worker pool and the vm event thread).  In some cases, it isn't
protected by the monitor lock, which may lead to call g_source_unref
more than one time and a use-after-free problem eventually.

Add the missing lock in qemuProcessHandleMonitorEOF (which is the only
position missing lock of monitor I found).

Suggested-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Peng Liang <liangpeng10@huawei.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
CVE: CVE-2021-3975
CWE: CWE-416
Vulnerability description: A use-after-free flaw was found in libvirt. The qemuMonitorUnregister() function in qemuProcessHandleMonitorEOF is called using multiple threads without being adequately protected by a monitor lock. This flaw could be triggered by the virConnectGetAllDomainStats API when the guest is shutting down. An unprivileged client with a read-only connection could use this flaw to perform a denial of service attack by causing the libvirt daemon to crash.

Project: libvirt
File: qemu_process.c

qemuProcessHandleMonitorEOF(qemuMonitorPtr mon,
                            virDomainObjPtr vm,
                            void *opaque)
{
    virQEMUDriverPtr driver = opaque;
    qemuDomainObjPrivatePtr priv;
    struct qemuProcessEvent *processEvent;

    virObjectLock(vm);

    VIR_DEBUG("Received EOF on %p '%s'", vm, vm->def->name);

    priv = vm->privateData;
    if (priv->beingDestroyed) {
        VIR_DEBUG("Domain is being destroyed, EOF is expected");
        goto cleanup;
    }

    processEvent = g_new0(struct qemuProcessEvent, 1);

    processEvent->eventType = QEMU_PROCESS_EVENT_MONITOR_EOF;
    processEvent->vm = virObjectRef(vm);

    if (virThreadPoolSendJob(driver->workerPool, 0, processEvent) < 0) {
        virObjectUnref(vm);
        qemuProcessEventFree(processEvent);
        goto cleanup;
    }

    /* We don't want this EOF handler to be called over and over while the
     * thread is waiting for a job.
     */
    qemuMonitorUnregister(mon);

    /* We don't want any cleanup from EOF handler (or any other
     * thread) to enter qemu namespace. */
    qemuDomainDestroyNamespace(driver, vm);

 cleanup:
    virObjectUnlock(vm);
}
Commit message: Rm unneeded function
CVE: CVE-2020-7071
CWE: CWE-20
Vulnerability description: In PHP versions 7.3.x below 7.3.26, 7.4.x below 7.4.14 and 8.0.0, when validating URL with functions like filter_var($url, FILTER_VALIDATE_URL), PHP will accept an URL with invalid password as valid URL. This may lead to functions that rely on URL being valid to mis-parse the URL and produce wrong data as components of the URL.

Project: php-src
File: url.c

static int is_userinfo_valid(const char *str, size_t len)
{
	char *valid = "-._~!$&'()*+,;=:";
	char *p = str;
	while (p - str < len) {
		if (isalpha(*p) || isdigit(*p) || strchr(valid, *p)) {
			p++;
		} else if (*p == '%' && p - str <= len - 3 && isdigit(*(p+1)) && isxdigit(*(p+2))) {
			p += 3;
		} else {
			return 0;
		}
	}
	return 1;
}
Commit message: opt_go: Tolerate unplanned server death

While debugging some experimental nbdkit code that was triggering an
assertion failure in nbdkit, I noticed a secondary failure of nbdsh
also dying from an assertion:

libnbd: debug: nbdsh: nbd_opt_go: transition: NEWSTYLE.OPT_GO.SEND -> DEAD
libnbd: debug: nbdsh: nbd_opt_go: option queued, ignoring state machine failure
nbdsh: opt.c:86: nbd_unlocked_opt_go: Assertion `nbd_internal_is_state_negotiating (get_next_state (h))' failed.

Although my trigger was from non-production nbdkit code, libnbd should
never die from an assertion failure merely because a server
disappeared at the wrong moment during an incomplete reply to
NBD_OPT_GO or NBD_OPT_INFO.  If this is assigned a CVE, a followup
patch will add mention of it in docs/libnbd-security.pod.

Fixes: bbf1c51392 (api: Give aio_opt_go a completion callback)
CVE: CVE-2021-20286
CWE: CWE-617
Vulnerability description: A flaw was found in libnbd 1.7.3. An assertion failure in nbd_unlocked_opt_go in ilb/opt.c may lead to denial of service.

Project: libnbd
File: opt.c

nbd_unlocked_opt_go (struct nbd_handle *h)
{
  int err;
  nbd_completion_callback c = { .callback = go_complete, .user_data = &err };
  int r = nbd_unlocked_aio_opt_go (h, &c);

  if (r == -1)
    return r;

  r = wait_for_option (h);
  if (r == 0 && err) {
    assert (nbd_internal_is_state_negotiating (get_next_state (h)));
    set_error (err, "server replied with error to opt_go request");
    return -1;
  }
  if (r == 0)
    assert (nbd_internal_is_state_ready (get_next_state (h)));
  return r;
}
Commit message: opencdk: cdk_pk_get_keyid: fix stack overflow

Issue found using oss-fuzz:
  https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=340

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
CVE: CVE-2017-5336
CWE: CWE-119
Vulnerability description: Stack-based buffer overflow in the cdk_pk_get_keyid function in lib/opencdk/pubkey.c in GnuTLS before 3.3.26 and 3.5.x before 3.5.8 allows remote attackers to have unspecified impact via a crafted OpenPGP certificate.

Project: gnutls

u32 cdk_pk_get_keyid(cdk_pubkey_t pk, u32 * keyid)
{
	u32 lowbits = 0;
	byte buf[24];

	if (pk && (!pk->keyid[0] || !pk->keyid[1])) {
		if (pk->version < 4 && is_RSA(pk->pubkey_algo)) {
			byte p[MAX_MPI_BYTES];
			size_t n;

			n = MAX_MPI_BYTES;
			_gnutls_mpi_print(pk->mpi[0], p, &n);
			pk->keyid[0] =
			    p[n - 8] << 24 | p[n - 7] << 16 | p[n -
								6] << 8 |
			    p[n - 5];
			pk->keyid[1] =
			    p[n - 4] << 24 | p[n - 3] << 16 | p[n -
								2] << 8 |
			    p[n - 1];
		} else if (pk->version == 4) {
			cdk_pk_get_fingerprint(pk, buf);
			pk->keyid[0] = _cdk_buftou32(buf + 12);
			pk->keyid[1] = _cdk_buftou32(buf + 16);
		}
	}
	lowbits = pk ? pk->keyid[1] : 0;
	if (keyid && pk) {
		keyid[0] = pk->keyid[0];
		keyid[1] = pk->keyid[1];
	}

	return lowbits;
}
Commit message: CDRIVER-2269 Check for zero string length in codewscope
CVE: CVE-2017-14227
CWE: CWE-125
Vulnerability description: In MongoDB libbson 1.7.0, the bson_iter_codewscope function in bson-iter.c miscalculates a bson_utf8_validate length argument, which allows remote attackers to cause a denial of service (heap-based buffer over-read in the bson_utf8_validate function in bson-utf8.c), as demonstrated by bson-to-json.c.

Project: libbson
File: bson-iter.c

bson_iter_codewscope (const bson_iter_t *iter, /* IN */
                      uint32_t *length,        /* OUT */
                      uint32_t *scope_len,     /* OUT */
                      const uint8_t **scope)   /* OUT */
{
   uint32_t len;

   BSON_ASSERT (iter);

   if (ITER_TYPE (iter) == BSON_TYPE_CODEWSCOPE) {
      if (length) {
         memcpy (&len, iter->raw + iter->d2, sizeof (len));
         *length = BSON_UINT32_FROM_LE (len) - 1;
      }

      memcpy (&len, iter->raw + iter->d4, sizeof (len));
      *scope_len = BSON_UINT32_FROM_LE (len);
      *scope = iter->raw + iter->d4;
      return (const char *) (iter->raw + iter->d3);
   }

   if (length) {
      *length = 0;
   }

   if (scope_len) {
      *scope_len = 0;
   }

   if (scope) {
      *scope = NULL;
   }

   return NULL;
}