Skip to content

fix: correct errors.Is argument order in unloadProfile#66

Open
tuxerrante wants to merge 1 commit into
mainfrom
fix/errors-is-argument-order
Open

fix: correct errors.Is argument order in unloadProfile#66
tuxerrante wants to merge 1 commit into
mainfrom
fix/errors-is-argument-order

Conversation

@tuxerrante
Copy link
Copy Markdown
Owner

Summary

  • Fix swapped errors.Is() arguments in unloadProfile(): errors.Is(os.ErrNotExist, err)errors.Is(err, os.ErrNotExist)
  • The reversed arguments caused the file-existence guard to never trigger, making unloadProfile always proceed even when the profile file doesn't exist on disk

Security Impact

Severity: Medium-High — In a privileged DaemonSet managing kernel AppArmor profiles:

  • During graceful shutdown, apparmor_parser --remove was invoked on non-existent files
  • Failed unloads could leave stale profiles loaded in the kernel (fail-open condition)
  • Relates to threat model T14 (TOCTOU) and general shutdown reliability

Test plan

  • Verified no other instances of this bug exist in the codebase (errors.Is(os.Err*, err) pattern)
  • Confirmed all other errors.Is calls use the correct argument order
  • Existing TestUnloadProfile tests cover the corrected path
  • CI passes (golangci-lint, unit tests, CodeQL)

Made with Cursor

The arguments to errors.Is() were swapped: errors.Is(os.ErrNotExist, err)
instead of errors.Is(err, os.ErrNotExist). This caused the file-existence
guard to never trigger, making unloadProfile always proceed even when the
profile file does not exist on disk.

This is security-relevant: during graceful shutdown, apparmor_parser --remove
was invoked on non-existent files, potentially leaving stale profiles loaded
in the kernel.

Made-with: Cursor
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a logic bug in unloadProfile() where errors.Is() was called with swapped arguments, preventing the “file does not exist” guard from ever triggering during profile unload.

Changes:

  • Correct errors.Is(os.ErrNotExist, err) to errors.Is(err, os.ErrNotExist) in unloadProfile().
  • Ensure unloadProfile() properly no-ops when the profile file is missing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/app/main.go
Comment on lines +297 to 300
if _, err := os.Stat(filePath); errors.Is(err, os.ErrNotExist) {
slog.Default().Info("Profile file does not exist, skipping unload", slog.String("profile", filePath))

return nil // Nothing to do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants