diff options
author | Sage Weil <sage@inktank.com> | 2013-05-10 22:14:05 -0700 |
---|---|---|
committer | Sage Weil <sage@inktank.com> | 2013-05-13 11:49:27 -0700 |
commit | 5c305d63043762027323052b4bb3ae3063665c6f (patch) | |
tree | 516064f816ebda4579ea7d88b1111b0418faf682 | |
parent | 110411630986e083d9012d12a5b6c68b0dcd872c (diff) | |
download | ceph-5c305d63043762027323052b4bb3ae3063665c6f.tar.gz |
mon: fix validatation of mds ids in mon commands
Fixes: #4996
Signed-off-by: Sage Weil <sage@inktank.com>
-rw-r--r-- | src/mon/MDSMonitor.cc | 55 | ||||
-rw-r--r-- | src/mon/MDSMonitor.h | 1 |
2 files changed, 41 insertions, 15 deletions
diff --git a/src/mon/MDSMonitor.cc b/src/mon/MDSMonitor.cc index 566bf1caa3f..43747612dde 100644 --- a/src/mon/MDSMonitor.cc +++ b/src/mon/MDSMonitor.cc @@ -527,6 +527,27 @@ void MDSMonitor::dump_info(Formatter *f) f->close_section(); } +int MDSMonitor::parse_mds_id(const char *s, stringstream *pss) +{ + // osd.NNN? + if (strncmp(s, "mds.", 4) == 0) { + s += 4; + } + + // NNN? + ostringstream ss; + long id = parse_pos_long(s, &ss); + if (id < 0) { + *pss << ss.str(); + return id; + } + if (id > 0xffff) { + *pss << "mds id " << id << " is too large"; + return -ERANGE; + } + return id; +} + bool MDSMonitor::preprocess_command(MMonCommand *m) { int r = -1; @@ -656,18 +677,22 @@ bool MDSMonitor::preprocess_command(MMonCommand *m) } } else { errno = 0; - int who = strtol(m->cmd[0].c_str(), 0, 10); - m->cmd.erase(m->cmd.begin()); //done with target num now - if (!errno && who >= 0) { - if (mdsmap.is_up(who)) { - mon->send_command(mdsmap.get_inst(who), m->cmd, get_version()); - r = 0; - ss << "ok"; - } else { - ss << "mds." << who << " no up"; - r = -ENOENT; + int who = parse_mds_id(m->cmd[0].c_str(), &ss); + if (who < 0) { + r = -EINVAL; + } else { + m->cmd.erase(m->cmd.begin()); //done with target num now + if (!errno && who >= 0) { + if (mdsmap.is_up(who)) { + mon->send_command(mdsmap.get_inst(who), m->cmd, get_version()); + r = 0; + ss << "ok"; + } else { + ss << "mds." << who << " no up"; + r = -ENOENT; + } } - } else ss << "specify mds number or *"; + } } } else if (m->cmd[1] == "compat") { @@ -717,9 +742,9 @@ void MDSMonitor::fail_mds_gid(uint64_t gid) int MDSMonitor::fail_mds(std::ostream &ss, const std::string &arg) { - std::string err; - int w = strict_strtoll(arg.c_str(), 10, &err); - if (!err.empty()) { + stringstream ss2; + int w = parse_mds_id(arg.c_str(), &ss2); + if (w < 0) { // Try to interpret the arg as an MDS name const MDSMap::mds_info_t *mds_info = mdsmap.find_by_name(arg); if (!mds_info) { @@ -731,7 +756,7 @@ int MDSMonitor::fail_mds(std::ostream &ss, const std::string &arg) if (!mon->osdmon()->is_writeable()) { return -EAGAIN; - } + } bool failed_mds_gid = false; if (pending_mdsmap.up.count(w)) { diff --git a/src/mon/MDSMonitor.h b/src/mon/MDSMonitor.h index 52841cfff10..674003728aa 100644 --- a/src/mon/MDSMonitor.h +++ b/src/mon/MDSMonitor.h @@ -65,6 +65,7 @@ class MDSMonitor : public PaxosService { void create_new_fs(MDSMap &m, int metadata_pool, int data_pool); + int parse_mds_id(const char *s, stringstream *pss); // service methods void create_initial(); |