package: haproxy
[packages.git] / net / haproxy / patches / 0015-BUG-MAJOR-cli-show-sess-id-may-randomly-corrup-1.4.22.diff
1 From 475b5ec3be8e022bd0f96331efc14c7b7b137d60 Mon Sep 17 00:00:00 2001
2 From: Willy Tarreau <w@1wt.eu>
3 Date: Mon, 26 Nov 2012 02:22:40 +0100
4 Subject: BUG/MAJOR: cli: show sess <id> may randomly corrupt the back-ref list
5
6 show sess <id> puts a backref into the session it's dumping. If the output
7 is interrupted, the backref cannot always be removed because it's only done
8 in the I/O handler. This can randomly corrupt the backref list when the
9 session closes, because it passes the pointer to the next session which
10 itself might be watched.
11
12 The case is hard to reproduce (hundreds of attempts) but monitoring systems
13 might encounter it frequently.
14
15 Thus we have to add a release handler which does the cleanup even when the
16 I/O handler is not called.
17
18 This issue should also be present in 1.4 so the patch should be backported.
19 (cherry picked from commit 5f9a8779b3d4fb324dacc1daacfb478bd12963d1)
20
21 NOTE: In 1.4 there is no release function so we have to hard-code the
22 release in session.c when the condition is encountered.
23 ---
24  src/session.c |   15 +++++++++++++++
25  1 files changed, 15 insertions(+), 0 deletions(-)
26
27 diff --git a/src/session.c b/src/session.c
28 index 0f6a1cf..239d4f5 100644
29 --- a/src/session.c
30 +++ b/src/session.c
31 @@ -989,6 +989,21 @@ resync_stream_interface:
32                         if (may_dequeue_tasks(s->srv, s->be))
33                                 process_srv_queue(s->srv);
34                 }
35 +
36 +               if (s->req->cons->iohandler == stats_io_handler &&
37 +                   s->req->cons->st0 == STAT_CLI_O_SESS && s->data_state == DATA_ST_LIST) {
38 +                       /* This is a fix for a design bug in the stats I/O handler :
39 +                        * "show sess $sess" may corrupt the struct session if not
40 +                        * properly detached. Unfortunately, in 1.4 there is no way
41 +                        * to ensure we always cleanly unregister an I/O handler upon
42 +                        * error. So we're doing the cleanup here if we can detect the
43 +                        * situation.
44 +                        */
45 +                       if (!LIST_ISEMPTY(&s->data_ctx.sess.bref.users)) {
46 +                               LIST_DEL(&s->data_ctx.sess.bref.users);
47 +                               LIST_INIT(&s->data_ctx.sess.bref.users);
48 +                       }
49 +               }
50         }
51  
52         /*
53 -- 
54 1.7.1
55