提交 cffe37fd 编写于 作者: E Enrico Giordani

Merged tag 2.8.24 from antirez/2.8

...@@ -14,6 +14,23 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade! ...@@ -14,6 +14,23 @@ HIGH: There is a critical bug that may affect a subset of users. Upgrade!
CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP. CRITICAL: There is a critical bug affecting MOST USERS. Upgrade ASAP.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
--[ Redis 2.8.24 ] Release date: 18 Dec 2015
Upgrade urgency: MODERATE. We fixed a crash that happens very rarely, so
updating does not hurt, but most users are unlikely to
experience this condition because it requires some odd
timing.
* [FIX] lua_struct.c/getnum security issue fixed. (Luca Bruno discovered it,
patched by Sun He and Chris Lamb)
* [FIX] Fix a race condition in processCommand() because of interactions
with freeMemoryIfNeeded(). Details in issue #2948 and especially
in the commit message d999f5a. (Race found analytically by
Oran Agra, patch by Salvatore Sanfilippo)
* [NEW] Log offending memory access address on SIGSEGV/SIGBUS (Salvatore
Sanfilippo)
--[ Redis 2.8.23 ] Release date: 15 Oct 2015 --[ Redis 2.8.23 ] Release date: 15 Oct 2015
Upgrade urgency: MODERATE, the most important thing is a fix in the replication Upgrade urgency: MODERATE, the most important thing is a fix in the replication
......
...@@ -89,12 +89,14 @@ typedef struct Header { ...@@ -89,12 +89,14 @@ typedef struct Header {
} Header; } Header;
static int getnum (const char **fmt, int df) { static int getnum (lua_State *L, const char **fmt, int df) {
if (!isdigit(**fmt)) /* no number? */ if (!isdigit(**fmt)) /* no number? */
return df; /* return default value */ return df; /* return default value */
else { else {
int a = 0; int a = 0;
do { do {
if (a > (INT_MAX / 10) || a * 10 > (INT_MAX - (**fmt - '0')))
luaL_error(L, "integral size overflow");
a = a*10 + *((*fmt)++) - '0'; a = a*10 + *((*fmt)++) - '0';
} while (isdigit(**fmt)); } while (isdigit(**fmt));
return a; return a;
...@@ -115,9 +117,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) { ...@@ -115,9 +117,9 @@ static size_t optsize (lua_State *L, char opt, const char **fmt) {
case 'f': return sizeof(float); case 'f': return sizeof(float);
case 'd': return sizeof(double); case 'd': return sizeof(double);
case 'x': return 1; case 'x': return 1;
case 'c': return getnum(fmt, 1); case 'c': return getnum(L, fmt, 1);
case 'i': case 'I': { case 'i': case 'I': {
int sz = getnum(fmt, sizeof(int)); int sz = getnum(L, fmt, sizeof(int));
if (sz > MAXINTSIZE) if (sz > MAXINTSIZE)
luaL_error(L, "integral size %d is larger than limit of %d", luaL_error(L, "integral size %d is larger than limit of %d",
sz, MAXINTSIZE); sz, MAXINTSIZE);
...@@ -150,7 +152,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt, ...@@ -150,7 +152,7 @@ static void controloptions (lua_State *L, int opt, const char **fmt,
case '>': h->endian = BIG; return; case '>': h->endian = BIG; return;
case '<': h->endian = LITTLE; return; case '<': h->endian = LITTLE; return;
case '!': { case '!': {
int a = getnum(fmt, MAXALIGN); int a = getnum(L, fmt, MAXALIGN);
if (!isp2(a)) if (!isp2(a))
luaL_error(L, "alignment %d is not a power of 2", a); luaL_error(L, "alignment %d is not a power of 2", a);
h->align = a; h->align = a;
......
...@@ -836,6 +836,10 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) { ...@@ -836,6 +836,10 @@ void sigsegvHandler(int sig, siginfo_t *info, void *secret) {
bugReportStart(); bugReportStart();
redisLog(REDIS_WARNING, redisLog(REDIS_WARNING,
" Redis %s crashed by signal: %d", REDIS_VERSION, sig); " Redis %s crashed by signal: %d", REDIS_VERSION, sig);
if (sig == SIGSEGV) {
redisLog(REDIS_WARNING,
" SIGSEGV caused by address: %p", (void*)info->si_addr);
}
redisLog(REDIS_WARNING, redisLog(REDIS_WARNING,
" Failed assertion: %s (%s:%d)", server.assert_failed, " Failed assertion: %s (%s:%d)", server.assert_failed,
server.assert_file, server.assert_line); server.assert_file, server.assert_line);
......
...@@ -2128,6 +2128,12 @@ int processCommand(redisClient *c) { ...@@ -2128,6 +2128,12 @@ int processCommand(redisClient *c) {
* is returning an error. */ * is returning an error. */
if (server.maxmemory) { if (server.maxmemory) {
int retval = freeMemoryIfNeeded(); int retval = freeMemoryIfNeeded();
/* freeMemoryIfNeeded may flush slave output buffers. This may result
* into a slave, that may be the active client, to be freed. */
if (server.current_client == NULL) return REDIS_ERR;
/* It was impossible to free enough memory, and the command the client
* is trying to execute is denied during OOM conditions? Error. */
if ((c->cmd->flags & REDIS_CMD_DENYOOM) && retval == REDIS_ERR) { if ((c->cmd->flags & REDIS_CMD_DENYOOM) && retval == REDIS_ERR) {
flagTransaction(c); flagTransaction(c);
addReply(c, shared.oomerr); addReply(c, shared.oomerr);
......
#define REDIS_VERSION "2.8.23" #define REDIS_VERSION "2.8.24"
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册