mirror of
https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9.git
synced 2026-09-09 00:08:12 +08:00
Merge: CVE-2026-64490: ALSA: virtio: Validate control metadata from the device
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/8535 JIRA: https://redhat.atlassian.net/browse/RHEL-230137 CVE: CVE-2026-64490 Backported from tree(s): linux ``` ALSA: virtio: Validate control metadata from the device virtio-snd control handling trusts the device-provided control type and value count returned by the device. That metadata is then used directly to index g_v2a_type_map[] in virtsnd_kctl_info(), and to size loops and memcpy() operations in virtsnd_kctl_get() and virtsnd_kctl_put() against fixed-size virtio_snd_ctl_value and snd_ctl_elem_value arrays. A buggy or malicious device can therefore trigger out-of-bounds access by advertising an invalid control type or an oversized value count. Validate control type and count once in virtsnd_kctl_parse_cfg(), before querying enumerated items or exposing the control to ALSA. Fixes: d6568e3de42d ("ALSA: virtio: add support for audio controls") Cc: stable@vger.kernel.org Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com> Link: https://patch.msgid.link/20260507-alsa-virtio-validate-kctl-info-v1-1-7404fb12ec37@gmail.com Signed-off-by: Takashi Iwai <tiwai@suse.de> (cherry picked from commit c77a6cbb36ff8cbc1f084d94f8dcda5250935271) ``` Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com> [^footer]: Created 2026-08-05 23:53 UTC by backporter - [KWF FAQ](https://red.ht/kernel_workflow_doc) - [Slack #team-kernel-workflow](https://redhat-internal.slack.com/archives/C04LRUPMJQ5) - [Source](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/webhook/utils/backporter.py) - [Documentation](https://gitlab.com/cki-project/kernel-workflow/-/blob/main/docs/README.backporter.md) - [Report an issue](https://redhat.atlassian.net/secure/CreateIssueDetails!init.jspa?pid=11779&issuetype=10016&priority=10001&summary=backporter+webhook+issue&components=66291) [^footer] Approved-by: Jaroslav Kysela <jkysela@redhat.com> Approved-by: Daniel Horak <dhorak@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: CKI GitLab Kmaint Pipeline Bot <26919896-cki-kmaint-pipeline-bot@users.noreply.gitlab.com>
This commit is contained in:
@@ -18,6 +18,21 @@ static const snd_ctl_elem_type_t g_v2a_type_map[] = {
|
||||
[VIRTIO_SND_CTL_TYPE_IEC958] = SNDRV_CTL_ELEM_TYPE_IEC958
|
||||
};
|
||||
|
||||
/* Map for converting VirtIO types to maximum value counts. */
|
||||
static const unsigned int g_v2a_count_map[] = {
|
||||
[VIRTIO_SND_CTL_TYPE_BOOLEAN] =
|
||||
ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
|
||||
[VIRTIO_SND_CTL_TYPE_INTEGER] =
|
||||
ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
|
||||
[VIRTIO_SND_CTL_TYPE_INTEGER64] =
|
||||
ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer64),
|
||||
[VIRTIO_SND_CTL_TYPE_ENUMERATED] =
|
||||
ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.enumerated),
|
||||
[VIRTIO_SND_CTL_TYPE_BYTES] =
|
||||
ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.bytes),
|
||||
[VIRTIO_SND_CTL_TYPE_IEC958] = 1
|
||||
};
|
||||
|
||||
/* Map for converting VirtIO access rights to ALSA access rights. */
|
||||
static const unsigned int g_v2a_access_map[] = {
|
||||
[VIRTIO_SND_CTL_ACCESS_READ] = SNDRV_CTL_ELEM_ACCESS_READ,
|
||||
@@ -36,6 +51,37 @@ static const unsigned int g_v2a_mask_map[] = {
|
||||
[VIRTIO_SND_CTL_EVT_MASK_TLV] = SNDRV_CTL_EVENT_MASK_TLV
|
||||
};
|
||||
|
||||
static int virtsnd_kctl_validate_info(struct virtio_snd *snd, u32 cid,
|
||||
struct virtio_snd_ctl_info *kinfo)
|
||||
{
|
||||
struct virtio_device *vdev = snd->vdev;
|
||||
unsigned int type = le32_to_cpu(kinfo->type);
|
||||
unsigned int count = le32_to_cpu(kinfo->count);
|
||||
|
||||
if (type >= ARRAY_SIZE(g_v2a_type_map)) {
|
||||
dev_err(&vdev->dev, "control #%u: unknown type %u\n",
|
||||
cid, type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (count > g_v2a_count_map[type] ||
|
||||
(type == VIRTIO_SND_CTL_TYPE_IEC958 && count != 1)) {
|
||||
dev_err(&vdev->dev, "control #%u: invalid count %u for type %u\n",
|
||||
cid, count, type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED &&
|
||||
!le32_to_cpu(kinfo->value.enumerated.items)) {
|
||||
dev_err(&vdev->dev,
|
||||
"control #%u: no items for enumerated control\n",
|
||||
cid);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* virtsnd_kctl_info() - Returns information about the control.
|
||||
* @kcontrol: ALSA control element.
|
||||
@@ -385,6 +431,10 @@ int virtsnd_kctl_parse_cfg(struct virtio_snd *snd)
|
||||
struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i];
|
||||
unsigned int type = le32_to_cpu(kinfo->type);
|
||||
|
||||
rc = virtsnd_kctl_validate_info(snd, i, kinfo);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED) {
|
||||
rc = virtsnd_kctl_get_enum_items(snd, i);
|
||||
if (rc)
|
||||
|
||||
Reference in New Issue
Block a user