Bug 2572312 (CVE-2026-127018) - CVE-2026-127018 incron: setuid incrontab can change ownership of arbitrary files, enabling local privilege escalation
Summary: CVE-2026-127018 incron: setuid incrontab can change ownership of arbitrary fi...
Keywords:
Status: NEW
Alias: CVE-2026-127018
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2572611 2572612
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-11-12 09:51 UTC by OSIDB Bzimport
Modified: 2026-11-12 15:25 UTC (History)
0 users

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


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-11-12 09:51:54 UTC
Overview
========

An unprivileged local user can supply a custom incron configuration to the setuid-root /usr/bin/incrontab program. Although incrontab prints: "insufficient privileges to use custom configuration (will use default)" it does not actually reset the configuration path to the default. It proceeds to load the attacker-controlled configuration.

By making the user-table path a symbolic link to a root-owned file, incrontab follows the link while running with effective UID 0, writes the supplied table through it, and then calls chown() on the resulting path. This gives us an arbitrary root-file overwrite primitive. I demonstrated local privilege escalation by targeting /etc/passwd.

This works on the stock Fedora ISO installed into a qemu VM with the only change being the installation of incron, SELinux was left enabled.

* Fedora release 45 (Forty Five)
* incron-0.5.12-30.fc45.x86_64
* selinux-policy-targeted-45.23-1.fc45.noarch
* selinux-policy-45.23-1.fc45.noarch

Root cause
==========

In ict-main.cpp, the config option is initialized to the system configuration:

    std::string cfg(INCRON_CONFIG);

When -f/--config is supplied, AppArgs::GetOption() replaces cfg with the
attacker-provided path. For a non-root real UID, the code only prints a
warning:

    if (uid != 0) {
        fprintf(stderr,
            "insufficient privileges to use custom configuration "
            "(will use default)\n");
    }

It does not return an error and does not restore cfg to INCRON_CONFIG.
IncronCfg::Load(cfg) consequently loads the attacker-provided file.

The attacker-controlled user_table_dir is later used to construct the output
path in copy_from_file(). The setuid process saves the table to that path and
then performs:

    chown(out.c_str(), ppwd->pw_uid, -1)

Both operations follow a symbolic link placed at the attacker-selected output
path.


Reproducible: Always

Steps to Reproduce:
Reproduction
============

As root

1. Install incron.

As an ordinary user:

1. Create an attacker-owned directory containing a spool directory.
2. Create a custom configuration setting user_table_dir to that spool directory and allowed_users to an attacker-controlled allow file.
3. Add the current username to the allow file.
4. Create a symbolic link named after the current user inside the spool directory, pointing to /etc/passwd.
5. Execute /usr/bin/incrontab -f ATTACKER_CONFIG TABLE_FILE

Despite reporting that the custom configuration cannot be used, incrontab loads it. /etc/passwd is overwritten through the symbolic link and its owner is changed to the attacking user's UID.

---

Details of PoC/steps to reproduce:

mkdir /tmp/repro
mkdir /tmp/repro/spool
ln -s /etc/passwd /tmp/repro/spool/riv

/tmp/repro/config:
user_table_dir = /tmp/repro/spool
allowed_users = /tmp/repro/allow

/tmp/repro/allow:
riv

/tmp/repro/table
riv:x:1001:1001::/home/riv:/bin/bash 1 placeholder

/usr/bin/incrontab -f /tmp/repro/config /tmp/repro/table



Expected Results:
If the software is launched by a low privilege user, it should not be able to overwrite arbitrary files.


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