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

Commit 84eae59b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "KEYS: fix out-of-bounds read during ASN.1 parsing"

parents beae668f 86b59907
Loading
Loading
Loading
Loading
+29 −21
Original line number Diff line number Diff line
@@ -283,6 +283,9 @@ next_op:
				if (unlikely(len > datalen - dp))
					goto data_overrun_error;
			}
		} else {
			if (unlikely(len > datalen - dp))
				goto data_overrun_error;
		}

		if (flags & FLAG_CONS) {
@@ -309,42 +312,47 @@ next_op:

	/* Decide how to handle the operation */
	switch (op) {
	case ASN1_OP_MATCH_ANY_ACT:
	case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
	case ASN1_OP_COND_MATCH_ANY_ACT:
	case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:
		ret = actions[machine[pc + 1]](context, hdr, tag, data + dp, len);
		if (ret < 0)
			return ret;
		goto skip_data;

	case ASN1_OP_MATCH_ACT:
	case ASN1_OP_MATCH_ACT_OR_SKIP:
	case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
		ret = actions[machine[pc + 2]](context, hdr, tag, data + dp, len);
		if (ret < 0)
			return ret;
		goto skip_data;

	case ASN1_OP_MATCH:
	case ASN1_OP_MATCH_OR_SKIP:
	case ASN1_OP_MATCH_ACT:
	case ASN1_OP_MATCH_ACT_OR_SKIP:
	case ASN1_OP_MATCH_ANY:
	case ASN1_OP_MATCH_ANY_OR_SKIP:
	case ASN1_OP_MATCH_ANY_ACT:
	case ASN1_OP_MATCH_ANY_ACT_OR_SKIP:
	case ASN1_OP_COND_MATCH_OR_SKIP:
	case ASN1_OP_COND_MATCH_ACT_OR_SKIP:
	case ASN1_OP_COND_MATCH_ANY:
	case ASN1_OP_COND_MATCH_ANY_OR_SKIP:
	skip_data:
	case ASN1_OP_COND_MATCH_ANY_ACT:
	case ASN1_OP_COND_MATCH_ANY_ACT_OR_SKIP:

		if (!(flags & FLAG_CONS)) {
			if (flags & FLAG_INDEFINITE_LENGTH) {
				size_t tmp = dp;

				ret = asn1_find_indefinite_length(
					data, datalen, &dp, &len, &errmsg);
					data, datalen, &tmp, &len, &errmsg);
				if (ret < 0)
					goto error;
			} else {
				dp += len;
			}
			pr_debug("- LEAF: %zu\n", len);
		}

		if (op & ASN1_OP_MATCH__ACT) {
			unsigned char act;

			if (op & ASN1_OP_MATCH__ANY)
				act = machine[pc + 1];
			else
				act = machine[pc + 2];
			ret = actions[act](context, hdr, tag, data + dp, len);
			if (ret < 0)
				return ret;
		}

		if (!(flags & FLAG_CONS))
			dp += len;
		pc += asn1_op_lengths[op];
		goto next_op;