Fix crash unloading module referenced by ACL rules#2923
Fix crash unloading module referenced by ACL rules#2923sachinvmurthy wants to merge 3 commits intovalkey-io:unstablefrom
Conversation
f0a86d9 to
a575173
Compare
|
cc: @roshkhatri @dmitrypol @dvkashapov Thanks for reviewing the earlier PR. Created a new PR against unstable as addressed in the old PR. |
f086df4 to
1f2b77e
Compare
src/acl.c
Outdated
| const char *sub = pipe + 1; | ||
| if (cmd->subcommands_ht) { | ||
| sds sub_sds = sdsnew(sub); | ||
| struct serverCommand *sc = (struct serverCommand *)dictFetchValue(cmd->subcommands_ht, sub_sds); |
There was a problem hiding this comment.
The command table uses hashtable instead of dict in 8.1 and later. That seems to be why the build is failing.
We probably need this code with dict when we backport the fix to 8.0 and 7.2 though.
There was a problem hiding this comment.
... or would it work to use lookupCommandBySdsLogic here?
UNTESTED:
| struct serverCommand *sc = (struct serverCommand *)dictFetchValue(cmd->subcommands_ht, sub_sds); | |
| struct serverCommand *sc = lookupCommandBySdsLogic(cmd->subcommands_ht, sub_sds); |
There was a problem hiding this comment.
ah okay! thank you. will try and see if that helps
| /* Get a command from the original command table, that is not affected | ||
| * by the command renaming operations: we base all the ACL work from that | ||
| * table, so that ACLs are valid regardless of command renaming. */ | ||
| static struct serverCommand *ACLLookupCommand(const char *name) { |
There was a problem hiding this comment.
If you add the new function below this existing function, there is no need to move the existing function ACLLookupCommand within the file. We can minimize the diff, the git history footprint.
rjd15372
left a comment
There was a problem hiding this comment.
LGTM. I'm approving the PR but make sure to address @zuiderkwast comments.
roshkhatri
left a comment
There was a problem hiding this comment.
I agree with @zuiderkwast 's review. Overall looks good.
src/acl.c
Outdated
| if (first != '+' && first != '-') { | ||
| /* Unknown formatting, keep as-is */ | ||
| new_rules = sdscatfmt(new_rules, "%S ", tok); | ||
| continue; |
There was a problem hiding this comment.
What are the unknown formatting are we looking at here?
There was a problem hiding this comment.
just wanted to cover all edge cases.
1f2b77e to
c47e846
Compare
Signed-off-by: sachinvmurthy <sachin.murthy97@gmail.com>
Signed-off-by: sachinvmurthy <sachin.murthy97@gmail.com>
Signed-off-by: sachinvmurthy <sachin.murthy97@gmail.com>
c47e846 to
e5d3201
Compare
| aclSelector *selector = (aclSelector *) listNodeValue(ln); | ||
| int argc = 0; | ||
| sds *argv = sdssplitargs(selector->command_rules, &argc); | ||
| if (!argv) continue; |
There was a problem hiding this comment.
Can we atleast add a warning here while continuing, if sdssplitargs() fails for any reason?
| } else { | ||
| sdsfree(selector->command_rules); | ||
| selector->command_rules = sdsempty(); | ||
| sdsfree(new_rules); |
There was a problem hiding this comment.
How can we make sure the new rules are parsable? is there a small check we can add?
|
After discussion in the meeting today, it was decided to not edit the command rules and reject unloading of the module until ACLs are cleaned by the user |
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.
Fixes #2797
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.