|
|
7f4c2a |
From b1de5fd8f480bb6cd034242c49a1f85ff6c21e51 Mon Sep 17 00:00:00 2001
|
|
|
7f4c2a |
From: Raghavendra Bhat <raghavendra@redhat.com>
|
|
|
7f4c2a |
Date: Wed, 24 Jun 2015 20:06:01 +0530
|
|
|
7f4c2a |
Subject: [PATCH 186/190] features/bit-rot-stub: do not allow setxattr and removexattr on bit-rot xattrs
|
|
|
7f4c2a |
|
|
|
7f4c2a |
Backport of http://review.gluster.org/11389
|
|
|
7f4c2a |
|
|
|
7f4c2a |
* setxattr and {f}removexattr of versioning, signature and bad-file xattrs are
|
|
|
7f4c2a |
returned with error.
|
|
|
7f4c2a |
|
|
|
7f4c2a |
Change-Id: I21b25e06b6b78309c0ddd155345fec8765e03352
|
|
|
7f4c2a |
BUG: 1224227
|
|
|
7f4c2a |
Reviewed-on: https://code.engineering.redhat.com/gerrit/51758
|
|
|
7f4c2a |
Reviewed-by: Venky Shankar <vshankar@redhat.com>
|
|
|
7f4c2a |
Tested-by: Venky Shankar <vshankar@redhat.com>
|
|
|
7f4c2a |
---
|
|
|
7f4c2a |
.../bit-rot/src/stub/bit-rot-stub-messages.h | 10 ++-
|
|
|
7f4c2a |
xlators/features/bit-rot/src/stub/bit-rot-stub.c | 103 ++++++++++++++++++-
|
|
|
7f4c2a |
2 files changed, 106 insertions(+), 7 deletions(-)
|
|
|
7f4c2a |
|
|
|
7f4c2a |
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h b/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h
|
|
|
7f4c2a |
index db5736a..532c2be 100644
|
|
|
7f4c2a |
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h
|
|
|
7f4c2a |
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub-messages.h
|
|
|
7f4c2a |
@@ -167,7 +167,14 @@
|
|
|
7f4c2a |
* @recommendedaction
|
|
|
7f4c2a |
*
|
|
|
7f4c2a |
*/
|
|
|
7f4c2a |
-#define BRS_MSG_REMOVE_BAD_OBJECT_XATTR (GLFS_BITROT_STUB_BASE + 18)
|
|
|
7f4c2a |
+#define BRS_MSG_REMOVE_INTERNAL_XATTR (GLFS_BITROT_STUB_BASE + 18)
|
|
|
7f4c2a |
+/*!
|
|
|
7f4c2a |
+ * @messageid
|
|
|
7f4c2a |
+ * @diagnosis
|
|
|
7f4c2a |
+ * @recommendedaction
|
|
|
7f4c2a |
+ *
|
|
|
7f4c2a |
+ */
|
|
|
7f4c2a |
+#define BRS_MSG_SET_INTERNAL_XATTR (GLFS_BITROT_STUB_BASE + 19)
|
|
|
7f4c2a |
/*!
|
|
|
7f4c2a |
* @messageid
|
|
|
7f4c2a |
* @diagnosis
|
|
|
7f4c2a |
@@ -182,5 +189,6 @@
|
|
|
7f4c2a |
*
|
|
|
7f4c2a |
*/
|
|
|
7f4c2a |
/*------------*/
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
#define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages"
|
|
|
7f4c2a |
#endif /* !_BITROT_STUB_MESSAGES_H_ */
|
|
|
7f4c2a |
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
|
|
|
7f4c2a |
index de81510..41c8359 100644
|
|
|
7f4c2a |
--- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c
|
|
|
7f4c2a |
+++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c
|
|
|
7f4c2a |
@@ -993,6 +993,37 @@ unwind:
|
|
|
7f4c2a |
return 0;
|
|
|
7f4c2a |
}
|
|
|
7f4c2a |
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+/**
|
|
|
7f4c2a |
+ * As of now, versioning is done by the stub (though as a setxattr
|
|
|
7f4c2a |
+ * operation) as part of inode modification operations such as writev,
|
|
|
7f4c2a |
+ * truncate, ftruncate. And signing is done by BitD by a fsetxattr call.
|
|
|
7f4c2a |
+ * So any kind of setxattr coming on the versioning and the signing xattr is
|
|
|
7f4c2a |
+ * not allowed (i.e. BITROT_CURRENT_VERSION_KEY and BITROT_SIGNING_VERSION_KEY).
|
|
|
7f4c2a |
+ * In future if BitD/scrubber are allowed to change the versioning
|
|
|
7f4c2a |
+ * xattrs (though I cannot see a reason for it as of now), then the below
|
|
|
7f4c2a |
+ * function can be modified to block setxattr on version for only applications.
|
|
|
7f4c2a |
+ *
|
|
|
7f4c2a |
+ * NOTE: BitD sends sign request on GLUSTERFS_SET_OBJECT_SIGNATURE key.
|
|
|
7f4c2a |
+ * BITROT_SIGNING_VERSION_KEY is the xattr used to save the signature.
|
|
|
7f4c2a |
+ *
|
|
|
7f4c2a |
+ */
|
|
|
7f4c2a |
+static int32_t
|
|
|
7f4c2a |
+br_stub_handle_internal_xattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
|
|
|
7f4c2a |
+ char *key)
|
|
|
7f4c2a |
+{
|
|
|
7f4c2a |
+ int32_t op_ret = -1;
|
|
|
7f4c2a |
+ int32_t op_errno = EINVAL;
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
7f4c2a |
+ BRS_MSG_SET_INTERNAL_XATTR, "setxattr called"
|
|
|
7f4c2a |
+ " on the internal xattr %s for inode %s", key,
|
|
|
7f4c2a |
+ uuid_utoa (fd->inode->gfid));
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+ STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, NULL);
|
|
|
7f4c2a |
+ return 0;
|
|
|
7f4c2a |
+}
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
int
|
|
|
7f4c2a |
br_stub_fsetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
7f4c2a |
fd_t *fd, dict_t *dict, int flags, dict_t *xdata)
|
|
|
7f4c2a |
@@ -1013,6 +1044,20 @@ br_stub_fsetxattr (call_frame_t *frame, xlator_t *this,
|
|
|
7f4c2a |
goto done;
|
|
|
7f4c2a |
}
|
|
|
7f4c2a |
|
|
|
7f4c2a |
+ /* signing xattr */
|
|
|
7f4c2a |
+ if (dict_get(dict, BITROT_SIGNING_VERSION_KEY)) {
|
|
|
7f4c2a |
+ br_stub_handle_internal_xattr (frame, this, fd,
|
|
|
7f4c2a |
+ BITROT_SIGNING_VERSION_KEY);
|
|
|
7f4c2a |
+ goto done;
|
|
|
7f4c2a |
+ }
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+ /* version xattr */
|
|
|
7f4c2a |
+ if (dict_get(dict, BITROT_CURRENT_VERSION_KEY)) {
|
|
|
7f4c2a |
+ br_stub_handle_internal_xattr (frame, this, fd,
|
|
|
7f4c2a |
+ BITROT_CURRENT_VERSION_KEY);
|
|
|
7f4c2a |
+ goto done;
|
|
|
7f4c2a |
+ }
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
/* object reopen request */
|
|
|
7f4c2a |
ret = dict_get_uint32 (dict, BR_REOPEN_SIGN_HINT_KEY, &val;;
|
|
|
7f4c2a |
if (!ret) {
|
|
|
7f4c2a |
@@ -1035,6 +1080,45 @@ done:
|
|
|
7f4c2a |
return 0;
|
|
|
7f4c2a |
}
|
|
|
7f4c2a |
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+/**
|
|
|
7f4c2a |
+ * Currently BitD and scrubber are doing fsetxattr to either sign the object
|
|
|
7f4c2a |
+ * or to mark it as bad. Hence setxattr on any of those keys is denied directly
|
|
|
7f4c2a |
+ * without checking from where the fop is coming.
|
|
|
7f4c2a |
+ * Later, if BitD or Scrubber does setxattr of those keys, then appropriate
|
|
|
7f4c2a |
+ * check has to be added below.
|
|
|
7f4c2a |
+ */
|
|
|
7f4c2a |
+int
|
|
|
7f4c2a |
+br_stub_setxattr (call_frame_t *frame, xlator_t *this,
|
|
|
7f4c2a |
+ loc_t *loc, dict_t *dict, int flags, dict_t *xdata)
|
|
|
7f4c2a |
+{
|
|
|
7f4c2a |
+ int32_t op_ret = -1;
|
|
|
7f4c2a |
+ int32_t op_errno = EINVAL;
|
|
|
7f4c2a |
+ char dump[64*1024] = {0,};
|
|
|
7f4c2a |
+ char *format = "(%s:%s)";
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+ if (dict_get (dict, GLUSTERFS_SET_OBJECT_SIGNATURE) ||
|
|
|
7f4c2a |
+ dict_get (dict, BR_REOPEN_SIGN_HINT_KEY) ||
|
|
|
7f4c2a |
+ dict_get (dict, BITROT_OBJECT_BAD_KEY) ||
|
|
|
7f4c2a |
+ dict_get (dict, BITROT_SIGNING_VERSION_KEY) ||
|
|
|
7f4c2a |
+ dict_get (dict, BITROT_CURRENT_VERSION_KEY)) {
|
|
|
7f4c2a |
+ dict_dump_to_str (dict, dump, sizeof(dump), format);
|
|
|
7f4c2a |
+ gf_msg (this->name, GF_LOG_ERROR, 0,
|
|
|
7f4c2a |
+ BRS_MSG_SET_INTERNAL_XATTR, "setxattr called on "
|
|
|
7f4c2a |
+ "internal xattr %s", dump);
|
|
|
7f4c2a |
+ goto unwind;
|
|
|
7f4c2a |
+ }
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
+ STACK_WIND_TAIL (frame, FIRST_CHILD (this),
|
|
|
7f4c2a |
+ FIRST_CHILD (this)->fops->setxattr, loc, dict, flags,
|
|
|
7f4c2a |
+ xdata);
|
|
|
7f4c2a |
+ return 0;
|
|
|
7f4c2a |
+unwind:
|
|
|
7f4c2a |
+ STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL);
|
|
|
7f4c2a |
+ return 0;
|
|
|
7f4c2a |
+}
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
/** }}} */
|
|
|
7f4c2a |
|
|
|
7f4c2a |
|
|
|
7f4c2a |
@@ -1049,13 +1133,16 @@ br_stub_removexattr (call_frame_t *frame, xlator_t *this,
|
|
|
7f4c2a |
int32_t op_ret = -1;
|
|
|
7f4c2a |
int32_t op_errno = EINVAL;
|
|
|
7f4c2a |
|
|
|
7f4c2a |
- if (!strcmp (BITROT_OBJECT_BAD_KEY, name)) {
|
|
|
7f4c2a |
+ if (!strcmp (BITROT_OBJECT_BAD_KEY, name) ||
|
|
|
7f4c2a |
+ !strcmp (BITROT_SIGNING_VERSION_KEY, name) ||
|
|
|
7f4c2a |
+ !strcmp (BITROT_CURRENT_VERSION_KEY, name)) {
|
|
|
7f4c2a |
gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
7f4c2a |
- BRS_MSG_REMOVE_BAD_OBJECT_XATTR, "Remove xattr called"
|
|
|
7f4c2a |
- " on bad object xattr for file %s", loc->path);
|
|
|
7f4c2a |
+ BRS_MSG_REMOVE_INTERNAL_XATTR, "removexattr called"
|
|
|
7f4c2a |
+ " on internal xattr %s for file %s", name, loc->path);
|
|
|
7f4c2a |
goto unwind;
|
|
|
7f4c2a |
}
|
|
|
7f4c2a |
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
STACK_WIND_TAIL (frame, FIRST_CHILD(this),
|
|
|
7f4c2a |
FIRST_CHILD(this)->fops->removexattr,
|
|
|
7f4c2a |
loc, name, xdata);
|
|
|
7f4c2a |
@@ -1072,14 +1159,17 @@ br_stub_fremovexattr (call_frame_t *frame, xlator_t *this,
|
|
|
7f4c2a |
int32_t op_ret = -1;
|
|
|
7f4c2a |
int32_t op_errno = EINVAL;
|
|
|
7f4c2a |
|
|
|
7f4c2a |
- if (!strcmp (BITROT_OBJECT_BAD_KEY, name)) {
|
|
|
7f4c2a |
+ if (!strcmp (BITROT_OBJECT_BAD_KEY, name) ||
|
|
|
7f4c2a |
+ !strcmp (BITROT_SIGNING_VERSION_KEY, name) ||
|
|
|
7f4c2a |
+ !strcmp (BITROT_CURRENT_VERSION_KEY, name)) {
|
|
|
7f4c2a |
gf_msg (this->name, GF_LOG_WARNING, 0,
|
|
|
7f4c2a |
- BRS_MSG_REMOVE_BAD_OBJECT_XATTR, "Remove xattr called"
|
|
|
7f4c2a |
- " on bad object xattr for inode %s",
|
|
|
7f4c2a |
+ BRS_MSG_REMOVE_INTERNAL_XATTR, "removexattr called"
|
|
|
7f4c2a |
+ " on internal xattr %s for inode %s", name,
|
|
|
7f4c2a |
uuid_utoa (fd->inode->gfid));
|
|
|
7f4c2a |
goto unwind;
|
|
|
7f4c2a |
}
|
|
|
7f4c2a |
|
|
|
7f4c2a |
+
|
|
|
7f4c2a |
STACK_WIND_TAIL (frame, FIRST_CHILD(this),
|
|
|
7f4c2a |
FIRST_CHILD(this)->fops->fremovexattr,
|
|
|
7f4c2a |
fd, name, xdata);
|
|
|
7f4c2a |
@@ -2593,6 +2683,7 @@ struct xlator_fops fops = {
|
|
|
7f4c2a |
.readv = br_stub_readv,
|
|
|
7f4c2a |
.removexattr = br_stub_removexattr,
|
|
|
7f4c2a |
.fremovexattr = br_stub_fremovexattr,
|
|
|
7f4c2a |
+ .setxattr = br_stub_setxattr,
|
|
|
7f4c2a |
};
|
|
|
7f4c2a |
|
|
|
7f4c2a |
struct xlator_cbks cbks = {
|
|
|
7f4c2a |
--
|
|
|
7f4c2a |
1.7.1
|
|
|
7f4c2a |
|