Skip to content

fix: add FIFO validation to prevent arbitrary file writes#320

Merged
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
xujin177:bugfix/PMS-370161
Jul 23, 2026
Merged

fix: add FIFO validation to prevent arbitrary file writes#320
deepin-bot[bot] merged 1 commit into
linuxdeepin:masterfrom
xujin177:bugfix/PMS-370161

Conversation

@xujin177

@xujin177 xujin177 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Added sys/stat.h include and FIFO type verification for file descriptors and paths used in FIFO-based interprocess communication. The fix ensures only valid FIFO files are opened for writing, preventing security vulnerabilities where arbitrary file paths could be used to write to unintended locations. This addresses potential issues with --notify-fifo and --fd1/--fd2 arguments where the provided path or file descriptor might not be a FIFO, mitigating the risk of unauthorized file writes.

Influence:

  1. Test FIFO notification system with valid FIFO paths
  2. Verify FIFO validation with regular files instead of FIFOs
  3. Test with non-existent paths to ensure proper error handling
  4. Verify security loader helper arguments (--fd1, --fd2) with valid FIFOs
  5. Test with invalid file types (sockets, regular files) passed as FIFO arguments
  6. Verify error logging and graceful handling when invalid paths/fds are detected

fix: 添加FIFO验证以防止任意文件写入

添加了sys/stat.h头文件,并对FIFO通信中使用的文件描述符和路径进行了FIFO
类型验证。此修复确保只打开有效的FIFO文件进行写入,防止因提供任意文件路径
而写入未预期位置的潜在安全漏洞。解决了--notify-fifo--fd1/--fd2参 数可能指向非FIFO文件的问题,降低了未经授权文件写入的风险。

Influence:

  1. 使用有效的FIFO路径测试FIFO通知系统
  2. 使用普通文件替代FIFO验证FIFO类型检查
  3. 测试不存在的路径以确保正确处理错误
  4. 使用有效FIFO验证安全加载器助手参数(--fd1, --fd2)
  5. 测试将无效文件类型(套接字、普通文件)作为FIFO参数传递的情况
  6. 验证检测到无效路径/文件描述符时的错误记录和优雅处理

PMS: TASK-393165

Summary by Sourcery

Add FIFO type validation for security loader helper file descriptors and notify FIFO paths to prevent arbitrary file writes.

Bug Fixes:

  • Ensure security loader helper only accepts FIFO file descriptors for --fd1/--fd2, ignoring non-FIFO fds.
  • Validate notify FIFO paths before opening so that only FIFOs are used, avoiding unintended writes to arbitrary files.

Enhancements:

  • Improve logging when invalid FIFO file descriptors or paths are detected during update helper and notifier initialization.

@deepin-ci-robot

Copy link
Copy Markdown

Hi @xujin177. Thanks for your PR.

I'm waiting for a linuxdeepin member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@sourcery-ai

sourcery-ai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds FIFO type validation for file descriptors and paths used for interprocess communication to prevent arbitrary file writes via --notify-fifo and security loader helper arguments, logging and ignoring invalid FIFOs while preserving existing behavior for valid ones.

Sequence diagram for FIFO validation in SecurityLoaderHelper::parseLoaderArgs

sequenceDiagram
    actor LoaderProcess
    participant SecurityLoaderHelper
    participant Kernel

    LoaderProcess->>SecurityLoaderHelper: parseLoaderArgs(argc, argv)
    loop args
        SecurityLoaderHelper-->>SecurityLoaderHelper: parse --fd1 / --fd2
        alt fd1 provided
            SecurityLoaderHelper->>Kernel: fstat(fd1, st)
            alt S_ISFIFO(st.st_mode)
                SecurityLoaderHelper-->>LoaderProcess: info.fd1 set to fd1
            else not FIFO or fstat error
                SecurityLoaderHelper-->>LoaderProcess: info.fd1 set to -1
            end
        else fd2 provided
            SecurityLoaderHelper->>Kernel: fstat(fd2, st)
            alt S_ISFIFO(st.st_mode)
                SecurityLoaderHelper-->>LoaderProcess: info.fd2 set to fd2
            else not FIFO or fstat error
                SecurityLoaderHelper-->>LoaderProcess: info.fd2 set to -1
            end
        end
    end
Loading

