Track vulnerabilities like this one.
Sign up free to get alerted when software you use is affected.
7.1
Linux jfs: Data can be read from unintended memory locations
published 1 year ago
Summary
A Linux kernel vulnerability affects the jfs file system, potentially allowing unauthorized data access. This issue is resolved in the latest updates. To stay secure, ensure your Linux system is running with the latest kernel version.
What to do
- Update linux kernel to version 6.14.2.
Affected software
| Ecosystem | Vendor | Product | Affected versions |
|---|---|---|---|
| Linux | linux | kernel |
>= 6.13.0, < 6.14.2 Fix: upgrade to 6.14.2
|
Original advisory text
jfs: fix slab-out-of-bounds read in ea_get()
In the Linux kernel, the following vulnerability has been resolved:
jfs: fix slab-out-of-bounds read in ea_get()
During the "size_check" label in ea_get(), the code checks if the extended
attribute list (xattr) size matches ea_size. If not, it logs
"ea_get: invalid extended attribute" and calls print_hex_dump().
Here, EALIST_SIZE(ea_buf->xattr) returns 4110417968, which exceeds
INT_MAX (2,147,483,647). Then ea_size is clamped:
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
Although clamp_t aims to bound ea_size between 0 and 4110417968, the upper
limit is treated as an int, causing an overflow above 2^31 - 1. This leads
"size" to wrap around and become negative (-184549328).
The "size" is then passed to print_hex_dump() (called "len" in
print_hex_dump()), it is passed as type size_t (an unsigned
type), this is then stored inside a variable called
"int remaining", which is then assigned to "int linelen" which
is then passed to hex_dump_to_buffer(). In print_hex_dump()
the for loop, iterates through 0 to len-1, where len is
18446744073525002176, calling hex_dump_to_buffer()
on each iteration:
for (i = 0; i < len; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
linebuf, sizeof(linebuf), ascii);
...
}
The expected stopping condition (i < len) is effectively broken
since len is corrupted and very large. This eventually leads to
the "ptr+i" being passed to hex_dump_to_buffer() to get closer
to the end of the actual bounds of "ptr", eventually an out of
bounds access is done in hex_dump_to_buffer() in the following
for loop:
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
...
}
To fix this we should validate "EALIST_SIZE(ea_buf->xattr)"
before it is utilised.
jfs: fix slab-out-of-bounds read in ea_get()
During the "size_check" label in ea_get(), the code checks if the extended
attribute list (xattr) size matches ea_size. If not, it logs
"ea_get: invalid extended attribute" and calls print_hex_dump().
Here, EALIST_SIZE(ea_buf->xattr) returns 4110417968, which exceeds
INT_MAX (2,147,483,647). Then ea_size is clamped:
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
Although clamp_t aims to bound ea_size between 0 and 4110417968, the upper
limit is treated as an int, causing an overflow above 2^31 - 1. This leads
"size" to wrap around and become negative (-184549328).
The "size" is then passed to print_hex_dump() (called "len" in
print_hex_dump()), it is passed as type size_t (an unsigned
type), this is then stored inside a variable called
"int remaining", which is then assigned to "int linelen" which
is then passed to hex_dump_to_buffer(). In print_hex_dump()
the for loop, iterates through 0 to len-1, where len is
18446744073525002176, calling hex_dump_to_buffer()
on each iteration:
for (i = 0; i < len; i += rowsize) {
linelen = min(remaining, rowsize);
remaining -= rowsize;
hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
linebuf, sizeof(linebuf), ascii);
...
}
The expected stopping condition (i < len) is effectively broken
since len is corrupted and very large. This eventually leads to
the "ptr+i" being passed to hex_dump_to_buffer() to get closer
to the end of the actual bounds of "ptr", eventually an out of
bounds access is done in hex_dump_to_buffer() in the following
for loop:
for (j = 0; j < len; j++) {
if (linebuflen < lx + 2)
goto overflow2;
ch = ptr[j];
...
}
To fix this we should validate "EALIST_SIZE(ea_buf->xattr)"
before it is utilised.
References
- https://git.kernel.org/stable/c/0beddc2a3f9b9cf7d8887973041e36c2d0fa3652 URL
- https://git.kernel.org/stable/c/16d3d36436492aa248b2d8045e75585ebcc2f34d URL
- https://git.kernel.org/stable/c/3d6fd5b9c6acbc005e53d0211c7381f566babec1 URL
- https://git.kernel.org/stable/c/46e2c031aa59ea65128991cbca474bd5c0c2ecdb URL
- https://git.kernel.org/stable/c/50afcee7011155933d8d5e8832f52eeee018cfd3 URL
- https://git.kernel.org/stable/c/5263822558a8a7c0d0248d5679c2dcf4d5cda61f URL
- https://git.kernel.org/stable/c/78c9cbde8880ec02d864c166bcb4fe989ce1d95f URL
- https://git.kernel.org/stable/c/a8c31808925b11393a6601f534bb63bac5366bab URL
- https://git.kernel.org/stable/c/fdf480da5837c23b146c4743c18de97202fcab37 URL
- https://lists.debian.org/debian-lts-announce/2025/05/msg00030.html URL
- https://lists.debian.org/debian-lts-announce/2025/05/msg00045.html URL
- https://github.com/CVEProject/cvelistV5/tree/main/cves/2025/39xxx/CVE-2025-39735... Vendor Advisory
- https://nvd.nist.gov/vuln/detail/CVE-2025-39735 Vendor Advisory
- https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git Product
Internet-facing
60 days
Internal
At next upgrade
- Not known to be exploited
- Needs hands-on effort to exploit (estimated)
- Gives an attacker partial control (estimated)
Timeline
Published18 Apr 2025
Updated31 Jul 2026
First seen31 Jul 2026
Track software like this
Free during beta