From 6a232004554477942b8123e96186378958b9156a Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Mon, 9 Mar 2020 23:41:26 -0400 Subject: [PATCH] librbd: prevent 'non-primary' feature from being set via API This feature is mutable from only within librbd as a mirrored image is promoted/demoted. Signed-off-by: Jason Dillaman --- src/include/rbd/features.h | 1 + src/librbd/Features.cc | 12 +++++++----- src/librbd/Operations.cc | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/include/rbd/features.h b/src/include/rbd/features.h index 00cb4d2a1ead..06b5cd06471b 100644 --- a/src/include/rbd/features.h +++ b/src/include/rbd/features.h @@ -66,6 +66,7 @@ RBD_FEATURE_FAST_DIFF | \ RBD_FEATURE_JOURNALING | \ RBD_FEATURE_NON_PRIMARY) +#define RBD_FEATURES_MUTABLE_INTERNAL (RBD_FEATURE_NON_PRIMARY) /// features that may be dynamically disabled #define RBD_FEATURES_DISABLE_ONLY (RBD_FEATURE_DEEP_FLATTEN) diff --git a/src/librbd/Features.cc b/src/librbd/Features.cc index de50218ac099..1531a2eab4d8 100644 --- a/src/librbd/Features.cc +++ b/src/librbd/Features.cc @@ -74,12 +74,14 @@ uint64_t rbd_features_from_string(const std::string& orig_value, << std::hex << unsupported_features << std::dec; } } - uint64_t internal_features = (features & RBD_FEATURES_INTERNAL); - if (internal_features != 0ULL) { - features &= ~RBD_FEATURES_INTERNAL; + + uint64_t ignore_features_mask = ( + RBD_FEATURES_INTERNAL | RBD_FEATURES_MUTABLE_INTERNAL); + uint64_t ignored_features = (features & ignore_features_mask); + if (ignored_features != 0ULL) { + features &= ~ignore_features_mask; if (err) { - *err << "ignoring internal feature mask 0x" - << std::hex << internal_features; + *err << "ignoring feature mask 0x" << std::hex << ignored_features; } } } catch (boost::bad_lexical_cast&) { diff --git a/src/librbd/Operations.cc b/src/librbd/Operations.cc index 4334a4a37b9d..d53d7637e3f1 100644 --- a/src/librbd/Operations.cc +++ b/src/librbd/Operations.cc @@ -1337,7 +1337,8 @@ int Operations::update_features(uint64_t features, bool enabled) { uint64_t disable_mask = (RBD_FEATURES_MUTABLE | RBD_FEATURES_DISABLE_ONLY); if ((enabled && (features & RBD_FEATURES_MUTABLE) != features) || - (!enabled && (features & disable_mask) != features)) { + (!enabled && (features & disable_mask) != features) || + ((features & ~RBD_FEATURES_MUTABLE_INTERNAL) != features)) { lderr(cct) << "cannot update immutable features" << dendl; return -EINVAL; } -- 2.47.3