Skip to content

Comments

Fix crash on module unload when ACL includes module commands; clean stale ACL rules and harden recompute#2916

Closed
sachinvmurthy wants to merge 1 commit intovalkey-io:7.2from
sachinvmurthy:bug/issue_2797
Closed

Fix crash on module unload when ACL includes module commands; clean stale ACL rules and harden recompute#2916
sachinvmurthy wants to merge 1 commit intovalkey-io:7.2from
sachinvmurthy:bug/issue_2797

Conversation

@sachinvmurthy
Copy link
Contributor

Problem:

Unloading a module crashes if any ACL user has rules referencing that module’s commands or subcommands (e.g., +hello.simple). The crash occurs in ACLRecomputeCommandBitsFromCommandRulesAllUsers while applying stale rules; previously it asserted on failure.

Root Cause:
Stale ACL command rules persist in users’ selectors after module unload. Recompute attempts to reapply them, resulting in invalid lookups or assertions.

Fix:
Add ACLCleanupStaleCommandRulesAllUsers to proactively remove non-existent module commands/subcommands from selector->command_rules.
Make ACLRecomputeCommandBitsFromCommandRulesAllUsers skip invalid rules with a warning instead of asserting.

@roshkhatri
Copy link
Member

roshkhatri commented Dec 5, 2025

Thanks @sachinvmurthy for working on this, Can you please address these issues:

  1. Can you please push the commits with `--signoff', so the DCO passes?
  2. Can you please add some tests for this?
  3. The PR needs be made to the 'unstable' branch

/* Body after +/- */
const char *body = tok+1;
if (*body == '@') {
/* Category: always keep */
Copy link
Member

Choose a reason for hiding this comment

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

Modules can register new ACL categories, I suppose we should clean them up too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It does not crash on the categories so do we need to unregister them too?

/* Command or subcommand. Extract main and optional sub after '|' */
const char *pipe = strchr(body, '|');
sds main = pipe ? sdsnewlen(body, pipe - body) : sdsnew(body);
struct redisCommand *cmd = dictFetchValue(server.orig_commands, main);
Copy link
Member

Choose a reason for hiding this comment

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

Lets create this PR to unstable branch, now this struct is called serverCommand and wouldn't it be better to use struct serverCommand *lookupCommand(robj **argv, int argc)?

@sachinvmurthy
Copy link
Contributor Author

closing this PR since it needs to be raised against unstable.

NEW PR - #2923

@sachinvmurthy sachinvmurthy deleted the bug/issue_2797 branch December 9, 2025 21:43
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.

3 participants