### Summary
An out of bounds write vulnerability exists in the handling of the client-output-buffer-limit option during the CONFIG SET command for the Redis data structure store. A crafted CONFIG SET command can lead to an out of bounds write potentially resulting in code execution.
### Tested Versions
Redis - 3.2.3
### Product URLs
http://redis.io/
### CVSSv3 Score
6.6 - CVSS:3.0/AV:N/AC:H/PR:H/UI:N/S:U/C:H/I:H/A:H
### Details
Redis is a simple in-memory data structure store using a key-value model. Redis has been growing in popularity due to its ability to handle problems that other databases can't solve or are inherently slow at.
An out of bounds write vulnerability exists during the modification of the `client-output-buffer-limit` option using the `CONFIG SET` command. The required syntax for setting the `client-output-buffer-limit` option is shown below.
```
CONFIG SET client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
```
This option sets the limits for disconnecting clients of a certain class. This option is set using the following code:
```
src/config.c
849    /* Finally set the new config */
850    for (j = 0; j < vlen; j += 4) {
851        int class;
852        unsigned long long hard, soft;
853        int soft_seconds;
854
855        class = getClientTypeByName(v[j]);
856        hard = strtoll(v[j+1],NULL,10);
857        soft = strtoll(v[j+2],NULL,10);
858        soft_seconds = strtoll(v[j+3],NULL,10);
859
860        server.client_obuf_limits[class].hard_limit_bytes = hard;
861        server.client_obuf_limits[class].soft_limit_bytes = soft;
862        server.client_obuf_limits[class].soft_limit_seconds = soft_seconds;
863    }
src/networking.c
1747    int getClientTypeByName(char *name) {
1748        if (!strcasecmp(name,"normal")) return CLIENT_TYPE_NORMAL;      // 0
1749        else if (!strcasecmp(name,"slave")) return CLIENT_TYPE_SLAVE;   // 1
1750        else if (!strcasecmp(name,"pubsub")) return CLIENT_TYPE_PUBSUB; // 2
1751        else if (!strcasecmp(name,"master")) return CLIENT_TYPE_MASTER; // 3
1752        else return -1;
1753    }
```
In the parsing of `client-output-buffer-limit` a call to `getClientTypeByName` is used to retrieve the corresponding class's type. In this case, `getClientTypeByName` returns a value in the set of [-1, 3]. Looking at the declaration of the `client_obuf_limits` array, we see that the size of the array is `3`.
```
src/server.h
704    struct redisServer {
...
796    clientBufferLimitsConfig client_obuf_limits[CLIENT_TYPE_OBUF_COUNT];
...
980    }
src/server.h
292    #define CLIENT_TYPE_OBUF_COUNT 3 /* Number of clients to expose to output
```
Although `client-output-buffer-limit` is only expecting clients of types `normal`, `slave`, and `pubsub`, `master` is also a valid client. By providing a client type of `master`, the `client_obuf_limit` array is overflown and subsequent structure variables are overwritten.
A sample command exercising this vulnerability is below:
```
CONFIG SET client-output-buffer-limit "master 3735928559 3405691582 373529054"
```
### Timeline
* 2016-09-22 - Vendor Disclosure
* 2016—09-26 - Public Release
                       
                       
        
          
暂无评论