Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lua library commands can cause the Dragonfly service to crash #4468

Open
ankki-zsyang opened this issue Jan 17, 2025 · 8 comments
Open

Lua library commands can cause the Dragonfly service to crash #4468

ankki-zsyang opened this issue Jan 17, 2025 · 8 comments
Assignees
Labels
bug Something isn't working Next Up task that is ready to be worked on and should be added to working queue

Comments

@ankki-zsyang
Copy link

Summary

Authenticated users can construct special Lua library commands that cause the dragonfly service to crash.

Details

Dragonfly version: df-v1.26.1
Payload:
EVAL "return bit.tohex(65535, -2147483648)" 0
Executing the above payload will cause the dragonfly service to crash immediately.
Poof:

Image

Image

Reporter

The problem was reported by ankki-zsyang, Shenzhen Ankki Technologies Co.Ltd.

@ankki-zsyang ankki-zsyang added the bug Something isn't working label Jan 17, 2025
@kostasrim
Copy link
Contributor

Hi @ankki-zsyang, indeed we crash. We will take a look and get back to you

@uttomroy
Copy link

in my machine I am also getting similar issue for different command. My machine is mac m3. I am not sure it is specific to mac or not.

Image

@romange
Copy link
Collaborator

romange commented Jan 22, 2025

can you please paste the full command that reproduces the failure here, @uttomroy ?

@uttomroy
Copy link

"EVAL" "if redis.call('setnx', KEYS[6], ARGV[4]) == 0 then return -1;end;redis.call('expire', KEYS[6], ARGV[3]); local expiredKeys1 = redis.call('zrangebyscore', KEYS[2], 0, ARGV[1], 'limit', 0, ARGV[2]); for i, key in ipairs(expiredKeys1) do local v = redis.call('hget', KEYS[1], key); if v ~= false then local t, val = struct.unpack('dLc0', v); local msg = struct.pack('Lc0Lc0', string.len(key), key, string.len(val), val); local listeners = redis.call(ARGV[5], KEYS[4], msg); if (listeners == 0) then break;end; end;end;for i=1, #expiredKeys1, 5000 do redis.call('zrem', KEYS[5], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('zrem', KEYS[3], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('zrem', KEYS[2], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('hdel', KEYS[1], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); end; local expiredKeys2 = redis.call('zrangebyscore', KEYS[3], 0, ARGV[1], 'limit', 0, ARGV[2]); for i, key in ipairs(expiredKeys2) do local v = redis.call('hget', KEYS[1], key); if v ~= false then local t, val = struct.unpack('dLc0', v); local msg = struct.pack('Lc0Lc0', string.len(key), key, string.len(val), val); local listeners = redis.call(ARGV[5], KEYS[4], msg); if (listeners == 0) then break;end; end;end;for i=1, #expiredKeys2, 5000 do redis.call('zrem', KEYS[5], unpack(expiredKeys2, i, math.min(i+4999, table.getn(expiredKeys2)))); redis.call('zrem', KEYS[3], unpack(expiredKeys2, i, math.min(i+4999, table.getn(expiredKeys2)))); redis.call('zrem', KEYS[2], unpack(expiredKeys2, i, math.min(i+4999, table.getn(expiredKeys2)))); redis.call('hdel', KEYS[1], unpack(expiredKeys2, i, math.min(i+4999, table.getn(expiredKeys2)))); end; return #expiredKeys1 + #expiredKeys2;" "6" "suppressionMapCache" "redisson__timeout__set:{suppressionMapCache}" "redisson__idle__set:{suppressionMapCache}" "redisson_map_cache_expired:{suppressionMapCache}" "redisson__map_cache__last_access__set:{suppressionMapCache}" "redisson__execute_task_once_latch:{suppressionMapCache}" "1737463077167" "100" "5" "1" "PUBLISH"

@uttomroy
Copy link

the same command works for other machine.

@uttomroy
Copy link

@romange

@romange
Copy link
Collaborator

romange commented Jan 22, 2025

Thank you very much, we will follow up on this. 🙏🏼

@adiholden adiholden added the Next Up task that is ready to be worked on and should be added to working queue label Jan 22, 2025
@romange
Copy link
Collaborator

romange commented Jan 23, 2025

@uttomroy I can not reproduce the failure on my machine. This is what I do:

docker run -p 6379:6379  docker.dragonflydb.io/dragonflydb/dragonfly:v1.26.1

and then run the command you posted. I get "0" in the result.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working Next Up task that is ready to be worked on and should be added to working queue
Projects
None yet
Development

No branches or pull requests

6 participants