Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5afcf337 authored by Zhen Kong's avatar Zhen Kong
Browse files

crypto: msm: check potential integer overflow on AEAD req length



According to the specification of AEAD, AEAD request cryptlen is
not a Fixed maximum and assoclen is also same. This could lead to
potential integer overflow, thus allocating less memory. So we
need to check potential integer overflow on AEAD request length.

Change-Id: I58a0c5e1a6e890bad30f7865e96b7db46337158c
Signed-off-by: default avatarZhen Kong <zkong@codeaurora.org>
parent 3f0d02d1
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1949,6 +1949,12 @@ int qce_aead_req(void *handle, struct qce_req *q_req)
	else
		q_req->cryptlen = areq->cryptlen - authsize;

	if ((q_req->cryptlen > ULONG_MAX - ivsize) ||
		(q_req->cryptlen + ivsize > ULONG_MAX - areq->assoclen)) {
		pr_err("Integer overflow on total aead req length.\n");
		return -EINVAL;
	}

	totallen = q_req->cryptlen + ivsize + areq->assoclen;
	pad_len = ALIGN(totallen, ADM_CE_BLOCK_SIZE) - totallen;

+22 −3
Original line number Diff line number Diff line
@@ -1711,16 +1711,28 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
		}
	}
	/* Check for sum of all dst length is equal to data_len  */
	for (i = 0; (i < QCEDEV_MAX_BUFFERS) && (total < req->data_len); i++)
	for (i = 0; (i < QCEDEV_MAX_BUFFERS) && (total < req->data_len); i++) {
		if (req->vbuf.dst[i].len > ULONG_MAX - total) {
			pr_err("%s: Integer overflow on total req dst vbuf length\n",
				__func__);
			goto error;
		}
		total += req->vbuf.dst[i].len;
	}
	if (total != req->data_len) {
		pr_err("%s: Total (i=%d) dst(%d) buf size != data_len (%d)\n",
			__func__, i, total, req->data_len);
		goto error;
	}
	/* Check for sum of all src length is equal to data_len  */
	for (i = 0, total = 0; i < req->entries; i++)
	for (i = 0, total = 0; i < req->entries; i++) {
		if (req->vbuf.src[i].len > ULONG_MAX - total) {
			pr_err("%s: Integer overflow on total req src vbuf length\n",
				__func__);
			goto error;
		}
		total += req->vbuf.src[i].len;
	}
	if (total != req->data_len) {
		pr_err("%s: Total src(%d) buf size != data_len (%d)\n",
			__func__, total, req->data_len);
@@ -1776,8 +1788,15 @@ static int qcedev_check_sha_params(struct qcedev_sha_op_req *req,
	}

	/* Check for sum of all src length is equal to data_len  */
	for (i = 0, total = 0; i < req->entries; i++)
	for (i = 0, total = 0; i < req->entries; i++) {
		if (req->data[i].len > ULONG_MAX - total) {
			pr_err("%s: Integer overflow on total req buf length\n",
				__func__);
			goto sha_error;
		}
		total += req->data[i].len;
	}

	if (total != req->data_len) {
		pr_err("%s: Total src(%d) buf size != data_len (%d)\n",
			__func__, total, req->data_len);
+23 −1
Original line number Diff line number Diff line
@@ -1542,8 +1542,20 @@ static int _qcrypto_process_aead(struct crypto_engine *pengine,

			rctx->orig_src = req->src;
			rctx->orig_dst = req->dst;

			if ((MAX_ALIGN_SIZE*2 > ULONG_MAX - req->assoclen) ||
				((MAX_ALIGN_SIZE*2 + req->assoclen) >
						ULONG_MAX - qreq.authsize) ||
				((MAX_ALIGN_SIZE*2 + req->assoclen +
						qreq.authsize) >
						ULONG_MAX - req->cryptlen)) {
				pr_err("Integer overflow on aead req length.\n");
				return -EINVAL;
			}

			rctx->data = kzalloc((req->cryptlen + qreq.assoclen +
					qreq.authsize + 64*2), GFP_ATOMIC);
					qreq.authsize + MAX_ALIGN_SIZE*2),
					GFP_ATOMIC);
			if (rctx->data == NULL) {
				pr_err("Mem Alloc fail rctx->data, err %ld\n",
							PTR_ERR(rctx->data));
@@ -1605,6 +1617,16 @@ static int _qcrypto_process_aead(struct crypto_engine *pengine,
			 * include  assoicated data, ciphering data stream,
			 * generated MAC, and CCM padding.
			 */
			if ((MAX_ALIGN_SIZE * 2 > ULONG_MAX - req->assoclen) ||
				((MAX_ALIGN_SIZE * 2 + req->assoclen) >
						ULONG_MAX - qreq.ivsize) ||
				((MAX_ALIGN_SIZE * 2 + req->assoclen
					+ qreq.ivsize)
						> ULONG_MAX - req->cryptlen)) {
				pr_err("Integer overflow on aead req length.\n");
				return -EINVAL;
			}

			rctx->data = kzalloc(
					(req->cryptlen +
						req->assoclen +