Pārlūkot izejas kodu

Fix crash if a read event occur and the request args have been deleted

This could happen with the upload module if for a reason the upload
is aborted. In this case an internal redirect is done, but the request
still contains our read even handler.
Unfortunately the request args are nullified before calling this read
even handler. So we were crashing because we didn't check for id==null.
This patch fixes this issue.

Signed-off-by: Brice Figureau <brice@daysofwonder.com>
tags/v0.7
Brice Figureau 16 gadus atpakaļ
vecāks
revīzija
ddca3a78af
1 mainītis faili ar 27 papildinājumiem un 16 dzēšanām
  1. 27
    16
      ngx_http_uploadprogress_module.c

+ 27
- 16
ngx_http_uploadprogress_module.c Parādīt failu

131
     ngx_uint_t                       i;
131
     ngx_uint_t                       i;
132
     ngx_list_part_t                 *part;
132
     ngx_list_part_t                 *part;
133
     ngx_table_elt_t                 *header;
133
     ngx_table_elt_t                 *header;
134
-    ngx_str_t                       *ret;
134
+    ngx_str_t                       *ret, args;
135
 
135
 
136
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upload-progress: get_tracking_id");
136
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "upload-progress: get_tracking_id");
137
 
137
 
165
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
165
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
166
                     "upload-progress: get_tracking_id no header found");
166
                     "upload-progress: get_tracking_id no header found");
167
 
167
 
168
-    /* not found, check as a reaquest arg */
169
-    if (r->args.len) {
168
+    /* not found, check as a request arg */
169
+    /* it is possible the request args have not been yet created (or already released) */
170
+    /* so let's try harder first from the request line */
171
+    args.len =  r->args.len;
172
+    args.data = r->args.data;
173
+    
174
+    if (args.len && args.data) {
170
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
175
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
171
-                       "upload-progress: get_tracking_id no header found but args present");
176
+                       "upload-progress: get_tracking_id no header found, args found");
172
         i = 0;
177
         i = 0;
173
-        p = r->args.data;
178
+        p = args.data;
174
         do {
179
         do {
175
-            ngx_uint_t len = r->args.len - (p - r->args.data);
180
+            ngx_uint_t len = args.len - (p - args.data);
176
             if (len >= 14 && ngx_strncasecmp(p, (u_char*)"X-Progress-ID=", 14) == 0) {
181
             if (len >= 14 && ngx_strncasecmp(p, (u_char*)"X-Progress-ID=", 14) == 0) {
177
               ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
182
               ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 
178
                              "upload-progress: get_tracking_id found args: %s",p);
183
                              "upload-progress: get_tracking_id found args: %s",p);
186
 
191
 
187
         if (i) {
192
         if (i) {
188
             start_p = p += 14;
193
             start_p = p += 14;
189
-            while (p < r->args.data + r->args.len) {
194
+            while (p < args.data + args.len) {
190
                 if (*p++ != '&') {
195
                 if (*p++ != '&') {
191
                     continue;
196
                     continue;
192
                 }
197
                 }
321
 
326
 
322
     /* find node, update rest */
327
     /* find node, update rest */
323
     oldid = id = get_tracking_id(r);
328
     oldid = id = get_tracking_id(r);
324
-    
329
+
330
+    if (id == NULL) {
331
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
332
+                       "upload-progress: read_event_handler cant find id");
333
+        return;
334
+    }
335
+
325
     /* perform a deep copy of id */
336
     /* perform a deep copy of id */
326
     id = ngx_http_uploadprogress_strdup(id, r->connection->log);
337
     id = ngx_http_uploadprogress_strdup(id, r->connection->log);
327
-    
328
     ngx_free(oldid);
338
     ngx_free(oldid);
329
-		
339
+
330
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
340
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
331
                    "upload-progress: read_event_handler found id: %V", id);
341
                    "upload-progress: read_event_handler found id: %V", id);
332
     upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
342
     upcf = ngx_http_get_module_loc_conf(r, ngx_http_uploadprogress_module);
334
     
344
     
335
     /* call the original read event handler */
345
     /* call the original read event handler */
336
     module_ctx = ngx_http_get_module_ctx(r, ngx_http_uploadprogress_module);
346
     module_ctx = ngx_http_get_module_ctx(r, ngx_http_uploadprogress_module);
337
-    module_ctx->read_event_handler(r);
347
+    if (module_ctx != NULL ) {
348
+        module_ctx->read_event_handler(r);
349
+    }
338
 
350
 
339
     /* at this stage, r is not anymore safe to use */
351
     /* at this stage, r is not anymore safe to use */
340
     /* the request could have been closed/freed behind our back */
352
     /* the request could have been closed/freed behind our back */
341
     /* and thats the same issue with any other material that was allocated in the request pool */
353
     /* and thats the same issue with any other material that was allocated in the request pool */
342
     /* that's why we duplicate id afterward */
354
     /* that's why we duplicate id afterward */
343
 
355
 
344
-    if (id == NULL) {
345
-        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0,
346
-                       "upload-progress: read_event_handler cant find id");
347
-        return;
348
-    }
356
+    /* it's also possible that the id was null if we got a spurious (like abort) read */
357
+    /* event. In this case we still have called the original read event handler */
358
+    /* but we have to bail out, because we won't ever be able to find our upload node */
359
+
349
 
360
 
350
     if (shm_zone == NULL) {
361
     if (shm_zone == NULL) {
351
         ngx_http_uploadprogress_strdupfree(id);
362
         ngx_http_uploadprogress_strdupfree(id);

Notiek ielāde…
Atcelt
Saglabāt