f8291b3520bfb2a9b75780c2e9f7850bf17b49a0
[packages/rsync.git] / CVE-2016-9841.patch
1 >From 9aaec95e82117c1cb0f9624264c3618fc380cecb Mon Sep 17 00:00:00 2001
2 From: Mark Adler <madler@alumni.caltech.edu>
3 Date: Wed, 21 Sep 2016 22:25:21 -0700
4 Subject: [PATCH] Use post-increment only in inffast.c.
5
6 An old inffast.c optimization turns out to not be optimal anymore
7 with modern compilers, and furthermore was not compliant with the
8 C standard, for which decrementing a pointer before its allocated
9 memory is undefined. Per the recommendation of a security audit of
10 the zlib code by Trail of Bits and TrustInSoft, in support of the
11 Mozilla Foundation, this "optimization" was removed, in order to
12 avoid the possibility of undefined behavior.
13 ---
14  inffast.c | 81 +++++++++++++++++++++----------------------------------
15  1 file changed, 31 insertions(+), 50 deletions(-)
16
17 diff --git a/zlib/inffast.c b/zlib/inffast.c
18 index bda59ceb..f0d163db 100644
19 --- a/zlib/inffast.c
20 +++ b/zlib/inffast.c
21 @@ -10,25 +10,6 @@
22  
23  #ifndef ASMINF
24  
25 -/* Allow machine dependent optimization for post-increment or pre-increment.
26 -   Based on testing to date,
27 -   Pre-increment preferred for:
28 -   - PowerPC G3 (Adler)
29 -   - MIPS R5000 (Randers-Pehrson)
30 -   Post-increment preferred for:
31 -   - none
32 -   No measurable difference:
33 -   - Pentium III (Anderson)
34 -   - M68060 (Nikl)
35 - */
36 -#ifdef POSTINC
37 -#  define OFF 0
38 -#  define PUP(a) *(a)++
39 -#else
40 -#  define OFF 1
41 -#  define PUP(a) *++(a)
42 -#endif
43 -
44  /*
45     Decode literal, length, and distance codes and write out the resulting
46     literal and match bytes until either not enough input or output is
47 @@ -96,9 +77,9 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
48  
49      /* copy state to local variables */
50      state = (struct inflate_state FAR *)strm->state;
51 -    in = strm->next_in - OFF;
52 +    in = strm->next_in;
53      last = in + (strm->avail_in - 5);
54 -    out = strm->next_out - OFF;
55 +    out = strm->next_out;
56      beg = out - (start - strm->avail_out);
57      end = out + (strm->avail_out - 257);
58  #ifdef INFLATE_STRICT
59 @@ -119,9 +100,9 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
60         input data or output space */
61      do {
62          if (bits < 15) {
63 -            hold += (unsigned long)(PUP(in)) << bits;
64 +            hold += (unsigned long)(*in++) << bits;
65              bits += 8;
66 -            hold += (unsigned long)(PUP(in)) << bits;
67 +            hold += (unsigned long)(*in++) << bits;
68              bits += 8;
69          }
70          here = lcode[hold & lmask];
71 @@ -134,14 +115,14 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
72              Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
73                      "inflate:         literal '%c'\n" :
74                      "inflate:         literal 0x%02x\n", here.val));
75 -            PUP(out) = (unsigned char)(here.val);
76 +            *out++ = (unsigned char)(here.val);
77          }
78          else if (op & 16) {                     /* length base */
79              len = (unsigned)(here.val);
80              op &= 15;                           /* number of extra bits */
81              if (op) {
82                  if (bits < op) {
83 -                    hold += (unsigned long)(PUP(in)) << bits;
84 +                    hold += (unsigned long)(*in++) << bits;
85                      bits += 8;
86                  }
87                  len += (unsigned)hold & ((1U << op) - 1);
88 @@ -150,9 +131,9 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
89              }
90              Tracevv((stderr, "inflate:         length %u\n", len));
91              if (bits < 15) {
92 -                hold += (unsigned long)(PUP(in)) << bits;
93 +                hold += (unsigned long)(*in++) << bits;
94                  bits += 8;
95 -                hold += (unsigned long)(PUP(in)) << bits;
96 +                hold += (unsigned long)(*in++) << bits;
97                  bits += 8;
98              }
99              here = dcode[hold & dmask];
100 @@ -165,10 +146,10 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
101                  dist = (unsigned)(here.val);
102                  op &= 15;                       /* number of extra bits */
103                  if (bits < op) {
104 -                    hold += (unsigned long)(PUP(in)) << bits;
105 +                    hold += (unsigned long)(*in++) << bits;
106                      bits += 8;
107                      if (bits < op) {
108 -                        hold += (unsigned long)(PUP(in)) << bits;
109 +                        hold += (unsigned long)(*in++) << bits;
110                          bits += 8;
111                      }
112                  }
113 @@ -196,30 +177,30 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
114  #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
115                          if (len <= op - whave) {
116                              do {
117 -                                PUP(out) = 0;
118 +                                *out++ = 0;
119                              } while (--len);
120                              continue;
121                          }
122                          len -= op - whave;
123                          do {
124 -                            PUP(out) = 0;
125 +                            *out++ = 0;
126                          } while (--op > whave);
127                          if (op == 0) {
128                              from = out - dist;
129                              do {
130 -                                PUP(out) = PUP(from);
131 +                                *out++ = *from++;
132                              } while (--len);
133                              continue;
134                          }
135  #endif
136                      }
137 -                    from = window - OFF;
138 +                    from = window;
139                      if (wnext == 0) {           /* very common case */
140                          from += wsize - op;
141                          if (op < len) {         /* some from window */
142                              len -= op;
143                              do {
144 -                                PUP(out) = PUP(from);
145 +                                *out++ = *from++;
146                              } while (--op);
147                              from = out - dist;  /* rest from output */
148                          }
149 @@ -230,14 +211,14 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
150                          if (op < len) {         /* some from end of window */
151                              len -= op;
152                              do {
153 -                                PUP(out) = PUP(from);
154 +                                *out++ = *from++;
155                              } while (--op);
156 -                            from = window - OFF;
157 +                            from = window;
158                              if (wnext < len) {  /* some from start of window */
159                                  op = wnext;
160                                  len -= op;
161                                  do {
162 -                                    PUP(out) = PUP(from);
163 +                                    *out++ = *from++;
164                                  } while (--op);
165                                  from = out - dist;      /* rest from output */
166                              }
167 @@ -248,35 +229,35 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
168                          if (op < len) {         /* some from window */
169                              len -= op;
170                              do {
171 -                                PUP(out) = PUP(from);
172 +                                *out++ = *from++;
173                              } while (--op);
174                              from = out - dist;  /* rest from output */
175                          }
176                      }
177                      while (len > 2) {
178 -                        PUP(out) = PUP(from);
179 -                        PUP(out) = PUP(from);
180 -                        PUP(out) = PUP(from);
181 +                        *out++ = *from++;
182 +                        *out++ = *from++;
183 +                        *out++ = *from++;
184                          len -= 3;
185                      }
186                      if (len) {
187 -                        PUP(out) = PUP(from);
188 +                        *out++ = *from++;
189                          if (len > 1)
190 -                            PUP(out) = PUP(from);
191 +                            *out++ = *from++;
192                      }
193                  }
194                  else {
195                      from = out - dist;          /* copy direct from output */
196                      do {                        /* minimum length is three */
197 -                        PUP(out) = PUP(from);
198 -                        PUP(out) = PUP(from);
199 -                        PUP(out) = PUP(from);
200 +                        *out++ = *from++;
201 +                        *out++ = *from++;
202 +                        *out++ = *from++;
203                          len -= 3;
204                      } while (len > 2);
205                      if (len) {
206 -                        PUP(out) = PUP(from);
207 +                        *out++ = *from++;
208                          if (len > 1)
209 -                            PUP(out) = PUP(from);
210 +                            *out++ = *from++;
211                      }
212                  }
213              }
214 @@ -313,8 +294,8 @@ unsigned start;         /* inflate()'s starting value for strm->avail_out */
215      hold &= (1U << bits) - 1;
216  
217      /* update state and return */
218 -    strm->next_in = in + OFF;
219 -    strm->next_out = out + OFF;
220 +    strm->next_in = in;
221 +    strm->next_out = out;
222      strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
223      strm->avail_out = (unsigned)(out < end ?
224                                   257 + (end - out) : 257 - (out - end));
This page took 0.110269 seconds and 2 git commands to generate.