From: Joao Eduardo Luis Date: Mon, 8 Sep 2014 10:28:48 +0000 (+0100) Subject: mon: AuthMonitor: validate caps when creating or changing mon caps X-Git-Tag: v0.87~41^2~13 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=861246158e2e3d50e799f200f7180295bf7f439e;p=ceph.git mon: AuthMonitor: validate caps when creating or changing mon caps The monitor doesn't really know how to validate caps not meant for it. The MDS or the OSD may very well allow blank caps for instance, while the monitor categorically does not. We can't simply state a capability is invalid because we wouldn't take it as such. On the other hand, we must check monitor caps and make sure they are correct, otherwise malformed caps can go unnoticed for a while, sometimes even being hard to understand what may have gone wrong. Backport: firefly Signed-off-by: Joao Eduardo Luis --- diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index 80cd920b6b4..2050a447430 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -859,6 +859,11 @@ bool AuthMonitor::prepare_command(MMonCommand *m) !entity_name.empty()) { // auth get-or-create [mon osdcapa osd osdcapb ...] + if (!valid_caps(caps_vec, &ss)) { + err = -EINVAL; + goto done; + } + // do we have it? EntityAuth entity_auth; if (mon->key_server.get_auth(entity, entity_auth)) { @@ -952,6 +957,11 @@ bool AuthMonitor::prepare_command(MMonCommand *m) goto done; } + if (!valid_caps(caps_vec, &ss)) { + err = -EINVAL; + goto done; + } + map newcaps; for (vector::iterator it = caps_vec.begin(); it != caps_vec.end(); it += 2) diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h index 2f15518ce8f..d66de24985f 100644 --- a/src/mon/AuthMonitor.h +++ b/src/mon/AuthMonitor.h @@ -124,6 +124,20 @@ private: pending_auth.push_back(inc); } + /* validate mon caps ; don't care about caps for other services as + * we don't know how to validate them */ + bool valid_caps(const vector& caps, ostream *out) { + for (vector::const_iterator p = caps.begin(); + p != caps.end(); p += 2) { + if (!p->empty() && *p != "mon") + continue; + MonCap tmp; + if (!tmp.parse(*(p+1), out)) + return false; + } + return true; + } + void on_active(); bool should_propose(double& delay); void create_initial();