alsa-lib: security hardening — UCM, conf parser, topology, PCM plugins (6 findings) - #527
Open
HarshRajSinghania wants to merge 1 commit into
Open
HarshRajSinghania wants to merge 1 commit into
HarshRajSinghania wants to merge 1 commit into
Conversation
…alformed input Addresses six independently-triggered issues found during audit of commit f84cd4c: A1 (UCM sysw, src/ucm/main.c): snprintf() concatenates the sysfs root with an attacker-supplied path with no '..' rejection; add realpath() confinement to ensure the resolved path stays within the sysfs root. CWE-22. A2 (UCM cfg-save, src/ucm/main.c): snd_output_stdio_open() called with a caller-supplied filename and no path restriction; add realpath() check to confine writes to XDG_RUNTIME_DIR (or /tmp). CWE-73. A4 (conf parser, src/conf.c): absolute-path includes opened without any '../' rejection, allowing traversal reads; reject paths containing '/../'. CWE-22. A5 (topology ctl, src/topology/ctl.c): size2 = x->size + x->priv.size is computed in uint32_t arithmetic and can wrap on a 64-bit host, bypassing the subsequent bounds check. Fix: pre-check for overflow then cast to size_t before addition. Affects tplg_decode_control_mixer/enum/bytes (three sites). CWE-190. A7 (PCM route, src/pcm/pcm_route.c): channel indices from config grow csize/ ssize without bound, leading to an uncapped malloc(csize*ssize*4); cap both at 1024 (consistent with other PCM plugins). CWE-770. A8 (PCM multi, src/pcm/pcm_multi.c): two assert() calls fire on sparse channel binding maps (gaps between bindings leave sidxs[i]==-1), causing SIGABRT in debug builds and OOB reads under NDEBUG; replace with explicit -EINVAL returns. CWE-617. A3 (UCM shell/system()) and A6 (PCM file popen) are intentional features; hardening suggestions (compile-time gate, fork/execve) noted but not patched here without maintainer guidance on the desired interface. All six code-path changes verified standalone against f84cd4c with proof-of-concept programs. Signed-off-by: Harsh Raj Singhania <raj.harshraut@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR addresses six independently-triggered security hardening issues found during a source audit of commit
f84cd4c, all verified with proof-of-concept programs.A3 (
shell/system()) and A6 (PCM filepopen) are intentional features and are not patched here — hardening suggestions noted inline for maintainer consideration.A1 — UCM
syswpath traversal (CWE-22) ·src/ucm/main.cexecute_sysw()concatenates the sysfs root with a caller-supplied string viasnprintf()with no..rejection orrealpath()confinement. A UCM path like../../etc/cron.d/x:valuewrites to an arbitrary filesystem location. Fix:realpath()confinement — reject if resolved path does not remain within the sysfs root.A2 — UCM
cfg-saveunrestricted path (CWE-73) ·src/ucm/main.cexecute_cfgsave()callssnd_output_stdio_open(&out, file, "w+")with a raw caller-suppliedfileand no restriction. Any writable path (e.g.~/.ssh/authorized_keys) is reachable. Fix:realpath()check — confine toXDG_RUNTIME_DIR(fallback/tmp).A4 — Config parser absolute include traversal (CWE-22) ·
src/conf.cinput_stdio_open()immediately opens any absolute path (file[0]=='/') without checking for..components. A planted config with</../../etc/shadow>can read arbitrary files. Fix: reject paths containing/../.A5 — Topology control
uint32_tinteger overflow (CWE-190) ·src/topology/ctl.csize2 = x->size + x->priv.sizeis computed in 32-bit unsigned arithmetic before being widened tosize_t. On a 64-bit host,0xFFFFFFF0 + 0x20 = 0x10(wraps), bypassing the subsequentsize2 > sizeguard. Three sites:tplg_decode_control_mixer,tplg_decode_control_enum,tplg_decode_control_bytes(distinct from CVE-2026-25068 which wastplg_decode_control_mixer1). Fix: pre-check for overflow, then(size_t)x->size + (size_t)x->priv.size.A7 — PCM
routeplugin unboundedttableallocation (CWE-770) ·src/pcm/pcm_route.ccsize/ssizegrow from config-supplied channel indices with no upper bound beforemalloc(csize * ssize * sizeof(entry)). Index1073741823→malloc(8 GB). Fix: cap both at 1024 (consistent withdmix,softvol, other PCM plugins).A8 — PCM
multisparse bindings OOB assert (CWE-617) ·src/pcm/pcm_multi.cSparse binding maps leave
sidxs[i] == -1for gap indices.assert(schannels[i] < schannels_count[sidxs[i]])then dereferencesschannels_count[-1]→ SIGABRT (debug) / OOB read (NDEBUG). Fix: replace bothassert()s with explicit-EINVALreturns with bounds and sign checks.Verified: all six PoC programs confirmed on
libasound2 1.2.14/gcc 14.2, commitf84cd4c.Signed-off-by: Harsh Raj Singhania raj.harshraut@gmail.com