Sequence diagram for FIFO validation in FifoNotifier reportPid and notify

sequenceDiagram
    actor WrapperScript
    participant FifoNotifier
    participant Kernel

    WrapperScript->>FifoNotifier: reportPid()
    alt m_path is empty
        FifoNotifier-->>WrapperScript: return
    else m_path set via --notify-fifo
        FifoNotifier->>Kernel: stat(m_path, st)
        alt S_ISFIFO(st.st_mode)
            FifoNotifier->>Kernel: open(m_path, O_WRONLY | O_NONBLOCK)
            FifoNotifier-->>WrapperScript: write PID to FIFO
        else not FIFO or stat error
            FifoNotifier-->>WrapperScript: log warning and return
        end
    end

    WrapperScript->>FifoNotifier: notify()
    alt m_path is empty
        FifoNotifier-->>WrapperScript: return
    else m_path set via --notify-fifo
        FifoNotifier->>Kernel: stat(m_path, st)
        alt S_ISFIFO(st.st_mode)
            FifoNotifier->>Kernel: open(m_path, O_WRONLY | O_NONBLOCK)
            FifoNotifier-->>WrapperScript: write notification to FIFO
        else not FIFO or stat error
            FifoNotifier-->>WrapperScript: log warning and return
        end
    end
Loading

File-Level Changes

Change Details Files
Validate --fd1/--fd2 file descriptors are FIFOs before use in SecurityLoaderHelper::parseLoaderArgs.
  • Include sys/stat.h to access stat-related APIs and FIFO macros.
  • After parsing --fd1, call fstat on the resulting descriptor and verify S_ISFIFO; on failure or non-FIFO, log a warning, reset fd1 to -1, and skip using it.
  • Apply the same fstat + S_ISFIFO validation flow for --fd2, logging a warning and resetting fd2 to -1 when invalid.
src/dde-update/securityloaderhelper.cpp
Validate --notify-fifo paths are FIFOs before opening them in FifoNotifier to avoid arbitrary file writes.
  • Include sys/stat.h in main.cpp for stat/S_ISFIFO usage.
  • In FifoNotifier::reportPid, before open(), call stat on m_path and require S_ISFIFO; log a warning and return early if stat fails or the path is not a FIFO.
  • In FifoNotifier::notify, similarly stat m_path and require S_ISFIFO before open(); log a warning and return early on invalid or non-FIFO paths.
src/dde-update/main.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • The FIFO type checks for --fd1 and --fd2 are duplicated; consider extracting a small helper (e.g., bool isFifoFd(int fd)) to reduce repetition and make the intent clearer.
  • Within FifoNotifier, the stat/S_ISFIFO logic is duplicated in both reportPid and notify; factoring this into a shared private method would simplify maintenance and keep behavior consistent.
  • The stat + open sequence introduces a small TOCTOU window; if feasible, consider validating the FIFO property on an already-open descriptor (or immediately after open) to tighten the check, even if the practical risk is low here.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The FIFO type checks for `--fd1` and `--fd2` are duplicated; consider extracting a small helper (e.g., `bool isFifoFd(int fd)`) to reduce repetition and make the intent clearer.
- Within `FifoNotifier`, the `stat`/`S_ISFIFO` logic is duplicated in both `reportPid` and `notify`; factoring this into a shared private method would simplify maintenance and keep behavior consistent.
- The `stat` + `open` sequence introduces a small TOCTOU window; if feasible, consider validating the FIFO property on an already-open descriptor (or immediately after `open`) to tighten the check, even if the practical risk is low here.

## Individual Comments

### Comment 1
<location path="src/dde-update/securityloaderhelper.cpp" line_range="68-76" />
<code_context>
             }
             info.fd1 = static_cast<int>(fd);
             info.isLoadedByLoader = true;
