Bug 2459136 (CVE-2026-6435) - CVE-2026-6435 rust-coreutils: rust-coreutils: Arbitrary file permission modification via TOCTOU race in chmod symbolic link traversal
Summary: CVE-2026-6435 rust-coreutils: rust-coreutils: Arbitrary file permission modif...
Keywords:
Status: NEW
Alias: CVE-2026-6435
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
medium
medium
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2459137 2459138 2459139
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-04-17 08:11 UTC by OSIDB Bzimport
Modified: 2026-04-17 08:15 UTC (History)
0 users

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-04-17 08:11:42 UTC
The uutils implementation of 'chmod' has a TOCTOU race that can lead it to change the permissions of a file pointed to by a symbolic link during traversal.

See the following example:

```
$ mkdir -p a/b
$ touch a/b/1 a/b/2 a/b/3
$ strace -e trace='/stat|chmod' uu_chmod -R 777 a
[...]
newfstatat(3, "b", {st_mode=S_IFDIR|0777, st_size=6, ...}, AT_SYMLINK_NOFOLLOW) = 0
statx(AT_FDCWD, "a/b", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFDIR|0777, stx_size=6, ...}) = 0
statx(AT_FDCWD, "a/b", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFDIR|0777, stx_size=6, ...}) = 0
fchmodat(3, "b", 0777)                  = 0
fstat(5, {st_mode=S_IFDIR|0777, st_size=6, ...}) = 0
newfstatat(4, "1", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
statx(AT_FDCWD, "a/b/1", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
statx(AT_FDCWD, "a/b/1", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
fchmodat(4, "1", 0777)                  = 0
newfstatat(4, "2", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
statx(AT_FDCWD, "a/b/2", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
statx(AT_FDCWD, "a/b/2", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
fchmodat(4, "2", 0777)                  = 0
newfstatat(4, "3", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
statx(AT_FDCWD, "a/b/3", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
statx(AT_FDCWD, "a/b/3", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID|STATX_SUBVOL, stx_attributes=0, stx_mode=S_IFREG|0777, stx_size=0, ...}) = 0
fchmodat(4, "3", 0777)                  = 0
+++ exited with 0 +++
```

It is unsafe to rely on the result of stat or statx in the 'chmod' command, generally. The directory entry may change between the call to statx and fchmodat. A malicious user and/or process may create a symbolic link to an arbitrary file in its place between the two calls. If timed correctly, uutils 'chmod' will change the permissions of the file that the symbolic link points to. The classic way to do this is to generate lots of load on a system to slow down the 'uu_chmod' command. Then, use a process with higher priority to remove the file and create a symbolic link in it's place.

I think this is worth assigning a CVE.

Reproducible: Always

Steps to Reproduce:
Given in the description.
Actual Results:
Given in the description.

Expected Results:
uutils 'chmod' should use functions that do not follow symbolic links. For example, GNU coreutils handles the same example safely using fchmodat2 and the AT_SYMLINK_NOFOLLOW flag:

```
$ strace -e trace='/stat|chmod' chmod -R 777 a
[...]
newfstatat(4, "b", {st_mode=S_IFDIR|0777, st_size=6, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat2(4, "b", 0777, AT_SYMLINK_NOFOLLOW) = 0
fstat(3, {st_mode=S_IFDIR|0777, st_size=6, ...}) = 0
newfstatat(5, "1", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat2(5, "1", 0777, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(5, "2", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat2(5, "2", 0777, AT_SYMLINK_NOFOLLOW) = 0
newfstatat(5, "3", {st_mode=S_IFREG|0777, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
fchmodat2(5, "3", 0777, AT_SYMLINK_NOFOLLOW) = 0
+++ exited with 0 +++


Note You need to log in before you can comment on or make changes to this bug.