annotate src/http/ngx_http_upstream_round_robin.h @ 6359:dac6eda40475 stable-1.8

Resolver: fixed use-after-free memory accesses with CNAME. When several requests were waiting for a response, then after getting a CNAME response only the last request's context had the name updated. Contexts of other requests had the wrong name. This name was used by ngx_resolve_name_done() to find the node to remove the request context from. When the name was wrong, the request could not be properly cancelled, its context was freed but stayed linked to the node's waiting list. This happened e.g. when the first request was aborted or timed out before the resolving completed. When it completed, this triggered a use-after-free memory access by calling ctx->handler of already freed request context. The bug manifests itself by "could not cancel <name> resolving" alerts in error_log. When a request was responded with a CNAME, the request context kept the pointer to the original node's rn->u.cname. If the original node expired before the resolving timed out or completed with an error, this would trigger a use-after-free memory access via ctx->name in ctx->handler(). The fix is to keep ctx->name unmodified. The name from context is no longer used by ngx_resolve_name_done(). Instead, we now keep the pointer to resolver node to which this request is linked. Keeping the original name intact also improves logging.
author Roman Arutyunyan <arut@nginx.com>
date Tue, 26 Jan 2016 16:46:59 +0300
parents 94ce52db3367
children 6ff0ebd6fbf4
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
4412
d620f497c50f Copyright updated.
Maxim Konovalov <maxim@nginx.com>
parents: 4207
diff changeset
4 * Copyright (C) Nginx, Inc.
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5 */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #ifndef _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #define _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12 #include <ngx_config.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 #include <ngx_core.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 #include <ngx_http.h>
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17 typedef struct {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 struct sockaddr *sockaddr;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 socklen_t socklen;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20 ngx_str_t name;
5717
efc84a5723b3 Upstream: generic hash module.
Roman Arutyunyan <arut@nginx.com>
parents: 5136
diff changeset
21 ngx_str_t server;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22
1344
8f5b5641966c fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
23 ngx_int_t current_weight;
4621
c90801720a0c Upstream: smooth weighted round-robin balancing.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4412
diff changeset
24 ngx_int_t effective_weight;
1344
8f5b5641966c fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
25 ngx_int_t weight;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27 ngx_uint_t fails;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28 time_t accessed;
4207
4fc91bae6f83 Better recheck of dead upstream servers.
Maxim Dounin <mdounin@mdounin.ru>
parents: 3264
diff changeset
29 time_t checked;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31 ngx_uint_t max_fails;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 time_t fail_timeout;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 ngx_uint_t down; /* unsigned down:1; */
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35
1344
8f5b5641966c fair upstream weight balancer
Igor Sysoev <igor@sysoev.ru>
parents: 1284
diff changeset
36 #if (NGX_HTTP_SSL)
1284
be2b895d31e0 fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents: 954
diff changeset
37 ngx_ssl_session_t *ssl_session; /* local to a process */
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 #endif
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 } ngx_http_upstream_rr_peer_t;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41
1378
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
42 typedef struct ngx_http_upstream_rr_peers_s ngx_http_upstream_rr_peers_t;
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
43
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
44 struct ngx_http_upstream_rr_peers_s {
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 ngx_uint_t number;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46
4655
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4621
diff changeset
47 ngx_uint_t total_weight;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4621
diff changeset
48
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4621
diff changeset
49 unsigned single:1;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4621
diff changeset
50 unsigned weighted:1;
382c523d253a Upstream: weights support in ip_hash balancer.
Maxim Dounin <mdounin@mdounin.ru>
parents: 4621
diff changeset
51
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52 ngx_str_t *name;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53
1378
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
54 ngx_http_upstream_rr_peers_t *next;
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
55
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56 ngx_http_upstream_rr_peer_t peer[1];
1378
0be898896d1a backup upstream servers
Igor Sysoev <igor@sysoev.ru>
parents: 1344
diff changeset
57 };
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 typedef struct {
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 ngx_http_upstream_rr_peers_t *peers;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62 ngx_uint_t current;
954
f16424aa5d89 style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents: 884
diff changeset
63 uintptr_t *tried;
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 uintptr_t data;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 } ngx_http_upstream_rr_peer_data_t;
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 ngx_int_t ngx_http_upstream_init_round_robin(ngx_conf_t *cf,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 ngx_http_upstream_srv_conf_t *us);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 ngx_int_t ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71 ngx_http_upstream_srv_conf_t *us);
1658
13f8dec720b5 proxy_pass variables support
Igor Sysoev <igor@sysoev.ru>
parents: 1378
diff changeset
72 ngx_int_t ngx_http_upstream_create_round_robin_peer(ngx_http_request_t *r,
13f8dec720b5 proxy_pass variables support
Igor Sysoev <igor@sysoev.ru>
parents: 1378
diff changeset
73 ngx_http_upstream_resolved_t *ur);
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 ngx_int_t ngx_http_upstream_get_round_robin_peer(ngx_peer_connection_t *pc,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 void *data);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 void ngx_http_upstream_free_round_robin_peer(ngx_peer_connection_t *pc,
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 void *data, ngx_uint_t state);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79 #if (NGX_HTTP_SSL)
1284
be2b895d31e0 fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents: 954
diff changeset
80 ngx_int_t
be2b895d31e0 fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents: 954
diff changeset
81 ngx_http_upstream_set_round_robin_peer_session(ngx_peer_connection_t *pc,
be2b895d31e0 fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents: 954
diff changeset
82 void *data);
be2b895d31e0 fix segfault when session was freed twice
Igor Sysoev <igor@sysoev.ru>
parents: 954
diff changeset
83 void ngx_http_upstream_save_round_robin_peer_session(ngx_peer_connection_t *pc,
884
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 void *data);
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85 #endif
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87
4d68c486fcb0 upstream choice modules
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 #endif /* _NGX_HTTP_UPSTREAM_ROUND_ROBIN_H_INCLUDED_ */