mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-03-25 04:17:42 +00:00
BUG/MEDIUM: prevent gcc from moving empty keywords lists into BSS
Benoit Dolez reported a failure to start haproxy 1.5-dev19. The process would immediately report an internal error with missing fetches from some crap instead of ACL names. The cause is that some versions of gcc seem to trim static structs containing a variable array when moving them to BSS, and only keep the fixed size, which is just a list head for all ACL and sample fetch keywords. This was confirmed at least with gcc 3.4.6. And we can't move these structs to const because they contain a list element which is needed to link all of them together during the parsing. The bug indeed appeared with 1.5-dev19 because it's the first one to have some empty ACL keyword lists. One solution is to impose -fno-zero-initialized-in-bss to everyone but this is not really nice. Another solution consists in ensuring the struct is never empty so that it does not move there. The easy solution consists in having a non-null list head since it's not yet initialized. A new "ILH" list head type was thus created for this purpose : create an Initialized List Head so that gcc cannot move the struct to BSS. This fixes the issue for this version of gcc and does not create any burden for the declarations.
This commit is contained in:
parent
8615c2af67
commit
dc13c11c1e
@ -53,6 +53,12 @@ struct cond_wordlist {
|
||||
#undef LIST_INIT
|
||||
#undef LIST_NEXT
|
||||
|
||||
/* ILH = Initialized List Head : used to prevent gcc from moving an empty
|
||||
* list to BSS. Some older version tend to trim all the array and cause
|
||||
* corruption.
|
||||
*/
|
||||
#define ILH { .n = (struct list *)1, .p = (struct list *)2 }
|
||||
|
||||
#define LIST_HEAD(a) ((void *)(&(a)))
|
||||
|
||||
#define LIST_INIT(l) ((l)->n = (l)->p = (l))
|
||||
|
@ -2010,7 +2010,7 @@ smp_fetch_env(struct proxy *px, struct session *s, void *l7, unsigned int opt,
|
||||
* common denominator, the type that can be casted into all other ones. For
|
||||
* instance IPv4/IPv6 must be declared IPv4.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "always_false", smp_fetch_false, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
|
||||
{ "always_true", smp_fetch_true, 0, NULL, SMP_T_BOOL, SMP_USE_INTRN },
|
||||
{ "env", smp_fetch_env, ARG1(1,STR), NULL, SMP_T_CSTR, SMP_USE_INTRN },
|
||||
@ -2021,7 +2021,7 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
|
@ -1579,7 +1579,7 @@ smp_fetch_srv_sess_rate(struct proxy *px, struct session *l4, void *l7, unsigned
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "avg_queue", smp_fetch_avg_queue_size, ARG1(1,BE), NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
{ "be_conn", smp_fetch_be_conn, ARG1(1,BE), NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
{ "be_id", smp_fetch_be_id, 0, NULL, SMP_T_UINT, SMP_USE_BKEND, },
|
||||
@ -1598,7 +1598,7 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
|
@ -635,12 +635,12 @@ smp_fetch_res_comp_algo(struct proxy *px, struct session *l4, void *l7, unsigned
|
||||
}
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "res.comp", smp_fetch_res_comp, 0, NULL, SMP_T_BOOL, SMP_USE_HRSHP },
|
||||
{ "res.comp_algo", smp_fetch_res_comp_algo, 0, NULL, SMP_T_STR, SMP_USE_HRSHP },
|
||||
{ /* END */ },
|
||||
|
@ -4439,7 +4439,7 @@ static struct si_applet cli_applet = {
|
||||
.release = cli_release_handler,
|
||||
};
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {{ },{
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_GLOBAL, "stats", stats_parse_global },
|
||||
{ 0, NULL, NULL },
|
||||
}};
|
||||
|
@ -256,7 +256,7 @@ smp_fetch_fe_conn(struct proxy *px, struct session *l4, void *l7, unsigned int o
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "fe_conn", smp_fetch_fe_conn, ARG1(1,FE), NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
{ "fe_id", smp_fetch_fe_id, 0, NULL, SMP_T_UINT, SMP_USE_FTEND, },
|
||||
{ "fe_sess_rate", smp_fetch_fe_sess_rate, ARG1(1,FE), NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
@ -267,7 +267,7 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
|
@ -643,7 +643,7 @@ static int bind_parse_nice(char **args, int cur_arg, struct proxy *px, struct bi
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "dst_conn", smp_fetch_dconn, 0, NULL, SMP_T_UINT, SMP_USE_FTEND, },
|
||||
{ "so_id", smp_fetch_so_id, 0, NULL, SMP_T_UINT, SMP_USE_FTEND, },
|
||||
{ /* END */ },
|
||||
@ -652,7 +652,7 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
|
@ -650,7 +650,7 @@ static int val_payload_lv(struct arg *arg, char **err_msg)
|
||||
* common denominator, the type that can be casted into all other ones. For
|
||||
* instance IPv4/IPv6 must be declared IPv4.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
static struct sample_fetch_kw_list smp_kws = {ILH, {
|
||||
{ "payload", smp_fetch_payload, ARG2(2,UINT,UINT), val_payload, SMP_T_CBIN, SMP_USE_L6REQ|SMP_USE_L6RES },
|
||||
{ "payload_lv", smp_fetch_payload_lv, ARG3(2,UINT,UINT,SINT), val_payload_lv, SMP_T_CBIN, SMP_USE_L6REQ|SMP_USE_L6RES },
|
||||
{ "rdp_cookie", smp_fetch_rdp_cookie, ARG1(0,STR), NULL, SMP_T_CSTR, SMP_USE_L6REQ },
|
||||
@ -680,7 +680,7 @@ static struct sample_fetch_kw_list smp_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ "payload", "req.payload", acl_parse_str, acl_match_str },
|
||||
{ "payload_lv", "req.payload_lv", acl_parse_str, acl_match_str },
|
||||
{ "req_rdp_cookie", "req.rdp_cookie", acl_parse_str, acl_match_str },
|
||||
|
@ -10106,7 +10106,7 @@ static int val_hdr(struct arg *arg, char **err_msg)
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ "base", "base", acl_parse_str, acl_match_str },
|
||||
{ "base_beg", "base", acl_parse_str, acl_match_beg },
|
||||
{ "base_dir", "base", acl_parse_str, acl_match_dir },
|
||||
@ -10193,7 +10193,7 @@ static struct acl_kw_list acl_kws = {{ },{
|
||||
/* All supported pattern keywords must be declared here. */
|
||||
/************************************************************************/
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "base", smp_fetch_base, 0, NULL, SMP_T_CSTR, SMP_USE_HRQHV },
|
||||
{ "base32", smp_fetch_base32, 0, NULL, SMP_T_UINT, SMP_USE_HRQHV },
|
||||
{ "base32+src", smp_fetch_base32_src, 0, NULL, SMP_T_BIN, SMP_USE_HRQHV },
|
||||
|
@ -1731,7 +1731,7 @@ static int bind_parse_interface(char **args, int cur_arg, struct proxy *px, stru
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {{ },{
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_LISTEN, "tcp-request", tcp_parse_tcp_req },
|
||||
{ CFG_LISTEN, "tcp-response", tcp_parse_tcp_rep },
|
||||
{ 0, NULL, NULL },
|
||||
@ -1741,7 +1741,7 @@ static struct cfg_kw_list cfg_kws = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
@ -1751,7 +1751,7 @@ static struct acl_kw_list acl_kws = {{ },{
|
||||
* common denominator, the type that can be casted into all other ones. For
|
||||
* instance v4/v6 must be declared v4.
|
||||
*/
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "dst", smp_fetch_dst, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI },
|
||||
{ "dst_port", smp_fetch_dport, 0, NULL, SMP_T_UINT, SMP_USE_L4CLI },
|
||||
{ "src", smp_fetch_src, 0, NULL, SMP_T_IPV4, SMP_USE_L4CLI },
|
||||
|
@ -859,7 +859,7 @@ int session_set_backend(struct session *s, struct proxy *be)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct cfg_kw_list cfg_kws = {{ },{
|
||||
static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
{ CFG_LISTEN, "timeout", proxy_parse_timeout },
|
||||
{ CFG_LISTEN, "clitimeout", proxy_parse_timeout },
|
||||
{ CFG_LISTEN, "contimeout", proxy_parse_timeout },
|
||||
|
@ -1073,7 +1073,7 @@ static int sample_conv_ipmask(const struct arg *arg_p, struct sample *smp)
|
||||
}
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten */
|
||||
static struct sample_conv_kw_list sample_conv_kws = {{ },{
|
||||
static struct sample_conv_kw_list sample_conv_kws = {ILH, {
|
||||
{ "upper", sample_conv_str2upper, 0, NULL, SMP_T_STR, SMP_T_STR },
|
||||
{ "lower", sample_conv_str2lower, 0, NULL, SMP_T_STR, SMP_T_STR },
|
||||
{ "ipmask", sample_conv_ipmask, ARG1(1,MSK4), NULL, SMP_T_IPV4, SMP_T_IPV4 },
|
||||
|
@ -3938,14 +3938,14 @@ smp_fetch_table_avl(struct proxy *px, struct session *l4, void *l7, unsigned int
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ /* END */ },
|
||||
}};
|
||||
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct sample_fetch_kw_list smp_fetch_keywords = {{ },{
|
||||
static struct sample_fetch_kw_list smp_fetch_keywords = {ILH, {
|
||||
{ "sc0_bytes_in_rate", smp_fetch_sc0_bytes_in_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
{ "sc0_bytes_out_rate", smp_fetch_sc0_bytes_out_rate, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
{ "sc0_clr_gpc0", smp_fetch_sc0_clr_gpc0, 0, NULL, SMP_T_UINT, SMP_USE_INTRN, },
|
||||
|
@ -3080,7 +3080,7 @@ static int srv_parse_verify(char **args, int *cur_arg, struct proxy *px, struct
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
|
||||
{ "ssl_c_ca_err", smp_fetch_ssl_c_ca_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
|
||||
{ "ssl_c_ca_err_depth", smp_fetch_ssl_c_ca_err_depth, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
|
||||
{ "ssl_c_err", smp_fetch_ssl_c_err, 0, NULL, SMP_T_UINT, SMP_USE_L5CLI },
|
||||
@ -3124,7 +3124,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {{ },{
|
||||
/* Note: must not be declared <const> as its list will be overwritten.
|
||||
* Please take care of keeping this list alphabetically sorted.
|
||||
*/
|
||||
static struct acl_kw_list acl_kws = {{ },{
|
||||
static struct acl_kw_list acl_kws = {ILH, {
|
||||
{ "ssl_c_i_dn", NULL, acl_parse_str, acl_match_str },
|
||||
{ "ssl_c_key_alg", NULL, acl_parse_str, acl_match_str },
|
||||
{ "ssl_c_notafter", NULL, acl_parse_str, acl_match_str },
|
||||
|
Loading…
Reference in New Issue
Block a user