]> git.99rst.org Git - openwrt-packages.git/blob
c69f874d35a3993e8199096c79dd0a74790a060c
[openwrt-packages.git] /
1 commit 0dbaa252df906cc9c1d0dc7a075c16e039ab1c5b
2 Author: Willy Tarreau <w@1wt.eu>
3 Date: Tue Aug 21 15:35:31 2018 +0200
4
5 BUG/MEDIUM: cli/threads: protect some server commands against concurrent operations
6
7 The server-specific CLI commands "set weight", "set maxconn",
8 "disable agent", "enable agent", "disable health", "enable health",
9 "disable server" and "enable server" were not protected against
10 concurrent accesses. Now they take the server lock around the
11 sensitive part.
12
13 This patch must be backported to 1.8.
14
15 (cherry picked from commit 3bcc2699ba08dd3971ae7a56631994b2524d2acb)
16 Signed-off-by: Willy Tarreau <w@1wt.eu>
17
18 diff --git a/src/server.c b/src/server.c
19 index 36a05e27..98dae535 100644
20 --- a/src/server.c
21 +++ b/src/server.c
22 @@ -4299,6 +4299,10 @@ static int cli_parse_get_weight(char **args, struct appctx *appctx, void *privat
23 return 1;
24 }
25
26 +/* Parse a "set weight" command.
27 + *
28 + * Grabs the server lock.
29 + */
30 static int cli_parse_set_weight(char **args, struct appctx *appctx, void *private)
31 {
32 struct server *sv;
33 @@ -4311,16 +4315,24 @@ static int cli_parse_set_weight(char **args, struct appctx *appctx, void *privat
34 if (!sv)
35 return 1;
36
37 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
38 +
39 warning = server_parse_weight_change_request(sv, args[3]);
40 if (warning) {
41 appctx->ctx.cli.severity = LOG_ERR;
42 appctx->ctx.cli.msg = warning;
43 appctx->st0 = CLI_ST_PRINT;
44 }
45 +
46 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
47 +
48 return 1;
49 }
50
51 -/* parse a "set maxconn server" command. It always returns 1. */
52 +/* parse a "set maxconn server" command. It always returns 1.
53 + *
54 + * Grabs the server lock.
55 + */
56 static int cli_parse_set_maxconn_server(char **args, struct appctx *appctx, void *private)
57 {
58 struct server *sv;
59 @@ -4333,16 +4345,24 @@ static int cli_parse_set_maxconn_server(char **args, struct appctx *appctx, void
60 if (!sv)
61 return 1;
62
63 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
64 +
65 warning = server_parse_maxconn_change_request(sv, args[4]);
66 if (warning) {
67 appctx->ctx.cli.severity = LOG_ERR;
68 appctx->ctx.cli.msg = warning;
69 appctx->st0 = CLI_ST_PRINT;
70 }
71 +
72 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
73 +
74 return 1;
75 }
76
77 -/* parse a "disable agent" command. It always returns 1. */
78 +/* parse a "disable agent" command. It always returns 1.
79 + *
80 + * Grabs the server lock.
81 + */
82 static int cli_parse_disable_agent(char **args, struct appctx *appctx, void *private)
83 {
84 struct server *sv;
85 @@ -4354,11 +4374,16 @@ static int cli_parse_disable_agent(char **args, struct appctx *appctx, void *pri
86 if (!sv)
87 return 1;
88
89 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
90 sv->agent.state &= ~CHK_ST_ENABLED;
91 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
92 return 1;
93 }
94
95 -/* parse a "disable health" command. It always returns 1. */
96 +/* parse a "disable health" command. It always returns 1.
97 + *
98 + * Grabs the server lock.
99 + */
100 static int cli_parse_disable_health(char **args, struct appctx *appctx, void *private)
101 {
102 struct server *sv;
103 @@ -4370,11 +4395,16 @@ static int cli_parse_disable_health(char **args, struct appctx *appctx, void *pr
104 if (!sv)
105 return 1;
106
107 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
108 sv->check.state &= ~CHK_ST_ENABLED;
109 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
110 return 1;
111 }
112
113 -/* parse a "disable server" command. It always returns 1. */
114 +/* parse a "disable server" command. It always returns 1.
115 + *
116 + * Grabs the server lock.
117 + */
118 static int cli_parse_disable_server(char **args, struct appctx *appctx, void *private)
119 {
120 struct server *sv;
121 @@ -4386,11 +4416,16 @@ static int cli_parse_disable_server(char **args, struct appctx *appctx, void *pr
122 if (!sv)
123 return 1;
124
125 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
126 srv_adm_set_maint(sv);
127 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
128 return 1;
129 }
130
131 -/* parse a "enable agent" command. It always returns 1. */
132 +/* parse a "enable agent" command. It always returns 1.
133 + *
134 + * Grabs the server lock.
135 + */
136 static int cli_parse_enable_agent(char **args, struct appctx *appctx, void *private)
137 {
138 struct server *sv;
139 @@ -4409,11 +4444,16 @@ static int cli_parse_enable_agent(char **args, struct appctx *appctx, void *priv
140 return 1;
141 }
142
143 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
144 sv->agent.state |= CHK_ST_ENABLED;
145 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
146 return 1;
147 }
148
149 -/* parse a "enable health" command. It always returns 1. */
150 +/* parse a "enable health" command. It always returns 1.
151 + *
152 + * Grabs the server lock.
153 + */
154 static int cli_parse_enable_health(char **args, struct appctx *appctx, void *private)
155 {
156 struct server *sv;
157 @@ -4425,11 +4465,16 @@ static int cli_parse_enable_health(char **args, struct appctx *appctx, void *pri
158 if (!sv)
159 return 1;
160
161 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
162 sv->check.state |= CHK_ST_ENABLED;
163 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
164 return 1;
165 }
166
167 -/* parse a "enable server" command. It always returns 1. */
168 +/* parse a "enable server" command. It always returns 1.
169 + *
170 + * Grabs the server lock.
171 + */
172 static int cli_parse_enable_server(char **args, struct appctx *appctx, void *private)
173 {
174 struct server *sv;
175 @@ -4441,11 +4486,13 @@ static int cli_parse_enable_server(char **args, struct appctx *appctx, void *pri
176 if (!sv)
177 return 1;
178
179 + HA_SPIN_LOCK(SERVER_LOCK, &sv->lock);
180 srv_adm_set_ready(sv);
181 if (!(sv->flags & SRV_F_COOKIESET)
182 && (sv->proxy->ck_opts & PR_CK_DYNAMIC) &&
183 sv->cookie)
184 srv_check_for_dup_dyncookie(sv);
185 + HA_SPIN_UNLOCK(SERVER_LOCK, &sv->lock);
186 return 1;
187 }
188
git clone https://git.99rst.org/PROJECT