+            // Verify the fd is actually a FIFO to prevent writing
+            // authorization data to arbitrary open files.
+            struct stat st;
+            if (fstat(info.fd1, &st) != 0 || !S_ISFIFO(st.st_mode)) {
+                qWarning() << "fd1 is not a FIFO, ignoring";
+                info.fd1 = -1;
+                continue;
+            }
         } else if (strcmp(argv[i], "--fd2") == 0 && i + 1 < argc) {
</code_context>
<issue_to_address>
**issue (bug_risk):** Clarify behavior of isLoadedByLoader when all validated fds end up rejected

In the `fd1` branch, `info.isLoadedByLoader` is set before the FIFO validation. If `fstat` fails or the fd is not a FIFO, `info.fd1` is reset to `-1` and we `continue`, but `isLoadedByLoader` remains `true`. If both `fd1` and `fd2` are rejected, you can end up with `isLoadedByLoader == true` and both fds invalid. Please either set `isLoadedByLoader` only after successful FIFO validation, or make sure downstream code correctly handles the case where `isLoadedByLoader` is `true` but `fd1`/`fd2` are `-1`.
</issue_to_address>

### Comment 2
<location path="src/dde-update/main.cpp" line_range="90-98" />
<code_context>
         if (m_path.isEmpty()) {
             return;
         }
+        // Verify the path is actually a FIFO before opening,
+        // preventing arbitrary file writes via --notify-fifo.
+        struct stat st;
+        if (stat(m_path.toUtf8().constData(), &st) != 0 || !S_ISFIFO(st.st_mode)) {
+            qCWarning(logUpdateModal) << "FifoNotifier: path is not a FIFO, cannot report PID";
+            return;
+        }
         // Write our PID so the wrapper can track this exact process via kill -0.
         int fd = open(m_path.toUtf8().constData(), O_WRONLY | O_NONBLOCK);
         if (fd < 0) {
</code_context>
<issue_to_address>
**🚨 issue (security):** Address TOCTOU window between stat() and open() when validating FIFO paths

Calling `stat(m_path...)` before `open(m_path...)` creates a TOCTOU race: the path can be changed between the check and the open, defeating the protection against arbitrary file writes via `--notify-fifo`. Instead, `open()` first with `O_NONBLOCK`, then `fstat()` the fd to verify it is a FIFO, and close it if the check fails. Apply the same pattern in `notify()`, which currently has the same issue.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread src/dde-update/securityloaderhelper.cpp
Comment thread src/dde-update/main.cpp Outdated
@xujin177
xujin177 force-pushed the bugfix/PMS-370161 branch from dce91fe to 9ae50ec Compare July 23, 2026 06:20
Added `sys/stat.h` include and FIFO type verification for file
descriptors and paths used in FIFO-based interprocess communication.
The fix ensures only valid FIFO files are opened for writing, preventing
security vulnerabilities where arbitrary file paths could be used to
write to unintended locations. This addresses potential issues with
`--notify-fifo` and `--fd1`/`--fd2` arguments where the provided path or
file descriptor might not be a FIFO, mitigating the risk of unauthorized
file writes.

Influence:
1. Test FIFO notification system with valid FIFO paths
2. Verify FIFO validation with regular files instead of FIFOs
3. Test with non-existent paths to ensure proper error handling
4. Verify security loader helper arguments (`--fd1`, `--fd2`) with valid
FIFOs
5. Test with invalid file types (sockets, regular files) passed as FIFO
arguments
6. Verify error logging and graceful handling when invalid paths/fds
are detected

fix: 添加FIFO验证以防止任意文件写入

添加了`sys/stat.h`头文件,并对FIFO通信中使用的文件描述符和路径进行了FIFO
类型验证。此修复确保只打开有效的FIFO文件进行写入,防止因提供任意文件路径
而写入未预期位置的潜在安全漏洞。解决了`--notify-fifo`和`--fd1`/`--fd2`参
数可能指向非FIFO文件的问题,降低了未经授权文件写入的风险。

Influence:
1. 使用有效的FIFO路径测试FIFO通知系统
2. 使用普通文件替代FIFO验证FIFO类型检查
3. 测试不存在的路径以确保正确处理错误
4. 使用有效FIFO验证安全加载器助手参数(`--fd1`, `--fd2`)
5. 测试将无效文件类型(套接字、普通文件)作为FIFO参数传递的情况
6. 验证检测到无效路径/文件描述符时的错误记录和优雅处理

PMS: TASK-393165
@xujin177
xujin177 force-pushed the bugfix/PMS-370161 branch from 9ae50ec to c1e6bb6 Compare July 23, 2026 06:23
@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: waterlovemelon, xujin177

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@xujin177

Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot
deepin-bot Bot merged commit 6436f0f into linuxdeepin:master Jul 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants