为什么 Redis 不能使用 requirepass 指令?

gla*_*ain 2 authentication redis

我想设置一个密码来连接到 Redis 服务器。

适当的方法是使用requirepass配置文件中的指令。 http://redis.io/commands/auth

但是,在设置该值后,我在重新启动 Redis 时得到了这个:

Stopping redis-server: redis-server.
Starting redis-server: Segmentation fault (core dumped)
failed
Run Code Online (Sandbox Code Playgroud)

这是为什么?

Did*_*zia 5

密码长度限制为 512 个字符。

在 redis.h 中:

#define REDIS_AUTHPASS_MAX_LEN 512
Run Code Online (Sandbox Code Playgroud)

在 config.c 中:

    } else if (!strcasecmp(argv[0],"requirepass") && argc == 2) {
        if (strlen(argv[1]) > REDIS_AUTHPASS_MAX_LEN) {
            err = "Password is longer than REDIS_AUTHPASS_MAX_LEN";
            goto loaderr;
        }
        server.requirepass = zstrdup(argv[1]);
    }
Run Code Online (Sandbox Code Playgroud)

现在,配置文件的解析机制非常基本。使用 sds(字符串管理)库的 sdssplitargs 函数拆分所有行。此函数解释特定的字符序列,例如:

  • 单引号和双引号
  • \x 十六进制数字
  • 特殊字符,如\n、\r、\t、\b、\a

这里的问题是您的密码包含一个双引号字符。解析失败,因为字符串末尾没有匹配的双引号。在这种情况下,sdssplitargs 函数返回一个 NULL 指针。核心转储的发生是因为在 config.c 代码中没有正确检查这个指针:

    /* Split into arguments */
    argv = sdssplitargs(lines[i],&argc);
    sdstolower(argv[0]);
Run Code Online (Sandbox Code Playgroud)

这是一个应该提交 IMO 的错误。

一个简单的解决方法是用十六进制序列(即双引号 \x22)替换双引号字符或任何其他解释的字符。