Report exact dbid for COPY in ACL LOG when db= access is denied - #3888
Conversation
Extend commandDbIdArgs with an out-parameter that returns the argv index of each reported dbid, and use it in ACLSelectorCheckCmd instead of the cmd->proc-based offset table, so we don't need to maintain the whole block, just need to maintain get_dbid_args. The fix is for COPY: the old chain fell through to 0, so the "object" field in ACL LOG was always showed "copy", it now reports the first denied dbid. Also see valkey-io#3801 for more details, DB ACL was added in valkey-io#2309. Signed-off-by: Binbin <binloveplay1314@qq.com>
📝 WalkthroughWalkthroughHelpers now return argv-index positions for DB-id tokens; callers (ACL checks and MULTI) read dbids via those positions and set key/index reporting from the offending argument position. Tests updated to assert the reported db argument value is included in DRYRUN errors and ACL LOG entries. ChangesACL Database ID Position Tracking
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/server.h (1)
2554-2554: ⚡ Quick winConsider documenting the typedef parameters, especially the new
positionsout-parameter.The
commandDbIdArgstypedef signature has been extended with a new out-parameter, but there's no documentation explaining:
- The purpose of the
positionsparameter- Whether
positionscan be NULL (appears optional based on PR context)- Memory ownership (who allocates, who frees the returned array)
- The relationship between
countand thepositionsarray size📝 Suggested documentation
+/* Helper function to get database ID arguments from a command. + * Returns an array of database IDs, with count set to the number of IDs. + * If positions is non-NULL, it will be set to a newly allocated array + * containing the argv index of each database ID (caller must free). + * Returns NULL if the command has no database ID arguments. */ typedef int *commandDbIdArgs(robj **argv, int argc, int *count, int **positions);As per coding guidelines: "Document why code exists, not just what it does; document all functions in C code"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/server.h` at line 2554, Add a header comment above the typedef commandDbIdArgs that documents each parameter: explain that argv/argc are the command arguments, count is an out-parameter returning the number of DB-IDs found, and positions is an optional out-parameter that, when non-NULL, will be set to point to an array of integer positions (size equal to *count) indicating where DB-ID arguments were found; state whether positions may be NULL, who allocates the returned positions array (caller or callee), and who is responsible for freeing it, and clarify the relationship between count and the positions array length. Make the wording explicit and follow the file's existing C-doc style so callers know allocation/ownership and nullability semantics for commandDbIdArgs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@src/server.h`:
- Line 2554: Add a header comment above the typedef commandDbIdArgs that
documents each parameter: explain that argv/argc are the command arguments,
count is an out-parameter returning the number of DB-IDs found, and positions is
an optional out-parameter that, when non-NULL, will be set to point to an array
of integer positions (size equal to *count) indicating where DB-ID arguments
were found; state whether positions may be NULL, who allocates the returned
positions array (caller or callee), and who is responsible for freeing it, and
clarify the relationship between count and the positions array length. Make the
wording explicit and follow the file's existing C-doc style so callers know
allocation/ownership and nullability semantics for commandDbIdArgs.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: b7cb4114-eb5f-42f1-a283-10ac3852df05
📒 Files selected for processing (5)
src/acl.csrc/db.csrc/multi.csrc/server.htests/unit/acl-v2.tcl
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## unstable #3888 +/- ##
============================================
+ Coverage 76.66% 76.70% +0.03%
============================================
Files 162 162
Lines 80728 80731 +3
============================================
+ Hits 61893 61922 +29
+ Misses 18835 18809 -26
🚀 New features to boost your workflow:
|
Rework commandDbIdArgs so each helper returns the argv index of every dbid
argument it owns. ACLSelectorCheckCmd uses those positions to set keyidxptr
directly, replacing the cmd->proc-based offset table. The caller now reads
the dbid value via getLongLongFromObject(argv[positions[i]], ...). New
db=-checked commands only need to implement their own *DbIdArgs helper.
The fix is for COPY: the old chain fell through to 0, so the "object"
field in ACL LOG was always showed "copy", it now reports the first
denied dbid.
Based on #3801, also see it for more details, DB ACL was added in #2309.