]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: ssl: ckch_inst wrongly inserted in crtlist_entry
authorWilliam Lallemand <wlallemand@haproxy.com>
Mon, 30 Mar 2020 15:01:33 +0000 (17:01 +0200)
committerWilliam Lallemand <wlallemand@haproxy.org>
Tue, 31 Mar 2020 10:32:17 +0000 (12:32 +0200)
The instances were wrongly inserted in the crtlist entries, all
instances of a crt-list were inserted in the last crt-list entry.
Which was kind of handy to free all instances upon error.

Now that it's done correctly, the error path was changed, it must
iterate on the entries and find the ckch_insts which were generated for
this bind_conf. To avoid wasting time, it stops the iteration once it
found the first unsuccessful generation.

include/types/ssl_sock.h
src/ssl_sock.c

index e5d676db89b97e379b8a3849d7e0f212dbf7927e..2f366fc3556aa410c677131870125e426222f69d 100644 (file)
@@ -166,7 +166,7 @@ struct crtlist_entry {
        unsigned int linenum;
        unsigned int fcount; /* filters count */
        char **filters;
-       struct list ckch_inst; /* list of instances of this entry */
+       struct list ckch_inst; /* list of instances of this entry, there is 1 ckch_inst per instance of the crt-list */
        struct list by_crtlist; /* ordered entries */
        struct ebpt_node node; /* key is a ptr to a ckch_store */
 };
index f21c4b9d38cc041ec880c9ce31be7d844fd2f305..e8d64c9ca041ce05e546352beae396ef6f69f7d4 100644 (file)
@@ -4896,13 +4896,10 @@ int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_con
 {
        struct crtlist *crtlist = NULL;
        struct ebmb_node *eb;
-       struct crtlist_entry *entry;
-       struct list instances; /* temporary list head */
+       struct crtlist_entry *entry = NULL;
        struct bind_conf_list *bind_conf_node = NULL;
        int cfgerr = 0;
 
-       LIST_INIT(&instances);
-
        bind_conf_node = malloc(sizeof(*bind_conf_node));
        if (!bind_conf_node) {
                memprintf(err, "%sCan't alloc memory!\n", err && *err ? *err : "");
@@ -4943,10 +4940,8 @@ int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_con
                        memprintf(err, "error processing line %d in file '%s' : %s", entry->linenum, file, *err);
                        goto error;
                }
-               LIST_ADDQ(&instances, &ckch_inst->by_crtlist_entry);
+               LIST_ADDQ(&entry->ckch_inst, &ckch_inst->by_crtlist_entry);
        }
-       /* add the instances to the actual instance list in the crtlist_entry */
-       LIST_SPLICE(&entry->ckch_inst, &instances);
 
        /* add the bind_conf to the list */
        bind_conf_node->next = crtlist->bind_conf;
@@ -4955,19 +4950,32 @@ int ssl_sock_load_cert_list_file(char *file, int dir, struct bind_conf *bind_con
        return cfgerr;
 error:
        {
+               struct crtlist_entry *lastentry;
                struct ckch_inst *inst, *s_inst;
 
-               list_for_each_entry_safe(inst, s_inst, &instances, by_crtlist_entry) {
-                       struct sni_ctx *sni, *s_sni;
+               lastentry = entry; /* which entry we tried to generate last */
+               if (lastentry) {
+                       list_for_each_entry(entry, &crtlist->ord_entries, by_crtlist) {
+                               if (entry == lastentry) /* last entry we tried to generate, no need to go further */
+                                       break;
+
+                               list_for_each_entry_safe(inst, s_inst, &entry->ckch_inst, by_crtlist_entry) {
+                                       struct sni_ctx *sni, *s_sni;
 
-                       /* free the sni_ctx */
-                       list_for_each_entry_safe(sni, s_sni, &inst->sni_ctx, by_ckch_inst) {
-                               ebmb_delete(&sni->name);
-                               LIST_DEL(&sni->by_ckch_inst);
-                               free(sni);
+                                       /* this was not generated for this bind_conf, skip */
+                                       if (inst->bind_conf != bind_conf)
+                                               continue;
+
+                                       /* free the sni_ctx */
+                                       list_for_each_entry_safe(sni, s_sni, &inst->sni_ctx, by_ckch_inst) {
+                                               ebmb_delete(&sni->name);
+                                               LIST_DEL(&sni->by_ckch_inst);
+                                               free(sni);
+                                       }
+                                       LIST_DEL(&inst->by_crtlist_entry);
+                                       free(inst);
+                               }
                        }
-                       LIST_DEL(&inst->by_crtlist_entry);
-                       free(inst);
                }
                free(bind_conf_node);
        }