Debug Populate: Avoid server crash when passing negative value for key and value size (#8018)

* Debug Populate: Add checks for count and keysize to avoid crash

* provide getRangeLongFromObjectOrReply and getPositiveLongFromObjectOrReply for range check
This commit is contained in:
Wen Hui 2020-11-05 12:58:54 -05:00 committed by GitHub
parent 7e4325cbc9
commit 254367788a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 23 additions and 2 deletions

View File

@ -600,12 +600,14 @@ NULL
robj *key, *val;
char buf[128];
if (getLongFromObjectOrReply(c, c->argv[2], &keys, NULL) != C_OK)
if (getPositiveLongFromObjectOrReply(c, c->argv[2], &keys, NULL) != C_OK)
return;
dictExpand(c->db->dict,keys);
long valsize = 0;
if ( c->argc == 5 && getLongFromObjectOrReply(c, c->argv[4], &valsize, NULL) != C_OK )
if ( c->argc == 5 && getPositiveLongFromObjectOrReply(c, c->argv[4], &valsize, NULL) != C_OK )
return;
for (j = 0; j < keys; j++) {
snprintf(buf,sizeof(buf),"%s:%lu",
(c->argc == 3) ? "key" : (char*)c->argv[3]->ptr, j);

View File

@ -730,6 +730,23 @@ int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg)
return C_OK;
}
int getRangeLongFromObjectOrReply(client *c, robj *o, long min, long max, long *target, const char *msg) {
if (getLongFromObjectOrReply(c, o, target, msg) != C_OK) return C_ERR;
if (*target < min || *target > max) {
if (msg != NULL) {
addReplyError(c,(char*)msg);
} else {
addReplyErrorFormat(c,"value is out of range, value must between %ld and %ld", min, max);
}
return C_ERR;
}
return C_OK;
}
int getPositiveLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg) {
return getRangeLongFromObjectOrReply(c, o, 0, LONG_MAX, target, msg);
}
char *strEncoding(int encoding) {
switch(encoding) {
case OBJ_ENCODING_RAW: return "raw";

View File

@ -1838,6 +1838,8 @@ robj *createZsetZiplistObject(void);
robj *createStreamObject(void);
robj *createModuleObject(moduleType *mt, void *value);
int getLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg);
int getPositiveLongFromObjectOrReply(client *c, robj *o, long *target, const char *msg);
int getRangeLongFromObjectOrReply(client *c, robj *o, long min, long max, long *target, const char *msg);
int checkType(client *c, robj *o, int type);
int getLongLongFromObjectOrReply(client *c, robj *o, long long *target, const char *msg);
int getDoubleFromObjectOrReply(client *c, robj *o, double *target, const char *msg);