]>
Commit | Line | Data |
---|---|---|
9a904337 SL |
1 | From f2c45d782fe6b7a85bc41ace11b38e0979dd1bea Mon Sep 17 00:00:00 2001 |
2 | From: Jia Guo <guojia12@huawei.com> | |
3 | Date: Tue, 5 Mar 2019 15:41:41 -0800 | |
4 | Subject: ocfs2: fix a panic problem caused by o2cb_ctl | |
5 | ||
6 | [ Upstream commit cc725ef3cb202ef2019a3c67c8913efa05c3cce6 ] | |
7 | ||
8 | In the process of creating a node, it will cause NULL pointer | |
9 | dereference in kernel if o2cb_ctl failed in the interval (mkdir, | |
10 | o2cb_set_node_attribute(node_num)] in function o2cb_add_node. | |
11 | ||
12 | The node num is initialized to 0 in function o2nm_node_group_make_item, | |
13 | o2nm_node_group_drop_item will mistake the node number 0 for a valid | |
14 | node number when we delete the node before the node number is set | |
15 | correctly. If the local node number of the current host happens to be | |
16 | 0, cluster->cl_local_node will be set to O2NM_INVALID_NODE_NUM while | |
17 | o2hb_thread still running. The panic stack is generated as follows: | |
18 | ||
19 | o2hb_thread | |
20 | \-o2hb_do_disk_heartbeat | |
21 | \-o2hb_check_own_slot | |
22 | |-slot = ®->hr_slots[o2nm_this_node()]; | |
23 | //o2nm_this_node() return O2NM_INVALID_NODE_NUM | |
24 | ||
25 | We need to check whether the node number is set when we delete the node. | |
26 | ||
27 | Link: http://lkml.kernel.org/r/133d8045-72cc-863e-8eae-5013f9f6bc51@huawei.com | |
28 | Signed-off-by: Jia Guo <guojia12@huawei.com> | |
29 | Reviewed-by: Joseph Qi <jiangqi903@gmail.com> | |
30 | Acked-by: Jun Piao <piaojun@huawei.com> | |
31 | Cc: Mark Fasheh <mark@fasheh.com> | |
32 | Cc: Joel Becker <jlbec@evilplan.org> | |
33 | Cc: Junxiao Bi <junxiao.bi@oracle.com> | |
34 | Cc: Changwei Ge <ge.changwei@h3c.com> | |
35 | Signed-off-by: Andrew Morton <akpm@linux-foundation.org> | |
36 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | |
37 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
38 | --- | |
39 | fs/ocfs2/cluster/nodemanager.c | 14 ++++++++------ | |
40 | 1 file changed, 8 insertions(+), 6 deletions(-) | |
41 | ||
42 | diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c | |
43 | index 441c84e169e6..059414bb19dc 100644 | |
44 | --- a/fs/ocfs2/cluster/nodemanager.c | |
45 | +++ b/fs/ocfs2/cluster/nodemanager.c | |
46 | @@ -721,13 +721,15 @@ static void o2nm_node_group_drop_item(struct config_group *group, | |
47 | struct o2nm_node *node = to_o2nm_node(item); | |
48 | struct o2nm_cluster *cluster = to_o2nm_cluster(group->cg_item.ci_parent); | |
49 | ||
50 | - o2net_disconnect_node(node); | |
51 | + if (cluster->cl_nodes[node->nd_num] == node) { | |
52 | + o2net_disconnect_node(node); | |
53 | ||
54 | - if (cluster->cl_has_local && | |
55 | - (cluster->cl_local_node == node->nd_num)) { | |
56 | - cluster->cl_has_local = 0; | |
57 | - cluster->cl_local_node = O2NM_INVALID_NODE_NUM; | |
58 | - o2net_stop_listening(node); | |
59 | + if (cluster->cl_has_local && | |
60 | + (cluster->cl_local_node == node->nd_num)) { | |
61 | + cluster->cl_has_local = 0; | |
62 | + cluster->cl_local_node = O2NM_INVALID_NODE_NUM; | |
63 | + o2net_stop_listening(node); | |
64 | + } | |
65 | } | |
66 | ||
67 | /* XXX call into net to stop this node from trading messages */ | |
68 | -- | |
69 | 2.19.1 | |
70 |