Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 69355fa

Browse files
Future proof our igbinary header check
See: #2194
1 parent 141ca2e commit 69355fa

2 files changed

Lines changed: 27 additions & 7 deletions

File tree

library.c

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3565,15 +3565,14 @@ redis_unserialize(RedisSock* redis_sock, const char *val, int val_len,
35653565
* | header (4) | type (1) | ... (n) | NUL (1) |
35663566
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
35673567
*
3568-
* With header being either 0x00000001 or 0x00000002
3569-
* (encoded as big endian).
3568+
* With header being three zero bytes and one non-zero version
3569+
* specifier. At the time of this comment, there is only version
3570+
* 0x01 and 0x02, but newer versions will use subsequent
3571+
* values.
35703572
*
3571-
* Not all versions contain the trailing NULL byte though, so
3572-
* do not check for that.
3573+
* Not all versions contain a trailing \x00 so don't check for that.
35733574
*/
3574-
if (val_len < 5
3575-
|| (memcmp(val, "\x00\x00\x00\x01", 4) != 0
3576-
&& memcmp(val, "\x00\x00\x00\x02", 4) != 0))
3575+
if (val_len < 5 || memcmp(val, "\x00\x00\x00", 3) || val[3] < '\x01' || val[3] > '\x04')
35773576
{
35783577
/* This is most definitely not an igbinary string, so do
35793578
not try to unserialize this as one. */

tests/RedisTest.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4838,6 +4838,27 @@ public function testSerializerIGBinary() {
48384838
$this->redis->setOption(Redis::OPT_PREFIX, "test:");
48394839
$this->checkSerializer(Redis::SERIALIZER_IGBINARY);
48404840
$this->redis->setOption(Redis::OPT_PREFIX, "");
4841+
4842+
/* Test our igbinary header check logic. The check allows us to do
4843+
simple INCR type operations even with the serializer enabled, and
4844+
should also protect against igbinary-like data from being erroneously
4845+
deserialized */
4846+
$this->redis->del('incrkey');
4847+
4848+
$this->redis->set('spoof-1', "\x00\x00\x00\x00");
4849+
$this->redis->set('spoof-2', "\x00\x00\x00\x00bad-version1");
4850+
$this->redis->set('spoof-3', "\x00\x00\x00\x05bad-version2");
4851+
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_IGBINARY);
4852+
4853+
$this->assertEquals(16, $this->redis->incrby('incrkey', 16));
4854+
$this->assertEquals('16', $this->redis->get('incrkey'));
4855+
4856+
$this->assertEquals("\x00\x00\x00\x00", $this->redis->get('spoof-1'));
4857+
$this->assertEquals("\x00\x00\x00\x00bad-version1", $this->redis->get('spoof-2'));
4858+
$this->assertEquals("\x00\x00\x00\x05bad-version2", $this->redis->get('spoof-3'));
4859+
$this->redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_NONE);
4860+
4861+
$this->redis->del('incrkey', 'spoof-1', 'spoof-2', 'spoof-3');
48414862
}
48424863
}
48434864

0 commit comments

Comments
 (0)