|
1 Fix for CVE-2014-3538 |
|
2 Patch from PHP community: |
|
3 http://git.php.net/?p=php-src.git;a=commitdiff;h=eeaec70758bfc0c0e2c0f8944c8dbeae02866206 |
|
4 But this is for php 5.4.32. |
|
5 The website: |
|
6 http://permalink.gmane.org/gmane.linux.frugalware.scm/131282 |
|
7 shows a patch for php 5.3.26 so I've hand crafted a patch |
|
8 based on both websites. |
|
9 |
|
10 |
|
11 --- php-5.3.29/ext/fileinfo/libmagic/softmagic.c_orig 2014-10-20 16:46:35.678013082 -0700 |
|
12 +++ php-5.3.29/ext/fileinfo/libmagic/softmagic.c 2014-10-22 13:51:20.141509243 -0700 |
|
13 @@ -56,7 +56,7 @@ |
|
14 private int32_t moffset(struct magic_set *, struct magic *); |
|
15 private void mdebug(uint32_t, const char *, size_t); |
|
16 private int mcopy(struct magic_set *, union VALUETYPE *, int, int, |
|
17 - const unsigned char *, uint32_t, size_t, size_t); |
|
18 + const unsigned char *, uint32_t, size_t, struct magic *); |
|
19 private int mconvert(struct magic_set *, struct magic *); |
|
20 private int print_sep(struct magic_set *, int); |
|
21 private int handle_annotation(struct magic_set *, struct magic *); |
|
22 @@ -898,7 +898,7 @@ |
|
23 |
|
24 private int |
|
25 mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, |
|
26 - const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt) |
|
27 + const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) |
|
28 { |
|
29 /* |
|
30 * Note: FILE_SEARCH and FILE_REGEX do not actually copy |
|
31 @@ -918,15 +918,24 @@ |
|
32 const char *last; /* end of search region */ |
|
33 const char *buf; /* start of search region */ |
|
34 const char *end; |
|
35 - size_t lines; |
|
36 + size_t lines, linecnt, bytecnt; |
|
37 + |
|
38 + linecnt = m->str_range; |
|
39 + bytecnt = linecnt * 80; |
|
40 |
|
41 + if (bytecnt == 0) { |
|
42 + bytecnt = 8192; |
|
43 + } |
|
44 + if (bytecnt > nbytes) { |
|
45 + bytecnt = nbytes; |
|
46 + } |
|
47 if (s == NULL) { |
|
48 ms->search.s_len = 0; |
|
49 ms->search.s = NULL; |
|
50 return 0; |
|
51 } |
|
52 buf = RCAST(const char *, s) + offset; |
|
53 - end = last = RCAST(const char *, s) + nbytes; |
|
54 + end = last = RCAST(const char *, s) + bytecnt; |
|
55 /* mget() guarantees buf <= last */ |
|
56 for (lines = linecnt, b = buf; lines && b < end && |
|
57 ((b = CAST(const char *, |
|
58 @@ -939,7 +948,7 @@ |
|
59 b++; |
|
60 } |
|
61 if (lines) |
|
62 - last = RCAST(const char *, s) + nbytes; |
|
63 + last = RCAST(const char *, s) + bytecnt; |
|
64 |
|
65 ms->search.s = buf; |
|
66 ms->search.s_len = last - buf; |
|
67 @@ -1012,7 +1021,6 @@ |
|
68 int recursion_level) |
|
69 { |
|
70 uint32_t offset = ms->offset; |
|
71 - uint32_t count = m->str_range; |
|
72 union VALUETYPE *p = &ms->ms_value; |
|
73 |
|
74 if (recursion_level >= 20) { |
|
75 @@ -1020,10 +1028,13 @@ |
|
76 return -1; |
|
77 } |
|
78 |
|
79 - if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) |
|
80 + if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, |
|
81 + (uint32_t)nbytes, m) == -1) |
|
82 return -1; |
|
83 |
|
84 if ((ms->flags & MAGIC_DEBUG) != 0) { |
|
85 + fprintf(stderr, "mget(type=%d, flag=%x, offset=%u, " |
|
86 + "nbytes=%zu)\n", m->type, m->flag, offset, nbytes); |
|
87 mdebug(offset, (char *)(void *)p, sizeof(union VALUETYPE)); |
|
88 } |
|
89 |
|
90 @@ -1504,7 +1515,7 @@ |
|
91 if (m->flag & INDIROFFADD) { |
|
92 offset += ms->c.li[cont_level-1].off; |
|
93 } |
|
94 - if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1) |
|
95 + if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1) |
|
96 return -1; |
|
97 ms->offset = offset; |
|
98 |