~ubuntu-branches/ubuntu/vivid/musl/vivid

« back to all changes in this revision

Viewing changes to src/locale/__mo_lookup.c

  • Committer: Package Import Robot
  • Author(s): Kevin Bortis
  • Date: 2014-05-26 22:45:52 UTC
  • mfrom: (4.1.4 sid)
  • Revision ID: package-import@ubuntu.com-20140526224552-qrtsct934q29xo0x
Tags: 1.1.4-1
* Import upstream version 1.1.4. (Closes: #754758)
* Fixes possible stack-based buffer overflow CVE-2014-3484 (Closes: #750815) 
* Includes fix for build regression on armhf and armel

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdint.h>
 
2
#include <string.h>
 
3
 
 
4
static inline uint32_t swapc(uint32_t x, int c)
 
5
{
 
6
        return c ? x>>24 | x>>8&0xff00 | x<<8&0xff0000 | x<<24 : x;
 
7
}
 
8
 
 
9
const char *__mo_lookup(const void *p, size_t size, const char *s)
 
10
{
 
11
        const uint32_t *mo = p;
 
12
        int sw = *mo - 0x950412de;
 
13
        uint32_t b = 0, n = swapc(mo[2], sw);
 
14
        uint32_t o = swapc(mo[3], sw);
 
15
        uint32_t t = swapc(mo[4], sw);
 
16
        if (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))
 
17
                return 0;
 
18
        o/=4;
 
19
        t/=4;
 
20
        for (;;) {
 
21
                uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
 
22
                uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
 
23
                if (os >= size || ol >= size-os || ((char *)p)[os+ol])
 
24
                        return 0;
 
25
                int sign = strcmp(s, (char *)p + os);
 
26
                if (!sign) {
 
27
                        uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
 
28
                        uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
 
29
                        if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
 
30
                                return 0;
 
31
                        return (char *)p + ts;
 
32
                }
 
33
                else if (n == 1) return 0;
 
34
                else if (sign < 0)
 
35
                        n /= 2;
 
36
                else {
 
37
                        b += n/2;
 
38
                        n -= n/2;
 
39
                }
 
40
        }
 
41
        return 0;
 
42
}