Fedora Account System
Red Hat Associate
Red Hat Customer
AI_ONLY_REPORT package: sblim-sfcb-1.4.9-36.el10 ------ Summary: Insecure temporary file in /tmp allows symlink overwrite (sfcbinst.mof): a local attacker can win a TOCTOU race on `/tmp/sfcbinst.mof` during privileged instance migration and redirect appended MOF output into an attacker-chosen file, causing privileged file corruption or denial of service. Requirements to exploit: A local low-privileged user on the same host, the ability to repeatedly recreate `/tmp/sfcbinst.mof` as a symlink after it is removed, a privileged `sfcbrepos` execution, instance migration left enabled (no `-i`), and a `repository.previous/<namespace>/` directory containing at least one static instance file so the `sfcbinst2mof -o` path executes. Component affected: `sblim-sfcb-1.4.9-36.el10`: `sfcbrepos` temporary-file handling in `sfcbrepos.sh.in` and `sfcbrepos.sh.in.sfcbrepos-schema-location`, together with `sfcbinst2mof` output opening in `sfcbinst2mof.c`. Version affected: `sblim-sfcb-1.4.9-36.el10` Patch available: no released package fix established; proposed patch included below Version fixed: unknown Upstream coordination: Not notified. CVSS: CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:H/A:H - 6.5 (MEDIUM) AV:L - The attacker needs local access to the host. AC:H - Exploitation requires winning a race between `rm -f` and `fopen`, plus the vulnerable migration path must be active. PR:L - A low-privileged local account is sufficient. UI:N - No separate victim interaction is needed once the privileged rebuild runs. S:U - The impact remains within the same security scope. C:N - The available evidence supports write/corruption, not unauthorized reading of protected data. I:H - Successful exploitation can append to or corrupt attacker-chosen privileged files. A:H - Corrupting privileged files can make services or the system unavailable. Impact: Moderate. Successful exploitation can compromise integrity and availability by appending to or corrupting privileged files, but the flaw is local, timing-dependent, and state-dependent: it requires privileged `sfcbrepos` execution, active instance migration, and qualifying content in `repository.previous`. That makes it less easily exploited than a typical Important-impact local privilege-escalation flaw. The available evidence does not establish direct code execution, reliable privilege escalation, or confidentiality impact. Embargo: no Reason: The issue is local, race-based, and configuration/state dependent, and the mitigation is straightforward. A normal non-embargoed fix path appears appropriate. Acknowledgement: Aisle Research Vulnerability Details: `sfcbrepos` uses a fixed pathname in the shared world-writable `/tmp` directory for migrated instance output, deletes that pathname, and then reuses it while converting legacy static instances to MOF. The same logic is present in both `sfcbrepos.sh.in` variants. ```sh instmigfile=/tmp/sfcbinst.mof ... if [ -z "$ignore_instances" ] then rm -f $instmigfile 2> /dev/null #get class names (from filenames), ignoring specific files, from repos.previous, as it's already been moved if [ -e $registrationdir/repository.previous/$namespace/ ] then static_inst_files=`ls $registrationdir/repository.previous/$namespace/ -I classSchemas -I qualifiers -I *.idx` > /dev/null 2>&1 for instfile in $static_inst_files do sfcbinst2mof -n $namespace -c $instfile -o $instmigfile -r $registrationdir/repository.previous/ -g ${DESTDIR}@sysconfdir@/sfcb/sfcb.cfg 2> /dev/null done fi fi ``` `sfcbinst2mof` then opens the attacker-controlled pathname with standard `fopen` semantics: ```c if (*outfilepath) { if (opt_truncate) fp = fopen(outfilepath, "w"); else fp = fopen(outfilepath, "a"); } ``` Because the script explicitly removes `/tmp/sfcbinst.mof` before `sfcbinst2mof` opens it, a one-time precreated symlink is not enough. The issue is the race window after `rm -f` and before `fopen`. A local attacker who recreates `/tmp/sfcbinst.mof` as a symlink during that window can redirect the privileged write into an attacker-chosen file. In the observed `sfcbrepos` path, `sfcbinst2mof` is invoked without `-t`, so the demonstrated behavior is append mode rather than reliable truncating overwrite. The established impact is therefore privileged file append/corruption and resulting denial of service. The reviewed package sources also invoke `sfcbrepos -f` from the schema subpackage `%post` scriptlet, making privileged execution a realistic package-managed path when that subpackage is installed or updated. Steps to reproduce: 1. From an unprivileged local account, continuously recreate the symlink target. For a non-destructive test, use a disposable root-owned file instead of `/etc/shadow`. ```sh while true; do ln -sfn /etc/shadow /tmp/sfcbinst.mof done ``` 2. In another shell, trigger a privileged repository rebuild without `-i`: ```sh sudo sfcbrepos -f ``` 3. Ensure the migration path is reached: `registrationdir/repository.previous/<namespace>/` must exist, and it must contain at least one file other than `classSchemas`, `qualifiers`, or `*.idx` so the `for instfile` loop runs and `sfcbinst2mof -o /tmp/sfcbinst.mof` is executed. 4. Repeat the privileged rebuild as needed until the race is won. When successful, the chosen target file is appended with MOF output from the privileged `sfcbinst2mof` process, causing corruption. Mitigation: If instance migration is not required, run `sfcbrepos` with `-i` to avoid the vulnerable `sfcbinst2mof -o /tmp/sfcbinst.mof` path. Otherwise, avoid running `sfcbrepos` with elevated privileges while untrusted local users can write concurrently to the shared `/tmp` directory. These are operational mitigations only; the root cause is the fixed temporary pathname combined with unlink-and-reopen behavior. Proposed Fix: Create the migration file securely with `mktemp`, keep it allocated for the full run instead of unlinking and recreating it, quote shell expansions, and remove it with `trap`. ```diff diff --git a/sfcbrepos.sh.in b/sfcbrepos.sh.in @@ instmigfile=/tmp/sfcbinst.mof + instmigfile="$(mktemp "${TMPDIR:-/tmp}/sfcbinst.XXXXXX.mof")" || exit 1 + chmod 600 "$instmigfile" || exit 1 + trap 'rm -f – "$instmigfile"' EXIT @@ rm -f $instmigfile 2> /dev/null + : # already securely created; do not unlink/recreate @@ sfcbinst2mof -n $namespace -c $instfile -o $instmigfile -r $registrationdir/repository.previous/ -g ${DESTDIR}@sysconfdir@/sfcb/sfcb.cfg 2> /dev/null + sfcbinst2mof -n "$namespace" -c "$instfile" -o "$instmigfile" -r "$registrationdir/repository.previous/" -g "${DESTDIR}@sysconfdir@/sfcb/sfcb.cfg" 2> /dev/null @@ rm -f $instmigfile 2> /dev/null + rm -f – "$instmigfile" 2> /dev/null diff --git a/sfcbrepos.sh.in.sfcbrepos-schema-location b/sfcbrepos.sh.in.sfcbrepos-schema-location @@ instmigfile=/tmp/sfcbinst.mof + instmigfile="$(mktemp "${TMPDIR:-/tmp}/sfcbinst.XXXXXX.mof")" || exit 1 + chmod 600 "$instmigfile" || exit 1 + trap 'rm -f – "$instmigfile"' EXIT @@ rm -f $instmigfile 2> /dev/null + : # already securely created; do not unlink/recreate @@ sfcbinst2mof -n $namespace -c $instfile -o $instmigfile -r $registrationdir/repository.previous/ -g ${DESTDIR}@sysconfdir@/sfcb/sfcb.cfg 2> /dev/null + sfcbinst2mof -n "$namespace" -c "$instfile" -o "$instmigfile" -r "$registrationdir/repository.previous/" -g "${DESTDIR}@sysconfdir@/sfcb/sfcb.cfg" 2> /dev/null @@ rm -f $instmigfile 2> /dev/null + rm -f – "$instmigfile" 2> /dev/null ``` ------ This report was generated using AI technology. Always review AI-generated content prior to use