From 5376755a335cc1bf68910663b0c20e96a1a9530d Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Wed, 6 Jun 2018 10:00:47 -0700 Subject: [PATCH] cls/rgw: don't assert in decode_list_index_key() Fixes: http://tracker.ceph.com/issues/24117 Signed-off-by: Yehuda Sadeh (cherry picked from commit e71fba0c6f5b3b0572b5136840cf0ed3c9186569) --- src/cls/rgw/cls_rgw.cc | 44 ++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/cls/rgw/cls_rgw.cc b/src/cls/rgw/cls_rgw.cc index bb8876cf8a4fa..cc3eb0c253ad5 100644 --- a/src/cls/rgw/cls_rgw.cc +++ b/src/cls/rgw/cls_rgw.cc @@ -311,12 +311,20 @@ static void split_key(const string& key, list& vals) } } +static string escape_str(const string& s) +{ + int len = escape_json_attr_len(s.c_str(), s.size()); + std::string escaped(len, 0); + escape_json_attr(s.c_str(), s.size(), escaped.data()); + return escaped; +} + /* * list index key structure: * * \0[v\0i] */ -static void decode_list_index_key(const string& index_key, cls_rgw_obj_key *key, uint64_t *ver) +static int decode_list_index_key(const string& index_key, cls_rgw_obj_key *key, uint64_t *ver) { size_t len = strlen(index_key.c_str()); @@ -325,19 +333,25 @@ static void decode_list_index_key(const string& index_key, cls_rgw_obj_key *key, if (len == index_key.size()) { key->name = index_key; - return; + return 0; } list vals; split_key(index_key, vals); - assert(!vals.empty()); + if (vals.empty()) { + CLS_LOG(0, "ERROR: %s(): bad index_key (%s): split_key() returned empty vals", __func__, escape_str(index_key).c_str()); + return -EIO; + } list::iterator iter = vals.begin(); key->name = *iter; ++iter; - assert(iter != vals.end()); + if (iter == vals.end()) { + CLS_LOG(0, "ERROR: %s(): bad index_key (%s): no vals", __func__, escape_str(index_key).c_str()); + return -EIO; + } for (; iter != vals.end(); ++iter) { string& val = *iter; @@ -347,9 +361,14 @@ static void decode_list_index_key(const string& index_key, cls_rgw_obj_key *key, string err; const char *s = val.c_str() + 1; *ver = strict_strtoll(s, 10, &err); - assert(err.empty()); + if (!err.empty()) { + CLS_LOG(0, "ERROR: %s(): bad index_key (%s): could not parse val (v=%s)", __func__, escape_str(index_key).c_str(), s); + return -EIO; + } } } + + return 0; } static int read_bucket_header(cls_method_context_t hctx, struct rgw_bucket_dir_header *header) @@ -430,11 +449,16 @@ int rgw_bucket_list(cls_method_context_t hctx, bufferlist *in, bufferlist *out) cls_rgw_obj_key key; uint64_t ver; - decode_list_index_key(kiter->first, &key, &ver); start_key = kiter->first; CLS_LOG(20, "start_key=%s len=%zu", start_key.c_str(), start_key.size()); + int ret = decode_list_index_key(kiter->first, &key, &ver); + if (ret < 0) { + CLS_LOG(0, "ERROR: failed to decode list index key (%s)\n", escape_str(kiter->first).c_str()); + continue; + } + if (!entry.is_valid()) { CLS_LOG(20, "entry %s[%s] is not valid\n", key.name.c_str(), key.instance.c_str()); continue; @@ -992,14 +1016,6 @@ static void update_olh_log(struct rgw_bucket_olh_entry& olh_data_entry, OLHLogOp log.push_back(log_entry); } -static string escape_str(const string& s) -{ - int len = escape_json_attr_len(s.c_str(), s.size()); - std::string escaped(len, 0); - escape_json_attr(s.c_str(), s.size(), escaped.data()); - return escaped; -} - static int write_obj_instance_entry(cls_method_context_t hctx, struct rgw_bucket_dir_entry& instance_entry, const string& instance_idx) { CLS_LOG(20, "write_entry() instance=%s idx=%s flags=%d", escape_str(instance_entry.key.instance).c_str(), instance_idx.c_str(), instance_entry.flags); -- 2.39.5