diff options
author | jason.lau <Haitao.Liu@windriver.com> | 2020-07-03 17:28:26 +0800 |
---|---|---|
committer | Bruce Ashfield <bruce.ashfield@gmail.com> | 2020-07-06 16:29:00 -0400 |
commit | ffd787fb850e5a1657a01febc8402c74832147a1 (patch) | |
tree | 960e42d790e86f44a1309345c3265c681d8415f3 | |
parent | 5c2de3daedd3f65171b9debf938683ce6e7746ea (diff) | |
download | meta-virtualization-ffd787fb850e5a1657a01febc8402c74832147a1.tar.gz |
ceph: fix CVE-2020-10736
An authorization bypass vulnerability was found in Ceph versions 15.2.0 before 15.2.2,
where the ceph-mon and ceph-mgr daemons do not properly restrict access, resulting in
gaining access to unauthorized resources. This flaw allows an authenticated client to
modify the configuration and possibly conduct further attacks.
Upstream patches:
[master] https://github.com/ceph/ceph/commit/c7e7009a690621aacd4ac2c70c6469f25d692868
[v15.2.2] https://github.com/ceph/ceph/commit/f2cf2ce1bd9a86462510a7a12afa4e528b615df2
CVE: CVE-2020-10736
Signed-off-by: Liu Haitao <haitao.liu@windriver.com>
Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
4 files changed, 229 insertions, 0 deletions
diff --git a/recipes-extended/ceph/ceph/0001-mgr-require-all-caps-for-pre-octopus-tell-commands.patch b/recipes-extended/ceph/ceph/0001-mgr-require-all-caps-for-pre-octopus-tell-commands.patch new file mode 100644 index 00000000..de191bf8 --- /dev/null +++ b/recipes-extended/ceph/ceph/0001-mgr-require-all-caps-for-pre-octopus-tell-commands.patch | |||
@@ -0,0 +1,100 @@ | |||
1 | From de67c1dab5597c91538970421b25f6ec667af492 Mon Sep 17 00:00:00 2001 | ||
2 | From: Josh Durgin <jdurgin@redhat.com> | ||
3 | Date: Mon, 4 May 2020 17:03:35 -0400 | ||
4 | Subject: [PATCH 1/3] mgr: require all caps for pre-octopus tell commands | ||
5 | |||
6 | This matches the requirements for admin socket commands | ||
7 | sent via tell elsewhere. | ||
8 | |||
9 | Signed-off-by: Josh Durgin <jdurgin@redhat.com> | ||
10 | |||
11 | Upstream-status: Backport | ||
12 | [https://github.com/ceph/ceph/commit/347003e13167c428187a5450517850f4d85e09ad] | ||
13 | |||
14 | Signed-off-by: Liu Haitao <haitao.liu@windriver.com> | ||
15 | --- | ||
16 | src/mgr/DaemonServer.cc | 37 ++++++++++++++++++++++--------------- | ||
17 | 1 file changed, 22 insertions(+), 15 deletions(-) | ||
18 | |||
19 | diff --git a/src/mgr/DaemonServer.cc b/src/mgr/DaemonServer.cc | ||
20 | index becd428a..527326e3 100644 | ||
21 | --- a/src/mgr/DaemonServer.cc | ||
22 | +++ b/src/mgr/DaemonServer.cc | ||
23 | @@ -808,20 +808,12 @@ public: | ||
24 | bool DaemonServer::handle_command(const ref_t<MCommand>& m) | ||
25 | { | ||
26 | std::lock_guard l(lock); | ||
27 | - // a blank fsid in MCommand signals a legacy client sending a "mon-mgr" CLI | ||
28 | - // command. | ||
29 | - if (m->fsid != uuid_d()) { | ||
30 | - cct->get_admin_socket()->queue_tell_command(m); | ||
31 | + auto cmdctx = std::make_shared<CommandContext>(m); | ||
32 | + try { | ||
33 | + return _handle_command(cmdctx); | ||
34 | + } catch (const bad_cmd_get& e) { | ||
35 | + cmdctx->reply(-EINVAL, e.what()); | ||
36 | return true; | ||
37 | - } else { | ||
38 | - // legacy client; send to CLI processing | ||
39 | - auto cmdctx = std::make_shared<CommandContext>(m); | ||
40 | - try { | ||
41 | - return _handle_command(cmdctx); | ||
42 | - } catch (const bad_cmd_get& e) { | ||
43 | - cmdctx->reply(-EINVAL, e.what()); | ||
44 | - return true; | ||
45 | - } | ||
46 | } | ||
47 | } | ||
48 | |||
49 | @@ -853,8 +845,12 @@ bool DaemonServer::_handle_command( | ||
50 | std::shared_ptr<CommandContext>& cmdctx) | ||
51 | { | ||
52 | MessageRef m; | ||
53 | + bool admin_socket_cmd = false; | ||
54 | if (cmdctx->m_tell) { | ||
55 | m = cmdctx->m_tell; | ||
56 | + // a blank fsid in MCommand signals a legacy client sending a "mon-mgr" CLI | ||
57 | + // command. | ||
58 | + admin_socket_cmd = (cmdctx->m_tell->fsid != uuid_d()); | ||
59 | } else { | ||
60 | m = cmdctx->m_mgr; | ||
61 | } | ||
62 | @@ -888,7 +884,10 @@ bool DaemonServer::_handle_command( | ||
63 | |||
64 | dout(10) << "decoded-size=" << cmdctx->cmdmap.size() << " prefix=" << prefix << dendl; | ||
65 | |||
66 | - if (prefix == "get_command_descriptions") { | ||
67 | + // this is just for mgr commands - admin socket commands will fall | ||
68 | + // through and use the admin socket version of | ||
69 | + // get_command_descriptions | ||
70 | + if (prefix == "get_command_descriptions" && !admin_socket_cmd) { | ||
71 | dout(10) << "reading commands from python modules" << dendl; | ||
72 | const auto py_commands = py_modules.get_commands(); | ||
73 | |||
74 | @@ -925,7 +924,10 @@ bool DaemonServer::_handle_command( | ||
75 | |||
76 | bool is_allowed = false; | ||
77 | ModuleCommand py_command; | ||
78 | - if (!mgr_cmd) { | ||
79 | + if (admin_socket_cmd) { | ||
80 | + // admin socket commands require all capabilities | ||
81 | + is_allowed = session->caps.is_allow_all(); | ||
82 | + } else if (!mgr_cmd) { | ||
83 | // Resolve the command to the name of the module that will | ||
84 | // handle it (if the command exists) | ||
85 | auto py_commands = py_modules.get_py_commands(); | ||
86 | @@ -958,6 +960,11 @@ bool DaemonServer::_handle_command( | ||
87 | << "entity='" << session->entity_name << "' " | ||
88 | << "cmd=" << cmdctx->cmd << ": dispatch"; | ||
89 | |||
90 | + if (admin_socket_cmd) { | ||
91 | + cct->get_admin_socket()->queue_tell_command(cmdctx->m_tell); | ||
92 | + return true; | ||
93 | + } | ||
94 | + | ||
95 | // ---------------- | ||
96 | // service map commands | ||
97 | if (prefix == "service dump") { | ||
98 | -- | ||
99 | 2.25.1 | ||
100 | |||
diff --git a/recipes-extended/ceph/ceph/0002-mon-enforce-caps-for-pre-octopus-client-tell-command.patch b/recipes-extended/ceph/ceph/0002-mon-enforce-caps-for-pre-octopus-client-tell-command.patch new file mode 100644 index 00000000..79f2174b --- /dev/null +++ b/recipes-extended/ceph/ceph/0002-mon-enforce-caps-for-pre-octopus-client-tell-command.patch | |||
@@ -0,0 +1,95 @@ | |||
1 | From ddbac9b2779172876ebd2d26b68b04b02350a125 Mon Sep 17 00:00:00 2001 | ||
2 | From: Josh Durgin <jdurgin@redhat.com> | ||
3 | Date: Thu, 23 Apr 2020 00:22:10 -0400 | ||
4 | Subject: [PATCH 2/3] mon: enforce caps for pre-octopus client tell commands | ||
5 | |||
6 | This affects only the commands whitelisted here - in particular | ||
7 | injectargs requires write access to the monitors. | ||
8 | |||
9 | Signed-off-by: Josh Durgin <jdurgin@redhat.com> | ||
10 | |||
11 | Upstream-status: Backport | ||
12 | [https://github.com/ceph/ceph/commit/fc5e56b75a97c4652c87e9959aad1c4dec45010d] | ||
13 | |||
14 | Signed-off-by: Liu Haitao <haitao.liu@windriver.com> | ||
15 | --- | ||
16 | src/mon/Monitor.cc | 56 +++++++++++++++++++++++----------------------- | ||
17 | 1 file changed, 28 insertions(+), 28 deletions(-) | ||
18 | |||
19 | diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc | ||
20 | index b7cb3eae..eecd2f68 100644 | ||
21 | --- a/src/mon/Monitor.cc | ||
22 | +++ b/src/mon/Monitor.cc | ||
23 | @@ -3226,34 +3226,6 @@ void Monitor::handle_command(MonOpRequestRef op) | ||
24 | return; | ||
25 | } | ||
26 | |||
27 | - // compat kludge for legacy clients trying to tell commands that are | ||
28 | - // new. see bottom of MonCommands.h. we need to handle both (1) | ||
29 | - // pre-octopus clients and (2) octopus clients with a mix of pre-octopus | ||
30 | - // and octopus mons. | ||
31 | - if ((!HAVE_FEATURE(m->get_connection()->get_features(), SERVER_OCTOPUS) || | ||
32 | - monmap->min_mon_release < ceph_release_t::octopus) && | ||
33 | - (prefix == "injectargs" || | ||
34 | - prefix == "smart" || | ||
35 | - prefix == "mon_status" || | ||
36 | - prefix == "heap")) { | ||
37 | - if (m->get_connection()->get_messenger() == 0) { | ||
38 | - // Prior to octopus, monitors might forward these messages | ||
39 | - // around. that was broken at baseline, and if we try to process | ||
40 | - // this message now, it will assert out when we try to send a | ||
41 | - // message in reply from the asok/tell worker (see | ||
42 | - // AnonConnection). Just reply with an error. | ||
43 | - dout(5) << __func__ << " failing forwarded command from a (presumably) " | ||
44 | - << "pre-octopus peer" << dendl; | ||
45 | - reply_command( | ||
46 | - op, -EBUSY, | ||
47 | - "failing forwarded tell command in mixed-version mon cluster", 0); | ||
48 | - return; | ||
49 | - } | ||
50 | - dout(5) << __func__ << " passing command to tell/asok" << dendl; | ||
51 | - cct->get_admin_socket()->queue_tell_command(m); | ||
52 | - return; | ||
53 | - } | ||
54 | - | ||
55 | string module; | ||
56 | string err; | ||
57 | |||
58 | @@ -3368,6 +3340,34 @@ void Monitor::handle_command(MonOpRequestRef op) | ||
59 | << "entity='" << session->entity_name << "' " | ||
60 | << "cmd=" << m->cmd << ": dispatch"; | ||
61 | |||
62 | + // compat kludge for legacy clients trying to tell commands that are | ||
63 | + // new. see bottom of MonCommands.h. we need to handle both (1) | ||
64 | + // pre-octopus clients and (2) octopus clients with a mix of pre-octopus | ||
65 | + // and octopus mons. | ||
66 | + if ((!HAVE_FEATURE(m->get_connection()->get_features(), SERVER_OCTOPUS) || | ||
67 | + monmap->min_mon_release < ceph_release_t::octopus) && | ||
68 | + (prefix == "injectargs" || | ||
69 | + prefix == "smart" || | ||
70 | + prefix == "mon_status" || | ||
71 | + prefix == "heap")) { | ||
72 | + if (m->get_connection()->get_messenger() == 0) { | ||
73 | + // Prior to octopus, monitors might forward these messages | ||
74 | + // around. that was broken at baseline, and if we try to process | ||
75 | + // this message now, it will assert out when we try to send a | ||
76 | + // message in reply from the asok/tell worker (see | ||
77 | + // AnonConnection). Just reply with an error. | ||
78 | + dout(5) << __func__ << " failing forwarded command from a (presumably) " | ||
79 | + << "pre-octopus peer" << dendl; | ||
80 | + reply_command( | ||
81 | + op, -EBUSY, | ||
82 | + "failing forwarded tell command in mixed-version mon cluster", 0); | ||
83 | + return; | ||
84 | + } | ||
85 | + dout(5) << __func__ << " passing command to tell/asok" << dendl; | ||
86 | + cct->get_admin_socket()->queue_tell_command(m); | ||
87 | + return; | ||
88 | + } | ||
89 | + | ||
90 | if (mon_cmd->is_mgr()) { | ||
91 | const auto& hdr = m->get_header(); | ||
92 | uint64_t size = hdr.front_len + hdr.middle_len + hdr.data_len; | ||
93 | -- | ||
94 | 2.25.1 | ||
95 | |||
diff --git a/recipes-extended/ceph/ceph/0003-PendingReleaseNotes-note-about-security-fix.patch b/recipes-extended/ceph/ceph/0003-PendingReleaseNotes-note-about-security-fix.patch new file mode 100644 index 00000000..ed2a63e7 --- /dev/null +++ b/recipes-extended/ceph/ceph/0003-PendingReleaseNotes-note-about-security-fix.patch | |||
@@ -0,0 +1,31 @@ | |||
1 | From 56800925651857821034ac9c8ec82d45635cc3b8 Mon Sep 17 00:00:00 2001 | ||
2 | From: Josh Durgin <jdurgin@redhat.com> | ||
3 | Date: Wed, 13 May 2020 21:34:56 -0700 | ||
4 | Subject: [PATCH 3/3] PendingReleaseNotes: note about security fix | ||
5 | |||
6 | Signed-off-by: Josh Durgin <jdurgin@redhat.com> | ||
7 | |||
8 | Upstream-status: Backport | ||
9 | [https://github.com/ceph/ceph/commit/06f239fc35f35865d2cf92dda1ac8f4d5fe82bde] | ||
10 | |||
11 | Signed-off-by: Liu Haitao <haitao.liu@windriver.com> | ||
12 | --- | ||
13 | PendingReleaseNotes | 2 ++ | ||
14 | 1 file changed, 2 insertions(+) | ||
15 | |||
16 | diff --git a/PendingReleaseNotes b/PendingReleaseNotes | ||
17 | index c9fd4c79..6e07ce6d 100644 | ||
18 | --- a/PendingReleaseNotes | ||
19 | +++ b/PendingReleaseNotes | ||
20 | @@ -1,6 +1,8 @@ | ||
21 | >=15.0.0 | ||
22 | -------- | ||
23 | |||
24 | +* CVE-2020-10736: Fixes an authorization bypass in monitor and manager daemons | ||
25 | + | ||
26 | * The RGW "num_rados_handles" has been removed. | ||
27 | * If you were using a value of "num_rados_handles" greater than 1 | ||
28 | multiply your current "objecter_inflight_ops" and | ||
29 | -- | ||
30 | 2.25.1 | ||
31 | |||
diff --git a/recipes-extended/ceph/ceph_15.2.0.bb b/recipes-extended/ceph/ceph_15.2.0.bb index e41aa2f4..9423faa4 100644 --- a/recipes-extended/ceph/ceph_15.2.0.bb +++ b/recipes-extended/ceph/ceph_15.2.0.bb | |||
@@ -17,6 +17,9 @@ SRC_URI = "http://download.ceph.com/tarballs/ceph-${PV}.tar.gz \ | |||
17 | file://0001-rgw-reject-unauthenticated-response-header-actions.patch \ | 17 | file://0001-rgw-reject-unauthenticated-response-header-actions.patch \ |
18 | file://0001-rgw-EPERM-to-ERR_INVALID_REQUEST.patch \ | 18 | file://0001-rgw-EPERM-to-ERR_INVALID_REQUEST.patch \ |
19 | file://0001-rgw-reject-control-characters-in-response-header-act.patch \ | 19 | file://0001-rgw-reject-control-characters-in-response-header-act.patch \ |
20 | file://0001-mgr-require-all-caps-for-pre-octopus-tell-commands.patch \ | ||
21 | file://0002-mon-enforce-caps-for-pre-octopus-client-tell-command.patch \ | ||
22 | file://0003-PendingReleaseNotes-note-about-security-fix.patch \ | ||
20 | " | 23 | " |
21 | 24 | ||
22 | SRC_URI[md5sum] = "1f9af648b4c6d19975aab2583ab99710" | 25 | SRC_URI[md5sum] = "1f9af648b4c6d19975aab2583ab99710" |