acl: bitfield with get and set|incrby can be executed with readonly permission (#11086)

`bitfield` with `get` may not be readonly.

```
127.0.0.1:6384> acl setuser hello on nopass %R~* +@all
OK
127.0.0.1:6384> auth hello 1
OK
127.0.0.1:6384> bitfield hello set i8 0 1
(error) NOPERM this user has no permissions to access one of the keys used as arguments
127.0.0.1:6384> bitfield hello set i8 0 1 get i8 0
1) (integer) 0
2) (integer) 1
```

Co-authored-by: Oran Agra <oran@redislabs.com>
This commit is contained in:
Huang Zhw 2022-08-07 14:21:19 +08:00 committed by GitHub
parent 7d8911d22a
commit ec5034a2e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 17 additions and 3 deletions

View File

@ -2389,6 +2389,7 @@ int setGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *r
* read-only if the BITFIELD GET subcommand is used. */
int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResult *result) {
keyReference *keys;
int readonly = 1;
UNUSED(cmd);
keys = getKeysPrepareResult(result, 1);
@ -2399,11 +2400,23 @@ int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResu
int remargs = argc - i - 1; /* Remaining args other than current. */
char *arg = argv[i]->ptr;
if (!strcasecmp(arg, "get") && remargs >= 2) {
keys[0].flags = CMD_KEY_RO | CMD_KEY_ACCESS;
return 1;
i += 2;
} else if ((!strcasecmp(arg, "set") || !strcasecmp(arg, "incrby")) && remargs >= 3) {
readonly = 0;
i += 3;
break;
} else if (!strcasecmp(arg, "overflow") && remargs >= 1) {
i += 1;
} else {
readonly = 0; /* Syntax error. safer to assume non-RO. */
break;
}
}
keys[0].flags = CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_UPDATE;
if (readonly) {
keys[0].flags = CMD_KEY_RO | CMD_KEY_ACCESS;
} else {
keys[0].flags = CMD_KEY_RW | CMD_KEY_ACCESS | CMD_KEY_UPDATE;
}
return 1;
}

View File

@ -195,6 +195,7 @@ start_server {tags {"acl external:skip"}} {
# We don't have the permission to WRITE key.
assert_error {*NOPERM*keys*} {$r2 bitfield readstr set u4 0 1}
assert_error {*NOPERM*keys*} {$r2 bitfield readstr get u4 0 set u4 0 1}
assert_error {*NOPERM*keys*} {$r2 bitfield readstr incrby u4 0 1}
}