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