Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

common: audit OPT_INT/OPT_UINT and handle incorrect signed uint #10835

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f1d5045
common: Changes for issue #14934
oliveiradan Jul 23, 2016
c5a13f1
mon: Changes for issue #14934 - mon related changes only
oliveiradan Jul 25, 2016
305b657
mon: Changes for issue #14934 - mds related changes only
oliveiradan Jul 25, 2016
aa71b2c
osd: Changes for issue #14934 - osd related changes only
oliveiradan Jul 25, 2016
7563509
msg: Changes for issue #14934 - msg related changes only
oliveiradan Jul 26, 2016
686ca51
bluestore: Changes for issue #14934 - bluestore related changes only
oliveiradan Jul 26, 2016
df7cdb0
filestore: Changes for issue #14934 - filestore related changes only
oliveiradan Jul 26, 2016
de0550a
rgw: Changes for issue #14934 - rgw related changes only
oliveiradan Jul 26, 2016
96a83e7
rbd: Changes for issue #14934 - rbd related changes only
oliveiradan Jul 26, 2016
4c2c779
sync: Changes for issue #14934 - sync related changes only
oliveiradan Jul 26, 2016
287de56
bdev: Changes for issue #14934 - bdev related changes only
oliveiradan Jul 26, 2016
0d43b4c
client: Changes for issue #14934 - client related changes only
oliveiradan Jul 26, 2016
29cbbd6
crush: Changes for issue #14934 - crush related changes only
oliveiradan Jul 26, 2016
010f4d2
heartbeat: Changes for issue #14934 - heartbeat related changes only
oliveiradan Jul 26, 2016
e15c1b3
journal: Changes for issue #14934 - journal related changes only
oliveiradan Jul 26, 2016
d134478
kinetic: Changes for issue #14934 - kinetic related changes only
oliveiradan Jul 26, 2016
a5143d4
kstore: Changes for issue #14934 - kstore related changes only
oliveiradan Jul 26, 2016
ec097b2
leveldb: Changes for issue #14934 - leveldb related changes only
oliveiradan Jul 26, 2016
b49d9f9
log: Changes for issue #14934 - log related changes only
oliveiradan Jul 26, 2016
0d5749c
paxos: Changes for issue #14934 - paxos related changes only
oliveiradan Jul 26, 2016
c74ed8c
rocksdb: Changes for issue #14934 - rocksdb related changes only
oliveiradan Jul 26, 2016
001c8a2
threadpool: Changes for issue #14934 - threadpool related changes only
oliveiradan Jul 26, 2016
6cc5d70
xio: Changes for issue #14934 - xio related changes only
oliveiradan Jul 26, 2016
9f51f6f
common: Changes for issue #14934 - global related changes only
oliveiradan Jul 26, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ceph_mon.cc
Expand Up @@ -480,7 +480,7 @@ int main(int argc, const char **argv)
<< std::endl;
exit(-err);
}
if (stats.avail_percent <= g_conf->mon_data_avail_crit) {
if (static_cast<uint32_t>(stats.avail_percent) <= g_conf->mon_data_avail_crit) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cerr << "error: monitor data filesystem reached concerning levels of"
<< " available storage space (available: "
<< stats.avail_percent << "% " << prettybyte_t(stats.byte_avail)
Expand Down
314 changes: 279 additions & 35 deletions src/common/config.cc
Expand Up @@ -26,8 +26,12 @@
#include "msg/msg_types.h"
#include "osd/osd_types.h"
#include "common/errno.h"

#include "include/assert.h"
#include "common/debug.h"

#include <tuple>
#include <unordered_map>
#include <boost/variant.hpp>

#include <errno.h>
#include <sstream>
Expand Down Expand Up @@ -146,6 +150,8 @@ md_config_t::md_config_t()
lock("md_config_t", true, false)
{
init_subsys();
//--
reset_ceph_settings_table();
}

void md_config_t::init_subsys()
Expand Down Expand Up @@ -946,83 +952,177 @@ int md_config_t::set_val_impl(const char *val, const config_option *opt)

int md_config_t::set_val_raw(const char *val, const config_option *opt)
{
const int CEPH_SETTING_SAFE = 1;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oliveiradan Why local variable is taken as caps?
Conventionally we take macros as this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amitkumar50 , that was when I started working on Ceph (that's an old PR) and I used it as a way to identify a constant. However, as it ended up getting old and a rebase was needed, I ended up not touching it (once it is a pretty big change) 'till we were certain this PR would still be useful or not. Should this PR still be interesting, I will rebase and rework whatever is needed.

Thanks,

std::string ceph_setting_name(ConfFile::normalize_key_name(opt->name));
std::string ceph_setting_value(val);

assert(lock.is_locked());
switch (opt->type) {
case OPT_INT: {
std::string err;
int f = strict_si_cast<int>(val, &err);
if (!err.empty())
return -EINVAL;
*(int*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<int>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(int *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_LONGLONG: {
std::string err;
long long f = strict_si_cast<long long>(val, &err);
if (!err.empty())
return -EINVAL;
*(long long*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<long long>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(long long *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_STR:
*(std::string*)opt->conf_ptr(this) = val ? val : "";
case OPT_STR: {
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<std::string>
(ceph_setting_name, val));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(std::string *)opt->conf_ptr(this) = val ? val : "";
}
return 0;
}
case OPT_FLOAT: {
std::string err;
float f = strict_strtof(val, &err);
if (!err.empty())
return -EINVAL;
*(float*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<float>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(float *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_DOUBLE: {
std::string err;
double f = strict_strtod(val, &err);
if (!err.empty())
return -EINVAL;
*(double*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<double>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(double *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_BOOL:
if (strcasecmp(val, "false") == 0)
*(bool*)opt->conf_ptr(this) = false;
else if (strcasecmp(val, "true") == 0)
*(bool*)opt->conf_ptr(this) = true;
else {
std::string err;
int b = strict_strtol(val, 10, &err);
if (!err.empty())
return -EINVAL;
*(bool*)opt->conf_ptr(this) = !!b;
case OPT_BOOL: {
if (strcasecmp(val, "false") == 0) {
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<bool>
(ceph_setting_name, false));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(bool *)opt->conf_ptr(this) = false;
}
} else if (strcasecmp(val, "true") == 0) {
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<bool>
(ceph_setting_name, true));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(bool *)opt->conf_ptr(this) = true;
}
} else {
std::string err;
int b = strict_strtol(val, 10, &err);
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<bool>
(ceph_setting_name, !!b));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(bool *)opt->conf_ptr(this) = !!b;
}
}
return 0;
}
case OPT_U32: {
std::string err;
int f = strict_si_cast<uint32_t>(val, &err);
if (!err.empty())
return -EINVAL;
*(uint32_t*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<uint32_t>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(uint32_t *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_U64: {
std::string err;
uint64_t f = strict_si_cast<uint64_t>(val, &err);
if (!err.empty())
return -EINVAL;
*(uint64_t*)opt->conf_ptr(this) = f;
if (!err.empty()) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<uint64_t>
(ceph_setting_name, f));
assert(ceph_setting_upd_ret != EINVAL);
//--
if (ceph_setting_upd_ret == CEPH_SETTING_SAFE) {
*(uint64_t *)opt->conf_ptr(this) = f;
}
return 0;
}
case OPT_ADDR: {
entity_addr_t *addr = (entity_addr_t*)opt->conf_ptr(this);
if (!addr->parse(val)) {
return -EINVAL;
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<entity_addr_t>
(ceph_setting_name, *addr));
assert(ceph_setting_upd_ret != EINVAL);
//--
return 0;
}
case OPT_UUID: {
uuid_d *u = (uuid_d*)opt->conf_ptr(this);
if (!u->parse(val))
return -EINVAL;
if (!u->parse(val)) {
return -EINVAL;
}
//-- We check the guards for the setting first and apply it if it is ok.
int ceph_setting_upd_ret = (start_ceph_setting_update<uuid_d>
(ceph_setting_name, *u));
assert(ceph_setting_upd_ret != EINVAL);
//--
return 0;
}
}
Expand Down Expand Up @@ -1235,3 +1335,147 @@ void md_config_t::complain_about_parse_errors(CephContext *cct)
{
::complain_about_parse_errors(cct, &parse_errors);
}

//-- Check if a negative was stored in an unsigned int var.
bool is_uint_negative(const int value)
{
const int BITS = 8;
return ((unsigned) (value >> ((sizeof(int) * BITS) - 1)));
} //-- bool is_uint_negative (const int value)

void md_config_t::copydata_to_ceph_settings_table
(const config_option ceph_config_opts[], ceph_settings_table_t& settings_tbl)
{
//-- For performance reason, lets reserve what we need.
settings_tbl.clear();
settings_tbl.reserve(NUM_CONFIG_OPTIONS);

//--
for (int i = 0; i < NUM_CONFIG_OPTIONS; ++i) {
//-- In key names, leading and trailing whitespace are not significant.
std::string ceph_setting(ConfFile::normalize_key_name
(ceph_config_opts[i].name));
const config_option *opt = &ceph_config_opts[i];

std::ostringstream ossValue;
std::string strErr;
switch (opt->type) {
case OPT_INT: {
ossValue << *(int*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
int optValue = strict_si_cast<int>(strValue.c_str(), &strErr);
update_ceph_settings_table<int>(settings_tbl, ceph_setting,
(int)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_INT:
case OPT_LONGLONG: {
ossValue << *(long long*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
long long optValue = strict_si_cast<long long>(strValue.c_str(), &strErr);
update_ceph_settings_table<long long>(settings_tbl, ceph_setting,
(long long)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_LONGLONG:
case OPT_STR: {
ossValue << *((std::string*)opt->conf_ptr(this));
std::string strValue(ossValue.str());
update_ceph_settings_table<std::string>(settings_tbl, ceph_setting,
(std::string)(strValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_STR:
case OPT_FLOAT: {
ossValue << *(float*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
float optValue = strict_strtof(strValue.c_str(), &strErr);
update_ceph_settings_table<float>(settings_tbl, ceph_setting,
(float)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_FLOAT:
case OPT_DOUBLE: {
ossValue << *(double*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
double optValue = strict_strtod(strValue.c_str(), &strErr);
update_ceph_settings_table<double>(settings_tbl, ceph_setting,
(double)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_DOUBLE:
case OPT_BOOL: {
ossValue << *(bool*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
int optValue = strict_strtol(strValue.c_str(), 10, &strErr);
bool optValueBool = !!optValue;
update_ceph_settings_table<bool>(settings_tbl, ceph_setting,
(bool)(optValueBool),
ceph_config_opts[i].type);
break;
} //-- case OPT_BOOL:
case OPT_U32: {
ossValue << *(uint32_t*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
uint32_t optValue = strict_si_cast<uint32_t>(strValue.c_str(), &strErr);
update_ceph_settings_table<uint32_t>(settings_tbl, ceph_setting,
(uint32_t)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_U32:
case OPT_U64: {
ossValue << *(uint64_t*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
uint64_t optValue = strict_si_cast<uint64_t>(strValue.c_str(), &strErr);
update_ceph_settings_table<uint64_t>(settings_tbl, ceph_setting,
(uint64_t)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_U64:
case OPT_ADDR: {
ossValue << *(entity_addr_t*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
entity_addr_t optValue = *(entity_addr_t *)opt->conf_ptr(this);
update_ceph_settings_table<entity_addr_t>(settings_tbl, ceph_setting,
(entity_addr_t)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_U64:
case OPT_UUID: {
ossValue << *(uuid_d*)opt->conf_ptr(this);
std::string strValue(ossValue.str());
uuid_d optValue = *(uuid_d*)opt->conf_ptr(this);
update_ceph_settings_table<uuid_d>(settings_tbl, ceph_setting,
(uuid_d)(optValue),
ceph_config_opts[i].type);
break;
} //-- case OPT_UUID:
} //-- switch ((opt->type))
} //-- for (int i = 0; i < NUM_CONFIG_OPTIONS; ++i)
} /* void md_config_t::copydata_to_ceph_settings_table
(const config_option ceph_config_opts[], ceph_settings_table_t& settings_tbl)
*/

void md_config_t::reset_ceph_settings_table()
{
//--
if (ceph_use_guard_system()) {
copydata_to_ceph_settings_table(config_optionsp, m_ceph_config_params);
}
} //-- void md_config_t::reset_ceph_settings_table()

bool md_config_t::valid_ceph_setting
(const std::string& ceph_setting_name,
ceph_settings_tbl_const_iter& ceph_settings_tbl_iter)
{
auto iter = m_ceph_config_params.find(ceph_setting_name);
if (iter != m_ceph_config_params.end()) {
ceph_settings_tbl_iter = iter;
}
return (iter != m_ceph_config_params.end()) ? true : false;
} /*
bool md_config_t::valid_ceph_setting
(const std::string& ceph_setting_name,
ceph_settings_tbl_const_iter& ceph_settings_tbl_iter)
*/