diff options
author | Huang Zhw <huang_zhw@126.com> | 2022-08-07 14:21:19 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-07 09:21:19 +0300 |
commit | ec5034a2e3349235aa7142cfcc8333d21df755ce (patch) | |
tree | 5749d7176fc8688b1552e7937ff7d23a1b0aba0a /src/db.c | |
parent | 7d8911d22a588c78098e2df080d954cc889d5529 (diff) | |
download | redis-ec5034a2e3349235aa7142cfcc8333d21df755ce.tar.gz |
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>
Diffstat (limited to 'src/db.c')
-rw-r--r-- | src/db.c | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -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; } |