Skip to content

grammar: handle symlinked include entries#166

Open
rgerhards wants to merge 2 commits intomainfrom
codex/fix-issue-#6517-in-rsyslog
Open

grammar: handle symlinked include entries#166
rgerhards wants to merge 2 commits intomainfrom
codex/fix-issue-#6517-in-rsyslog

Conversation

@rgerhards
Copy link
Owner

Motivation

Description

  • Updated grammar/rainerscript.c (cnfDoInclude) to use lstat() on matched paths so symlink entries are detected.
  • When an entry is a symlink, the code now resolves the target with stat() and classifies the target as a regular file or directory before inclusion.
  • Preserved existing error and optional-file handling and the include ordering semantics.
  • Modified file: grammar/rainerscript.c.

Testing

  • Ran code formatting via devtools/format-code.sh, which completed successfully.
  • Attempted make -j$(nproc) check TESTS="" in this environment and it failed because there is no check make target here (no full build/test run available).
  • Static checks (searches and file inspection) were used to validate the inserted logic locally.

Codex Task

Why: operators use symlinked config snippets and expect them

to be treated like regular config paths.

Impact: include processing now resolves symlink metadata before

classification.

Before/After: before, symlinked include entries could be

rejected on some platforms; after, they resolve and parse

like regular files.

Technical Overview:

- use lstat to detect symlink entries during IncludeConfig

  expansion

- resolve symlink targets with stat for file vs directory

  classification

- preserve existing error handling for missing optional files

- keep include order semantics unchanged

Refs: rsyslog#6517

With the help of AI-Agents: ChatGPT
@gemini-code-assist
Copy link

Summary of Changes

Hello @rgerhards, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request resolves a critical issue in rsyslog where the $IncludeConfig directive failed to properly handle symbolic links, leading to configuration loading failures. The changes introduce robust symbolic link detection and resolution within the configuration inclusion logic, ensuring that rsyslog can now seamlessly process configurations that utilize symlinked files or directories without interruption.

Highlights

  • Symbolic Link Handling: The $IncludeConfig directive in rsyslog now correctly processes symbolic links, resolving an issue where configurations using symlinked snippets would cause rsyslog to abort.
  • File Information Retrieval: The cnfDoInclude function in grammar/rainerscript.c has been updated to use lstat() to detect symbolic links and then stat() to retrieve information about the actual target file or directory.
  • Error Handling and Semantics: Existing error handling, optional-file processing, and include ordering semantics have been preserved during the implementation of symlink resolution.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • grammar/rainerscript.c
    • Added a new struct stat linkInfo; variable to store information specifically about the symbolic link itself.
    • Modified the file information retrieval from stat(cfgFile, &fileInfo) to lstat(cfgFile, &linkInfo) to correctly identify symbolic links.
    • Introduced conditional logic to check if the path is a symbolic link (S_ISLNK). If it is, stat(cfgFile, &fileInfo) is then called to get the status of the link's target. Otherwise, fileInfo is directly assigned linkInfo.
Activity
  • Code formatting was successfully applied using devtools/format-code.sh.
  • A full build and test run (make -j$(nproc) check TESTS="") could not be performed due to the absence of a check make target in the environment.
  • Local validation of the inserted logic was performed through static checks, searches, and file inspection.
  • This task was initiated via a Codex Task link.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds support for symbolic links in $IncludeConfig paths, which is a good improvement. The implementation correctly uses lstat and stat to handle symlinks.

My main feedback is about an error handling logic bug. When an optional include fails (e.g., a broken symlink), the current implementation aborts processing all subsequent include files silently. This can lead to unexpected behavior and hard-to-debug configuration issues. I've suggested a fix to continue to the next file in such cases, which is the expected behavior for optional includes.

Comment on lines +5738 to +5749
if (stat(cfgFile, &fileInfo) != 0) {
if (optional == 0) {
rs_strerror_r(errno, errStr, sizeof(errStr));
if (getcwd(cwdBuf, sizeof(cwdBuf)) == NULL) strcpy(cwdBuf, "??getcwd() failed??");
parser_errmsg(
"error accessing config file or directory '%s' "
"[cwd: %s]: %s",
cfgFile, cwdBuf, errStr);
ret = 1;
}
goto done;
}

Choose a reason for hiding this comment

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

high

There's a logic bug here. If stat() fails for an optional include (e.g., a broken symlink), the goto done; will cause the function to exit prematurely, silently skipping the rest of the include files. For optional includes, it should continue to the next file in the loop instead of aborting the entire include process.

This logic is copied from the lstat error handling a few lines above, which has the same issue. While a larger refactoring could address the code duplication, fixing this bug in the new code is important.

            if (stat(cfgFile, &fileInfo) != 0) {
                if (optional == 0) {
                    rs_strerror_r(errno, errStr, sizeof(errStr));
                    if (getcwd(cwdBuf, sizeof(cwdBuf)) == NULL) strcpy(cwdBuf, "??getcwd() failed??");
                    parser_errmsg(
                        "error accessing config file or directory '%s' "
                        "[cwd: %s]: %s",
                        cfgFile, cwdBuf, errStr);
                    ret = 1;
                    goto done;
                }
                continue;
            }

### Motivation
- Include processing failed to handle symbolic links when expanding `$IncludeConfig` paths, causing rsyslog to abort on setups that use symlinked config snippets (see rsyslog#6517).

### Description
- Updated `grammar/rainerscript.c` (`cnfDoInclude`) to use `lstat()` on matched paths so symlink entries are detected.
- When an entry is a symlink, the code now resolves the target with `stat()` and classifies the target as a regular file or directory before inclusion.
- Preserved existing error and optional-file handling and the include ordering semantics.
- Modified file: `grammar/rainerscript.c`.

### Testing
- Ran code formatting via `devtools/format-code.sh`, which completed successfully.
- Attempted `make -j$(nproc) check TESTS=""` in this environment and it failed because there is no `check` make target here (no full build/test run available).
- Static checks (searches and file inspection) were used to validate the inserted logic locally.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant