Skip to content

Commit

Permalink
Integer Overflow in RAND commands can lead to assertion (CVE-2023-25155)
Browse files Browse the repository at this point in the history
Issue happens when passing a negative long value that greater than
the max positive value that the long can store.
  • Loading branch information
oranagra committed Feb 28, 2023
1 parent 0825552 commit 2a2a582
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 5 deletions.
4 changes: 2 additions & 2 deletions src/t_hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -1120,13 +1120,13 @@ void hrandfieldCommand(client *c) {
listpackEntry ele;

if (c->argc >= 3) {
if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr,"withvalues"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withvalues = 1;
if (l < LONG_MIN/2 || l > LONG_MAX/2) {
if (l < -LONG_MAX/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
Expand Down
2 changes: 1 addition & 1 deletion src/t_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ void srandmemberWithCountCommand(client *c) {

dict *d;

if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (l >= 0) {
count = (unsigned long) l;
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/t_zset.c
Original file line number Diff line number Diff line change
Expand Up @@ -4289,13 +4289,13 @@ void zrandmemberCommand(client *c) {
listpackEntry ele;

if (c->argc >= 3) {
if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr,"withscores"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withscores = 1;
if (l < LONG_MIN/2 || l > LONG_MAX/2) {
if (l < -LONG_MAX/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/type/hash.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ start_server {tags {"hash"}} {
test "HRANDFIELD count overflow" {
r hmset myhash a 1
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854770000 withvalues}
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808 withvalues}
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808}
} {}

test "HRANDFIELD with <count> against non existing key" {
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/type/set.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -645,6 +645,11 @@ start_server {
r srandmember nonexisting_key 100
} {}

test "SRANDMEMBER count overflow" {
r sadd myset a
assert_error {*value is out of range*} {r srandmember myset -9223372036854775808}
} {}

# Make sure we can distinguish between an empty array and a null response
r readraw 1

Expand Down
2 changes: 2 additions & 0 deletions tests/unit/type/zset.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -2303,6 +2303,8 @@ start_server {tags {"zset"}} {
test "ZRANDMEMBER count overflow" {
r zadd myzset 0 a
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854770000 withscores}
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808 withscores}
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808}
} {}

# Make sure we can distinguish between an empty array and a null response
Expand Down

0 comments on commit 2a2a582

Please sign in to comment.