Browse code

Forward-port the I/O wrapping code Dave Raynor wrote to fix an older bug that happened in the hashing code

Shawn Webb authored on 2014/11/20 05:15:04
Showing 3 changed files
... ...
@@ -60,11 +60,22 @@
60 60
 #include "others.h"
61 61
 #include "libclamav/conv.h"
62 62
 #include "libclamav/str.h"
63
+#include "iowrap.h"
63 64
 
64 65
 #if defined(_WIN32)
65 66
 char * strptime(const char *buf, const char *fmt, struct tm *tm);
66 67
 #endif
67 68
 
69
+#if defined(_WIN32)
70
+#define EXCEPTION_PREAMBLE __try {
71
+#define EXCEPTION_POSTAMBLE } __except (filter_memcpy(GetExceptionCode(), GetExceptionInformation())) { \
72
+    winres=1; \
73
+}
74
+#else
75
+#define EXCEPTION_PREAMBLE
76
+#define EXCEPTION_POSTAMBLE
77
+#endif
78
+
68 79
 #if !defined(MIN)
69 80
     #define MIN(x,y) ((x)<(y)?(x):(y))
70 81
 #endif
... ...
@@ -132,6 +143,7 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
132 132
     const EVP_MD *md;
133 133
     unsigned int i;
134 134
     size_t cur;
135
+    int winres=0;
135 136
 
136 137
     md = EVP_get_digestbyname(alg);
137 138
     if (!(md))
... ...
@@ -170,6 +182,8 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
170 170
     cur=0;
171 171
     while (cur < len) {
172 172
         size_t todo = MIN((unsigned long)EVP_MD_block_size(md), (unsigned long)(len-cur));
173
+
174
+        EXCEPTION_PREAMBLE
173 175
         if (!EVP_DigestUpdate(ctx, (void *)(((unsigned char *)buf)+cur), todo)) {
174 176
             if (!(obuf))
175 177
                 free(ret);
... ...
@@ -180,6 +194,18 @@ unsigned char *cl_hash_data(char *alg, const void *buf, size_t len, unsigned cha
180 180
             EVP_MD_CTX_destroy(ctx);
181 181
             return NULL;
182 182
         }
183
+        EXCEPTION_POSTAMBLE
184
+
185
+        if (winres) {
186
+            if (!(obuf))
187
+                free(ret);
188
+
189
+            if ((olen))
190
+                *olen = 0;
191
+
192
+            EVP_MD_CTX_destroy(ctx);
193
+            return NULL;
194
+        }
183 195
 
184 196
         cur += todo;
185 197
     }
... ...
@@ -240,6 +266,7 @@ unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen)
240 240
     int mdsz;
241 241
     unsigned int hashlen;
242 242
     STATBUF sb;
243
+    int winres=0;
243 244
 
244 245
 	unsigned int blocksize;
245 246
 
... ...
@@ -277,12 +304,21 @@ unsigned char *cl_hash_file_fd_ctx(EVP_MD_CTX *ctx, int fd, unsigned int *olen)
277 277
 #else
278 278
     while ((nread = read(fd, buf, blocksize)) > 0) {
279 279
 #endif
280
+        EXCEPTION_PREAMBLE
280 281
         if (!EVP_DigestUpdate(ctx, buf, nread)) {
281 282
             free(buf);
282 283
             free(hash);
283 284
 
284 285
             return NULL;
285 286
         }
287
+        EXCEPTION_POSTAMBLE
288
+
289
+        if (winres) {
290
+            free(buf);
291
+            free(hash);
292
+
293
+            return NULL;
294
+        }
286 295
     }
287 296
 
288 297
     if (!EVP_DigestFinal_ex(ctx, hash, &hashlen)) {
... ...
@@ -1123,11 +1159,18 @@ void *cl_hash_init(const char *alg)
1123 1123
 
1124 1124
 int cl_update_hash(void *ctx, void *data, size_t sz)
1125 1125
 {
1126
+    int winres=0;
1127
+
1126 1128
     if (!(ctx) || !(data))
1127 1129
         return -1;
1128 1130
 
1131
+    EXCEPTION_PREAMBLE
1129 1132
     if (!EVP_DigestUpdate((EVP_MD_CTX *)ctx, data, sz))
1130 1133
         return -1;
1134
+    EXCEPTION_POSTAMBLE
1135
+
1136
+    if (winres)
1137
+        return -1;
1131 1138
 
1132 1139
     return 0;
1133 1140
 }
... ...
@@ -33,7 +33,7 @@
33 33
 #endif
34 34
 
35 35
 #ifdef _WIN32
36
-static int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
36
+int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep) {
37 37
     if ((code == EXCEPTION_IN_PAGE_ERROR) || (code == STATUS_DEVICE_DATA_ERROR)) {
38 38
         return EXCEPTION_EXECUTE_HANDLER;
39 39
     }
... ...
@@ -42,4 +42,8 @@
42 42
  */
43 43
 int cli_memcpy(void *target, const void *source, unsigned long size);
44 44
 
45
+#ifdef _WIN32
46
+int filter_memcpy(unsigned int code, struct _EXCEPTION_POINTERS *ep);
47
+#endif
48
+
45 49
 #endif