diff options
author | guybe7 <guy.benoish@redislabs.com> | 2021-10-21 11:50:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-21 12:50:58 +0300 |
commit | 8f745da1597efdb5f9275af91a63c08ba26abb61 (patch) | |
tree | ec02cf121316bd94f3d6f1ddcab1e06b307d3ee2 /src/server.c | |
parent | 8bf4c2e38c6531af8a8b5bbe3ce469d79a920d35 (diff) | |
download | redis-8f745da1597efdb5f9275af91a63c08ba26abb61.tar.gz |
Fix sentinel commands, ACL dictIter leak (#9661)
Diffstat (limited to 'src/server.c')
-rw-r--r-- | src/server.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/src/server.c b/src/server.c index 7894be358..53303fc36 100644 --- a/src/server.c +++ b/src/server.c @@ -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 |