Hello community, here is the log from the commit of package redis for openSUSE:Factory checked in at 2018-08-18 00:05:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/redis (Old) and /work/SRC/openSUSE:Factory/.redis.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "redis" Sat Aug 18 00:05:49 2018 rev:44 rq:629736 version:4.0.11 Changes: -------- --- /work/SRC/openSUSE:Factory/redis/redis.changes 2018-07-25 16:13:49.310006585 +0200 +++ /work/SRC/openSUSE:Factory/.redis.new/redis.changes 2018-08-18 00:05:55.547402670 +0200 @@ -1,0 +2,20 @@ +Fri Aug 17 00:33:26 UTC 2018 - i...@ilya.pp.ua + +- Refresh spec-file. +- Update to 4.0.11 + * https://raw.githubusercontent.com/antirez/redis/4.0.11/00-RELEASENOTES + * The disconnection time between the master and slave was reset + in an incorrect place, sometimes a good slave will not be able + to failover because it claims it was disconnected for too much + time from the master. + * A replication bug, rare to trigger but non impossible, is in + Redis for years. It was lately discovered at Redis Labs and + fixed by Oran Agra. It may cause disconnections, + desynchronizations and other issues. + * RANDOMKEY may go in infinite loop on rare situations. Now fixed. + * EXISTS now works in a more consistent way on slaves. + * Sentinel: backport of an option to deny a potential security + problem when the SENTINEL command is used to configure an + arbitrary script to execute. + +------------------------------------------------------------------- Old: ---- redis-4.0.10.tar.gz New: ---- redis-4.0.11.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ redis.spec ++++++ --- /var/tmp/diff_new_pack.Ac3Yoz/_old 2018-08-18 00:05:56.223404695 +0200 +++ /var/tmp/diff_new_pack.Ac3Yoz/_new 2018-08-18 00:05:56.223404695 +0200 @@ -12,15 +12,14 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org # - %define _data_dir %{_localstatedir}/lib/%{name} %define _log_dir %{_localstatedir}/log/%{name} %define _conf_dir %{_sysconfdir}/%{name} Name: redis -Version: 4.0.10 +Version: 4.0.11 Release: 0 Summary: Persistent key-value database License: BSD-3-Clause @@ -63,7 +62,7 @@ %patch2 %ifnarch %{ix86} x86_64 ia64 %{arm} # We have no backtrace, so disable logging test -%patch3 -p0 +%patch3 %endif %patch4 -p1 @@ -96,7 +95,7 @@ install -Dm 0644 %{SOURCE1} %{buildroot}%{_sysconfdir}/logrotate.d/%{name} install -Dm 0644 %{SOURCE2} %{buildroot}%{_unitdir}/%{name}.target install -Dm 0644 %{SOURCE3} %{buildroot}%{_unitdir}/%{name}@.service -install -Dm 0644 %{SOURCE4} %{buildroot}%{_prefix}/lib/tmpfiles.d/%{name}.conf +install -Dm 0644 %{SOURCE4} %{buildroot}%{_libexecdir}/tmpfiles.d/%{name}.conf ln -sf %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name} cp %{SOURCE5} README.SUSE @@ -119,7 +118,7 @@ %service_add_pre %{name}.target %post -systemd-tmpfiles --create %{_prefix}/lib/tmpfiles.d/%{name}.conf || true +systemd-tmpfiles --create %{_libexecdir}/tmpfiles.d/%{name}.conf || true %service_add_post %{name}.target echo "See %{_docdir}/%{name}/README.SUSE to continue" @@ -130,13 +129,14 @@ %service_del_postun %{name}.target %files -%doc 00-RELEASENOTES BUGS CONTRIBUTING COPYING README.md +%license COPYING +%doc 00-RELEASENOTES BUGS CONTRIBUTING README.md %config(noreplace) %{_sysconfdir}/logrotate.d/%{name} %config(noreplace) %{_sysconfdir}/sysctl.d/00-%{name}.conf %{_bindir}/%{name}-* %{_sbindir}/%{name}-* %{_sbindir}/rc%{name} -%{_prefix}/lib/tmpfiles.d/%{name}.conf +%{_libexecdir}/tmpfiles.d/%{name}.conf %{_unitdir}/%{name}@.service %{_unitdir}/%{name}.target %doc README.SUSE ++++++ redis-4.0.10.tar.gz -> redis-4.0.11.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/00-RELEASENOTES new/redis-4.0.11/00-RELEASENOTES --- old/redis-4.0.10/00-RELEASENOTES 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/00-RELEASENOTES 2018-08-04 00:44:56.000000000 +0200 @@ -11,6 +11,56 @@ -------------------------------------------------------------------------------- ================================================================================ +Redis 4.0.11 Released Fri Aug 03 17:09:24 CEST 2018 +================================================================================ + +Upgrade urgency HIGH: not critical but very important bugs fixed. + +Dear users, this is just a bugfix release of Redis 4. All new work +is now focused on Redis 5, however we backported a number of bug fixes here: + +* The disconnection time between the master and slave was reset in an + incorrect place, sometimes a good slave will not be able to failover + because it claims it was disconnected for too much time from the master. +* A replication bug, rare to trigger but non impossible, is in Redis for + years. It was lately discovered at Redis Labs and fixed by Oran Agra. + It may cause disconnections, desynchronizations and other issues. +* RANDOMKEY may go in infinite loop on rare situations. Now fixed. +* EXISTS now works in a more consistent way on slaves. +* Sentinel: backport of an option to deny a potential security problem + when the SENTINEL command is used to configure an arbitrary script + to execute. + +Many of these issues are there for a very long time, however upgrading +is a good idea. + +This is the full list of commits: + +antirez in commit 677f7585: + Set repl_down_since to zero on state change. + 1 file changed, 2 insertions(+), 1 deletion(-) + +WuYunlong in commit 8c6223f9: + fix server.repl_down_since resetting, so that slaves could failover automatically as expected. + 1 file changed, 1 insertion(+), 1 deletion(-) + +Oran Agra in commit 9535c215: + fix rare replication stream corruption with disk-based replication + 3 files changed, 19 insertions(+), 9 deletions(-) + +zhaozhao.zz in commit 5f1fcc59: + fix exists command on slave + 1 file changed, 1 insertion(+), 2 deletions(-) + +antirez in commit ab145a9f: + Fix infinite loop in dbRandomKey(). + 1 file changed, 13 insertions(+) + +antirez in commit 2fa43ece: + Sentinel: add an option to deny online script reconfiguration. + 2 files changed, 41 insertions(+) + +================================================================================ Redis 4.0.10 Released Wed Jun 13 12:49:13 CEST 2018 ================================================================================ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/sentinel.conf new/redis-4.0.11/sentinel.conf --- old/redis-4.0.10/sentinel.conf 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/sentinel.conf 2018-08-04 00:44:56.000000000 +0200 @@ -194,3 +194,12 @@ # # sentinel client-reconfig-script mymaster /var/redis/reconfig.sh +# SECURITY +# +# By default SENTINEL SET will not be able to change the notification-script +# and client-reconfig-script at runtime. This avoids a trivial security issue +# where clients can set the script to anything and trigger a failover in order +# to get the program executed. + +sentinel deny-scripts-reconfig yes + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/db.c new/redis-4.0.11/src/db.c --- old/redis-4.0.10/src/db.c 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/db.c 2018-08-04 00:44:56.000000000 +0200 @@ -224,6 +224,8 @@ * The function makes sure to return keys not already expired. */ robj *dbRandomKey(redisDb *db) { dictEntry *de; + int maxtries = 100; + int allvolatile = dictSize(db->dict) == dictSize(db->expires); while(1) { sds key; @@ -235,6 +237,17 @@ key = dictGetKey(de); keyobj = createStringObject(key,sdslen(key)); if (dictFind(db->expires,key)) { + if (allvolatile && server.masterhost && --maxtries == 0) { + /* If the DB is composed only of keys with an expire set, + * it could happen that all the keys are already logically + * expired in the slave, so the function cannot stop because + * expireIfNeeded() is false, nor it can stop because + * dictGetRandomKey() returns NULL (there are keys to return). + * To prevent the infinite loop we do some tries, but if there + * are the conditions for an infinite loop, eventually we + * return a key name that may be already expired. */ + return keyobj; + } if (expireIfNeeded(db,keyobj)) { decrRefCount(keyobj); continue; /* search for another key. This expired. */ @@ -468,8 +481,7 @@ int j; for (j = 1; j < c->argc; j++) { - expireIfNeeded(c->db,c->argv[j]); - if (dbExists(c->db,c->argv[j])) count++; + if (lookupKeyRead(c->db,c->argv[j])) count++; } addReplyLongLong(c,count); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/networking.c new/redis-4.0.11/src/networking.c --- old/redis-4.0.10/src/networking.c 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/networking.c 2018-08-04 00:44:56.000000000 +0200 @@ -376,11 +376,13 @@ addReplyString(c,"-ERR ",5); addReplyString(c,s,len); addReplyString(c,"\r\n",2); - if (c->flags & CLIENT_MASTER) { + if (c->flags & (CLIENT_MASTER|CLIENT_SLAVE)) { + char* to = c->flags & CLIENT_MASTER? "master": "slave"; + char* from = c->flags & CLIENT_MASTER? "slave": "master"; char *cmdname = c->lastcmd ? c->lastcmd->name : "<unknown>"; - serverLog(LL_WARNING,"== CRITICAL == This slave is sending an error " - "to its master: '%s' after processing the command " - "'%s'", s, cmdname); + serverLog(LL_WARNING,"== CRITICAL == This %s is sending an error " + "to its %s: '%s' after processing the command " + "'%s'", from, to, s, cmdname); } } @@ -595,6 +597,7 @@ * destination client. */ void copyClientOutputBuffer(client *dst, client *src) { listRelease(dst->reply); + dst->sentlen = 0; dst->reply = listDup(src->reply); memcpy(dst->buf,src->buf,src->bufpos); dst->bufpos = src->bufpos; @@ -1068,7 +1071,7 @@ * with the error and close the connection. */ int processInlineBuffer(client *c) { char *newline; - int argc, j; + int argc, j, linefeed_chars = 1; sds *argv, aux; size_t querylen; @@ -1086,7 +1089,7 @@ /* Handle the \r\n case. */ if (newline && newline != c->querybuf && *(newline-1) == '\r') - newline--; + newline--, linefeed_chars++; /* Split the input buffer up to the \r\n */ querylen = newline-(c->querybuf); @@ -1106,7 +1109,7 @@ c->repl_ack_time = server.unixtime; /* Leave data after the first line of the query in the buffer */ - sdsrange(c->querybuf,querylen+2,-1); + sdsrange(c->querybuf,querylen+linefeed_chars,-1); /* Setup argv array on client structure */ if (argc) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/replication.c new/redis-4.0.11/src/replication.c --- old/redis-4.0.10/src/replication.c 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/replication.c 2018-08-04 00:44:56.000000000 +0200 @@ -1278,6 +1278,7 @@ close(server.repl_transfer_fd); replicationCreateMasterClient(server.repl_transfer_s,rsi.repl_stream_db); server.repl_state = REPL_STATE_CONNECTED; + server.repl_down_since = 0; /* After a full resynchroniziation we use the replication ID and * offset of the master. The secondary ID / offset are cleared since * we are starting a new history. */ @@ -1942,7 +1943,6 @@ * our own parameters, to later PSYNC with the new master. */ if (was_master) replicationCacheMasterUsingMyself(); server.repl_state = REPL_STATE_CONNECT; - server.repl_down_since = 0; } /* Cancel replication, setting the instance as a master itself. */ @@ -2140,6 +2140,8 @@ server.master->read_reploff = server.master->reploff; if (c->flags & CLIENT_MULTI) discardTransaction(c); listEmpty(c->reply); + c->sentlen = 0; + c->reply_bytes = 0; c->bufpos = 0; resetClient(c); @@ -2209,6 +2211,7 @@ server.master->authenticated = 1; server.master->lastinteraction = server.unixtime; server.repl_state = REPL_STATE_CONNECTED; + server.repl_down_since = 0; /* Re-add to the list of clients. */ listAddNodeTail(server.clients,server.master); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/sentinel.c new/redis-4.0.11/src/sentinel.c --- old/redis-4.0.10/src/sentinel.c 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/sentinel.c 2018-08-04 00:44:56.000000000 +0200 @@ -84,6 +84,7 @@ #define SENTINEL_MAX_PENDING_COMMANDS 100 #define SENTINEL_ELECTION_TIMEOUT 10000 #define SENTINEL_MAX_DESYNC 1000 +#define SENTINEL_DEFAULT_DENY_SCRIPTS_RECONFIG 1 /* Failover machine different states. */ #define SENTINEL_FAILOVER_STATE_NONE 0 /* No failover in progress. */ @@ -241,6 +242,8 @@ int announce_port; /* Port that is gossiped to other sentinels if non zero. */ unsigned long simfailure_flags; /* Failures simulation. */ + int deny_scripts_reconfig; /* Allow SENTINEL SET ... to change script + paths at runtime? */ } sentinel; /* A script execution job. */ @@ -468,6 +471,7 @@ sentinel.announce_ip = NULL; sentinel.announce_port = 0; sentinel.simfailure_flags = SENTINEL_SIMFAILURE_NONE; + sentinel.deny_scripts_reconfig = SENTINEL_DEFAULT_DENY_SCRIPTS_RECONFIG; memset(sentinel.myid,0,sizeof(sentinel.myid)); } @@ -1684,6 +1688,12 @@ } else if (!strcasecmp(argv[0],"announce-port") && argc == 2) { /* announce-port <port> */ sentinel.announce_port = atoi(argv[1]); + } else if (!strcasecmp(argv[0],"deny-scripts-reconfig") && argc == 2) { + /* deny-scripts-reconfig <yes|no> */ + if ((sentinel.deny_scripts_reconfig = yesnotoi(argv[1])) == -1) { + return "Please specify yes or no for the " + "deny-scripts-reconfig options."; + } } else { return "Unrecognized sentinel configuration statement."; } @@ -1704,6 +1714,12 @@ line = sdscatprintf(sdsempty(), "sentinel myid %s", sentinel.myid); rewriteConfigRewriteLine(state,"sentinel",line,1); + /* sentinel deny-scripts-reconfig. */ + line = sdscatprintf(sdsempty(), "sentinel deny-scripts-reconfig %s", + sentinel.deny_scripts_reconfig ? "yes" : "no"); + rewriteConfigRewriteLine(state,"sentinel",line, + sentinel.deny_scripts_reconfig != SENTINEL_DEFAULT_DENY_SCRIPTS_RECONFIG); + /* For every master emit a "sentinel monitor" config entry. */ di = dictGetIterator(sentinel.masters); while((de = dictNext(di)) != NULL) { @@ -3331,6 +3347,14 @@ changes++; } else if (!strcasecmp(option,"notification-script")) { /* notification-script <path> */ + if (sentinel.deny_scripts_reconfig) { + addReplyError(c, + "Reconfiguration of scripts path is denied for " + "security reasons. Check the deny-scripts-reconfig " + "configuration directive in your Sentinel configuration"); + return; + } + if (strlen(value) && access(value,X_OK) == -1) { addReplyError(c, "Notification script seems non existing or non executable"); @@ -3342,6 +3366,14 @@ changes++; } else if (!strcasecmp(option,"client-reconfig-script")) { /* client-reconfig-script <path> */ + if (sentinel.deny_scripts_reconfig) { + addReplyError(c, + "Reconfiguration of scripts path is denied for " + "security reasons. Check the deny-scripts-reconfig " + "configuration directive in your Sentinel configuration"); + return; + } + if (strlen(value) && access(value,X_OK) == -1) { addReplyError(c, "Client reconfiguration script seems non existing or " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/server.c new/redis-4.0.11/src/server.c --- old/redis-4.0.10/src/server.c 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/server.c 2018-08-04 00:44:56.000000000 +0200 @@ -2345,8 +2345,13 @@ c->cmd = c->lastcmd = lookupCommand(c->argv[0]->ptr); if (!c->cmd) { flagTransaction(c); - addReplyErrorFormat(c,"unknown command '%s'", - (char*)c->argv[0]->ptr); + sds args = sdsempty(); + int i; + for (i=1; i < c->argc && sdslen(args) < 128; i++) + args = sdscatprintf(args, "`%.*s`, ", 128-(int)sdslen(args), (char*)c->argv[i]->ptr); + addReplyErrorFormat(c,"unknown command `%s`, with args beginning with: %s", + (char*)c->argv[0]->ptr, args); + sdsfree(args); return C_OK; } else if ((c->cmd->arity > 0 && c->cmd->arity != c->argc) || (c->argc < -c->cmd->arity)) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/redis-4.0.10/src/version.h new/redis-4.0.11/src/version.h --- old/redis-4.0.10/src/version.h 2018-06-13 13:02:07.000000000 +0200 +++ new/redis-4.0.11/src/version.h 2018-08-04 00:44:56.000000000 +0200 @@ -1 +1 @@ -#define REDIS_VERSION "4.0.10" +#define REDIS_VERSION "4.0.11"