Open
Description
slots.c 和 slots_async.c 中都涉及到对一些dict数据结构的操作,一些操作比如 dictAdd
dictFind
所使用的 key 在 slot.c 中都为 sds
,而在 slots_async.c 中都为 robj *
我自己尝试手动合并 codis 的 patch到 redis 4.0.1 版本中,slots_async.c中对dict 的 find 和 add 操作会导致崩溃:
(gdb) thread 5
[Switching to thread 5 (Thread 0x7fbe4f373740 (LWP 34681))]#0 0x00000000004b4676 in siphash (in=0x7fbe46000000 <Address 0x7fbe46000000 out of bounds>,
inlen=808464432, k=0x768a50 "d04f1ef0cf136f63Linux") at siphash.c:136
136 siphash.c: No such file or directory.
in siphash.c
(gdb) bt
#0 0x00000000004b4676 in siphash (in=0x7fbe46000000 <Address 0x7fbe46000000 out of bounds>, inlen=808464432, k=0x768a50 "d04f1ef0cf136f63Linux") at siphash.c:136
#1 0x0000000000428d70 in dictGenHashFunction (key=0x7fbe2cac39d8, len=808464432) at dict.c:91
#2 0x000000000042b8aa in dictSdsHash (key=0x7fbe2cac39d8) at server.c:519
#3 0x0000000000429b79 in dictFind (d=0x7fbd994510c0, key=0x7fbe2cac39d8) at dict.c:483
#4 0x00000000004bda4b in batchedObjectIteratorContains (it=0x7fbe48e410f0, key=0x7fbe2cac39d8, usetag=1) at slots_async.c:538
#5 0x00000000004be750 in getSlotsmgrtAsyncClientMigrationStatusOrBlock (c=0x7fbe429f1180, key=0x7fbe2cac39d8, block=0) at slots_async.c:790
#6 0x00000000004bfe2e in slotsmgrtExecWrapperCommand (c=0x7fbe429f1180) at slots_async.c:1284
#7 0x000000000042f6e4 in call (c=0x7fbe429f1180, flags=15) at server.c:2275
#8 0x000000000043026e in processCommand (c=0x7fbe429f1180) at server.c:2557
原因是 调用真正的 hash 函数 siphash
时,如果 key 为 robj *
类型,传递给 siphash 函数的第一个参数 const uint8_t *in
后,内存地址就越界了.
将所有 key 为 robj *
的地方改成使用 sds
(sdsdup(robj->ptr)
for add, robj->ptr
for find & delete) 可以解决这问题。redis 源码对dict使用的key也为sds,是否考虑 slots_async.c
中对key的类型做一下修改,和其他代码统一起来?