Fix sentinel commands, ACL dictIter leak (#9661)

This commit is contained in:
guybe7 2021-10-21 11:50:58 +02:00 committed by GitHub
parent 8bf4c2e38c
commit 8f745da159
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 26 deletions

View File

@ -426,6 +426,7 @@ void ACLChangeCommandPerm(user *u, struct redisCommand *cmd, int allow) {
struct redisCommand *sub = (struct redisCommand *)dictGetVal(de);
ACLSetUserCommandBit(u,sub->id,allow);
}
dictReleaseIterator(di);
}
}

View File

@ -944,10 +944,10 @@ RedisModuleCommandProxy *moduleCreateCommandProxy(RedisModuleCtx *ctx, const cha
*
* Note that we use the Redis command table 'getkeys_proc' in order to
* pass a reference to the command proxy structure. */
cp = zmalloc(sizeof(*cp));
cp = zcalloc(sizeof(*cp));
cp->module = ctx->module;
cp->func = cmdfunc;
cp->rediscmd = zmalloc(sizeof(*rediscmd));
cp->rediscmd = zcalloc(sizeof(*rediscmd));
cp->rediscmd->name = cmdname;
cp->rediscmd->proc = RedisModuleCommandDispatcher;
cp->rediscmd->flags = flags | CMD_MODULE;

View File

@ -628,7 +628,7 @@ struct redisCommand sentinelSubcommands[] = {
{"config",sentinelCommand,-3,
"admin only-sentinel"},
{"debug",sentinelCommand,2,
{"debug",sentinelCommand,-2,
"admin only-sentinel"},
{"get-master-addr-by-name",sentinelCommand,3,
@ -673,7 +673,7 @@ struct redisCommand sentinelSubcommands[] = {
{"sentinels",sentinelCommand,3,
"admin only-sentinel"},
{"set",sentinelCommand,5,
{"set",sentinelCommand,-3,
"admin only-sentinel"},
{"simulate-failure",sentinelCommand,3,
@ -2027,7 +2027,7 @@ struct redisCommand redisCommandTable[] = {
"read-only fast"},
{"acl",NULL,-2,
"",
"sentinel",
.subcommands=aclSubcommands},
{"stralgo",NULL,-2,
@ -4449,16 +4449,17 @@ void commandAddSubcommand(struct redisCommand *parent, struct redisCommand *subc
serverAssert(dictAdd(parent->subcommands_dict, sdsnew(subcommand->name), subcommand) == DICT_OK);
}
/* Parse the flags string description 'strflags' and set them to the
* command 'c'. If the flags are all valid C_OK is returned, otherwise
* C_ERR is returned (yet the recognized flags are set in the command). */
int populateSingleCommand(struct redisCommand *c, char *strflags) {
* command 'c'. Abort on error. */
void parseCommandFlags(struct redisCommand *c, char *strflags) {
int argc;
sds *argv;
/* Split the line into arguments for processing. */
argv = sdssplitargs(strflags,&argc);
if (argv == NULL) return C_ERR;
if (argv == NULL)
serverPanic("Failed splitting strflags!");
for (int j = 0; j < argc; j++) {
char *flag = argv[j];
@ -4497,6 +4498,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
} else if (!strcasecmp(flag,"sentinel")) {
c->flags |= CMD_SENTINEL;
} else if (!strcasecmp(flag,"only-sentinel")) {
c->flags |= CMD_SENTINEL; /* Obviously it's s sentinel command */
c->flags |= CMD_ONLY_SENTINEL;
} else {
/* Parse ACL categories here if the flag name starts with @. */
@ -4507,7 +4509,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
c->flags |= catflag;
} else {
sdsfreesplitres(argv,argc);
return C_ERR;
serverPanic("Unsupported command flag %s", flag);
}
}
}
@ -4515,8 +4517,11 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
if (!(c->flags & CMD_CATEGORY_FAST)) c->flags |= CMD_CATEGORY_SLOW;
sdsfreesplitres(argv,argc);
}
/* Now handle the key arguments spec flags */
void populateCommandStructure(struct redisCommand *c) {
int argc;
sds *argv;
/* Redis commands don't need more args than STATIC_KEY_SPECS_NUM (Number of keys
* specs can be greater than STATIC_KEY_SPECS_NUM only for module commands) */
@ -4530,7 +4535,7 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
/* Split the line into arguments for processing. */
argv = sdssplitargs(c->key_specs[i].sflags,&argc);
if (argv == NULL)
return C_ERR;
serverPanic("Failed splitting key sflags!");
for (int j = 0; j < argc; j++) {
char *flag = argv[j];
@ -4540,6 +4545,8 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
c->key_specs[i].flags |= CMD_KEY_READ;
} else if (!strcasecmp(flag,"incomplete")) {
c->key_specs[i].flags |= CMD_KEY_INCOMPLETE;
} else {
serverPanic("Unsupported key-arg flag %s", flag);
}
}
@ -4552,6 +4559,9 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
/* Handle the "movablekeys" flag (must be done after populating all key specs). */
populateCommandMovableKeys(c);
/* Assign the ID used for ACL. */
c->id = ACLGetCommandID(c->name);
/* Handle subcommands */
if (c->subcommands) {
for (int j = 0; c->subcommands[j].name; j++) {
@ -4559,14 +4569,11 @@ int populateSingleCommand(struct redisCommand *c, char *strflags) {
/* Translate the command string flags description into an actual
* set of flags. */
if (populateSingleCommand(sub,sub->sflags) == C_ERR)
serverPanic("Unsupported command flag or key spec flag");
parseCommandFlags(sub,sub->sflags);
populateCommandStructure(sub);
commandAddSubcommand(c,sub);
}
}
return C_OK;
}
/* Populates the Redis Command Table starting from the hard coded list
@ -4577,6 +4584,11 @@ void populateCommandTable(void) {
for (j = 0; j < numcommands; j++) {
struct redisCommand *c = redisCommandTable+j;
int retval1, retval2;
/* Translate the command string flags description into an actual
* set of flags. */
parseCommandFlags(c,c->sflags);
if (!(c->flags & CMD_SENTINEL) && server.sentinel_mode)
continue;
@ -4584,15 +4596,7 @@ void populateCommandTable(void) {
if (c->flags & CMD_ONLY_SENTINEL && !server.sentinel_mode)
continue;
int retval1, retval2;
/* Assign the ID used for ACL. */
c->id = ACLGetCommandID(c->name);
/* Translate the command string flags description into an actual
* set of flags. */
if (populateSingleCommand(c,c->sflags) == C_ERR)
serverPanic("Unsupported command flag or key spec flag");
populateCommandStructure(c);
retval1 = dictAdd(server.commands, sdsnew(c->name), c);
/* Populate an additional dictionary that will be unaffected