BUG/MINOR: map/cli: make sure patterns don't vanish under "show map"'s init

When "show map" initializes itself, it first takes the reference to the
starting point under a lock, then releases it before switching to state
STATE_LIST, and takes the lock again. The problem is that it is possible
for another thread to remove the first element during this unlock/lock
sequence, and make the list run anywhere. This is of course extremely
unlikely but not impossible.

Let's initialize the pointer in the STATE_LIST part under the same lock,
which is simpler and more reliable.

This should be backported to all versions.

(cherry picked from commit 1ae0c43244254a3cf652300413625191d6a9dd4f)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 33f525cfcb7429443e8ac5e7ff338b22dfb2d34d)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/src/map.c b/src/map.c
index 2da22e9..f482b77 100644
--- a/src/map.c
+++ b/src/map.c
@@ -344,27 +344,17 @@
 	switch (appctx->st2) {
 
 	case STAT_ST_INIT:
-		/* the function had not been called yet, let's prepare the
-		 * buffer for a response. We initialize the current stream
-		 * pointer to the first in the global list. When a target
-		 * stream is being destroyed, it is responsible for updating
-		 * this pointer. We know we have reached the end when this
-		 * pointer points back to the head of the streams list.
-		 */
-		HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
-		LIST_INIT(&appctx->ctx.map.bref.users);
-		appctx->ctx.map.bref.ref = appctx->ctx.map.ref->head.n;
-		HA_SPIN_UNLOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
 		appctx->st2 = STAT_ST_LIST;
 		/* fall through */
 
 	case STAT_ST_LIST:
-
 		HA_SPIN_LOCK(PATREF_LOCK, &appctx->ctx.map.ref->lock);
 
 		if (!LIST_ISEMPTY(&appctx->ctx.map.bref.users)) {
 			LIST_DELETE(&appctx->ctx.map.bref.users);
 			LIST_INIT(&appctx->ctx.map.bref.users);
+		} else {
+			appctx->ctx.map.bref.ref = appctx->ctx.map.ref->head.n;
 		}
 
 		while (appctx->ctx.map.bref.ref != &appctx->ctx.map.ref->head) {
@@ -716,6 +706,7 @@
 		else
 			appctx->ctx.cli.i0 = appctx->ctx.map.ref->curr_gen;
 
+		LIST_INIT(&appctx->ctx.map.bref.users);
 		appctx->io_handler = cli_io_handler_pat_list;
 		appctx->io_release = cli_release_show_map;
 		return 0;