8000 alsa-lib: backport CVE-2026-90781 fix, declare GithubRepo provenance by bryan-minimal · Pull Request #915 · gominimal/pkgs · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
35 changes: 35 additions & 0 deletions packages/alsa-lib/CVE-2026-90781-numid.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
From 1e27d63ef6d1dcf7d1f1a1e1eca3ea779e7de377 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Dirk=20M=C3=BCller?= <dirk@dmllr.de>
Date: Tue, 2 Jun 2026 11:17:31 +0200
Subject: [PATCH] Fix theoretical one-byte buffer overrun
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If 64 (sizeof(buf))= or more characters were provided in the input string,
this unconditionally writes a null byte to `buf[64]`, which is one byte
past the end of the array.

Closes: https://github.com/alsa-project/alsa-lib/pull/509
Signed-off-by: Dirk Müller <dirk@dmllr.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/ctlparse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/control/ctlparse.c b/src/control/ctlparse.c
index 3bd86435..c40de2bd 100644
--- a/src/control/ctlparse.c
+++ b/src/control/ctlparse.c
@@ -173,7 +173,7 @@ int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
ptr = buf;
size = 0;
while (*str && *str != ',') {
- if (size < (int)sizeof(buf)) {
+ if (size < (int)sizeof(buf) - 1) {
*ptr++ = *str;
size++;
}
--
2.54.0 (Apple Git-157)

37 changes: 37 additions & 0 deletions packages/alsa-lib/CVE-2026-90781.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
From f84cd4ced7b36fddb8e4ee24404cf7c091d27020 Mon Sep 17 00:00:00 2001
From: Jaroslav Kysela <perex@perex.cz>
Date: Sun, 30 Aug 2026 20:20:30 +0200
Subject: [PATCH] control: ctlparse - another fix for one-byte overrrun in
__snd_ctl_ascii_elem_id_parse

Follows 1e27d63ef6d1dcf7d1f1a1e1eca3ea779e7de377 .

Link: https://lore.kernel.org/alsa-devel/CACBQ=P2FhO3M6dkv3cWuKb6Qhs92ouV+FJ3SJZ_PVBSSdJWRAQ@mail.gmail.com/
Reported-by: Harsh Raj Singhania <raj.harshraut@gmail.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
---
src/control/ctlparse.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/control/ctlparse.c b/src/control/ctlparse.c
index c40de2bd..7132210e 100644
--- a/src/control/ctlparse.c
+++ b/src/control/ctlparse.c
@@ -219,7 +219,7 @@ int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
if (*str == '\'' || *str == '\"') {
c = *str++;
while (*str && *str != c) {
- if (size < (int)sizeof(buf)) {
+ if (size < (int)sizeof(buf) - 1) {
*ptr++ = *str;
size++;
}
@@ -229,7 +229,7 @@ int __snd_ctl_ascii_elem_id_parse(snd_ctl_elem_id_t *dst, const char *str,
str++;
} else {
while (*str && *str != ',') {
- if (size < (int)sizeof(buf)) {
+ if (size < (int)sizeof(buf) - 1) {
*ptr++ = *str;
size++;
}
19 changes: 19 additions & 0 deletions packages/alsa-lib/build.ncl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ let { target, .. } = import "config.ncl" in
let base = import "../base/build.ncl" in
let make = import "../make/build.ncl" in
let toolchain = import "../toolchain/build.ncl" in
let patch = import "../patch/build.ncl" in
let glibc = import "../glibc/build.ncl" in

let version = "1.2.16.1" in
Expand All @@ -17,8 +18,21 @@ let version = "1.2.16.1" in
extract = true,
strip_prefix = "alsa-lib-%{version}",
} | Source,
# Security backport: CVE-2026-90781, one-byte stack overrun of the 64-byte
# `buf` in __snd_ctl_ascii_elem_id_parse (src/control/ctlparse.c) when an
# element-id string carries a name of 64+ characters. Upstream fixed it in
# alsa-project/alsa-lib commit f84cd4ced7b3 (2026-08-30), after 1.2.16.1, the
# latest release; Debian carries the same commit as 1.2.16.1-2. Verbatim
# `git format-patch` of that commit, applied fail-closed in build.sh.
{ file = "CVE-2026-90781.patch" } | Local,
# f84cd4ce "follows" upstream 1e27d63ef6d1 (2026-06-02), which fixes the
# same one-byte overrun on the numid= branch of the same function and is
# also not in 1.2.16.1. f84cd4ce alone leaves that site open, so both are
# carried. Verbatim `git format-patch` of 1e27d63e.
{ file = "CVE-2026-90781-numid.patch" } | Local,
base,
make,
patch,
toolchain,
],
runtime_deps = [
Expand All @@ -45,5 +59,10 @@ let version = "1.2.16.1" in
upstream_version = version,
license_spdx = "LGPL-2.1-only",
repology_project = "alsa-lib",
source_provenance = {
category = 'GithubRepo,
owner = "alsa-project",
repo = "alsa-lib",
},
} | Attrs,
} | BuildSpec
56 changes: 56 additions & 0 deletions packages/alsa-lib/build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#!/bin/sh
set -e

# Security backport (see build.ncl). `set -e` plus patch's non-zero exit on a
# rejected hunk means a stale patch ABORTS the build rather than silently
# shipping an unpatched libasound.
patch -Np1 -i "CVE-2026-90781-numid.patch" # control/ctlparse.c numid= one-byte stack overrun (1e27d63e)
patch -Np1 -i "CVE-2026-90781.patch" # control/ctlparse.c name= one-byte stack overruns (f84cd4ce)

case $(uname -m) in
x86_64) MARCH="-march=x86-64-v3" ;;
aarch64) MARCH="-march=armv8-a" ;;
Expand All @@ -14,4 +20,54 @@ export CXXFLAGS="${CFLAGS}"

make -j$(nproc)
make check

# Regression test for CVE-2026-90781. The overrun is a single '\0' written one
# byte past a stack array, which corrupts nothing observable on its own, so the
# test compiles ctlparse.c itself under AddressSanitizer (the copy inside
# libasound.so is not instrumented) and parses element ids that hit each of
# the three copy loops with 100 characters: a quoted name, an unquoted name,
# and a numid. Unpatched, ASan reports stack-buffer-overflow and the build
# fails; patched, each copy stops in bounds. Built in a scratch dir, never
# installed.
mkdir -p cve-test
cat > cve-test/ctlparse_overrun.c <<'EOF'
#include "../src/control/ctlparse.c"
#include <stdio.h>
#include <string.h>

static int parse(const char *s)
{
snd_ctl_elem_id_t *id;
snd_ctl_elem_id_alloca(&id);
int err = snd_ctl_ascii_elem_id_parse(id, s);
printf("parse(%zu chars) = %d, name length %zu\n",
strlen(s), err, strlen(snd_ctl_elem_id_get_name(id)));
return err;
}

int main(void)
{
char quoted[128] = "name='", unquoted[128] = "name=", numid[128] = "numid=";
memset(quoted + 6, 'A', 100);
strcpy(quoted + 106, "'");
memset(unquoted + 5, 'B', 100);
unquoted[105] = '\0';
memset(numid + 6, '1', 100);
numid[106] = '\0';
if (parse(quoted) < 0 || parse(unquoted) < 0)
return 1;
/* A 100-digit numid is out of range, so the parse is rejected. What
* matters is that the copy into buf stayed in bounds getting there. */
if (parse(numid) >= 0)
return 1;
return 0;
}
EOF
gcc -O1 -g -fsanitize=address -fno-omit-frame-pointer \
-I include -I src/control \
-o cve-test/ctlparse_overrun cve-test/ctlparse_overrun.c \
-L src/.libs -lasound
ASAN_OPTIONS=detect_leaks=0:abort_on_error=0 \
LD_LIBRARY_PATH="$(pwd)/src/.libs" ./cve-test/ctlparse_overrun

make DESTDIR=$OUTPUT_DIR install
Loading
0