summaryrefslogtreecommitdiffstats
path: root/xlators/cluster
diff options
context:
space:
mode:
authorPranith Kumar K <pkarampu@redhat.com>2015-01-05 16:21:52 +0530
committerPranith Kumar Karampuri <pkarampu@redhat.com>2015-01-08 21:55:37 -0800
commit70dc47389cbe08238d8c216c51d49583154bd08a (patch)
treef5da9dff6260291a7972e590d12ba785ed0841a1 /xlators/cluster
parentcf0770c61af2fa49fa435baf62cd5f28569175e4 (diff)
cluster/ec: Handle internal xattr get/set
Problem: Internal xattrs of EC like trusted.ec.size/config/version can be modified by users and that can lead to misbehavior in EC. Fix: Don't let the user modify the xattrs. Hide these xattrs in getfattr outputs. Change-Id: I39cec96ae12826b506b496fda7da74201015fd75 BUG: 1178688 Signed-off-by: Pranith Kumar K <pkarampu@redhat.com> Reviewed-on: http://review.gluster.org/9385 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Emmanuel Dreyfus <manu@netbsd.org> Tested-by: Emmanuel Dreyfus <manu@netbsd.org> Reviewed-by: Xavier Hernandez <xhernandez@datalab.es>
Diffstat (limited to 'xlators/cluster')
-rw-r--r--xlators/cluster/ec/src/ec-helpers.c17
-rw-r--r--xlators/cluster/ec/src/ec-helpers.h5
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c50
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c97
-rw-r--r--xlators/cluster/ec/src/ec.c125
-rw-r--r--xlators/cluster/ec/src/ec.h9
6 files changed, 188 insertions, 115 deletions
diff --git a/xlators/cluster/ec/src/ec-helpers.c b/xlators/cluster/ec/src/ec-helpers.c
index 3c3e2302e53..05ecab51ab6 100644
--- a/xlators/cluster/ec/src/ec-helpers.c
+++ b/xlators/cluster/ec/src/ec-helpers.c
@@ -694,3 +694,20 @@ uint64_t ec_adjust_size(ec_t * ec, uint64_t size, int32_t scale)
return size;
}
+
+inline gf_boolean_t
+ec_is_internal_xattr (dict_t *dict, char *key, data_t *value, void *data)
+{
+ if (key &&
+ (strncmp (key, EC_XATTR_PREFIX, strlen (EC_XATTR_PREFIX)) == 0))
+ return _gf_true;
+
+ return _gf_false;
+}
+
+void
+ec_filter_internal_xattrs (dict_t *xattr)
+{
+ dict_foreach_match (xattr, ec_is_internal_xattr, NULL,
+ dict_remove_foreach_fn, NULL);
+}
diff --git a/xlators/cluster/ec/src/ec-helpers.h b/xlators/cluster/ec/src/ec-helpers.h
index 46791041a3f..ff61839756c 100644
--- a/xlators/cluster/ec/src/ec-helpers.h
+++ b/xlators/cluster/ec/src/ec-helpers.h
@@ -52,4 +52,9 @@ static inline int32_t ec_is_power_of_2(uint32_t value)
return (value != 0) && ((value & (value - 1)) == 0);
}
+inline gf_boolean_t
+ec_is_internal_xattr (dict_t *dict, char *key, data_t *value, void *data);
+
+void
+ec_filter_internal_xattrs (dict_t *xattr);
#endif /* __EC_HELPERS_H__ */
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
index 3b5315b187a..64b1b719eea 100644
--- a/xlators/cluster/ec/src/ec-inode-read.c
+++ b/xlators/cluster/ec/src/ec-inode-read.c
@@ -280,15 +280,10 @@ int32_t ec_manager_getxattr(ec_fop_data_t * fop, int32_t state)
else
{
if (cbk->xdata != NULL)
- {
- dict_del(cbk->xdata, EC_XATTR_SIZE);
- dict_del(cbk->xdata, EC_XATTR_VERSION);
- }
+ ec_filter_internal_xattrs (cbk->xdata);
+
if (cbk->dict != NULL)
- {
- dict_del(cbk->dict, EC_XATTR_SIZE);
- dict_del(cbk->dict, EC_XATTR_VERSION);
- }
+ ec_filter_internal_xattrs (cbk->dict);
}
}
else
@@ -399,9 +394,10 @@ out:
return 0;
}
-void ec_getxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_getxattr_cbk_t func, void * data,
- loc_t * loc, const char * name, dict_t * xdata)
+void
+ec_getxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_getxattr_cbk_t func, void *data,
+ loc_t *loc, const char *name, dict_t *xdata)
{
ec_cbk_t callback = { .getxattr = func };
ec_fop_data_t * fop = NULL;
@@ -464,13 +460,10 @@ void ec_getxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL, NULL);
}
}
@@ -536,7 +529,8 @@ out:
return 0;
}
-void ec_wind_fgetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
+void
+ec_wind_fgetxattr (ec_t *ec, ec_fop_data_t *fop, int32_t idx)
{
ec_trace("WIND", fop, "idx=%d", idx);
@@ -545,9 +539,10 @@ void ec_wind_fgetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
fop->fd, fop->str[0], fop->xdata);
}
-void ec_fgetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fgetxattr_cbk_t func, void * data,
- fd_t * fd, const char * name, dict_t * xdata)
+void
+ec_fgetxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_fgetxattr_cbk_t func, void *data,
+ fd_t *fd, const char *name, dict_t *xdata)
{
ec_cbk_t callback = { .fgetxattr = func };
ec_fop_data_t * fop = NULL;
@@ -606,13 +601,10 @@ void ec_fgetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL, NULL);
}
}
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
index c120f067b6a..9c3f6fcd115 100644
--- a/xlators/cluster/ec/src/ec-inode-write.c
+++ b/xlators/cluster/ec/src/ec-inode-write.c
@@ -195,9 +195,10 @@ int32_t ec_manager_removexattr(ec_fop_data_t * fop, int32_t state)
}
}
-void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_removexattr_cbk_t func, void * data,
- loc_t * loc, const char * name, dict_t * xdata)
+void
+ec_removexattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_removexattr_cbk_t func, void *data,
+ loc_t *loc, const char *name, dict_t *xdata)
{
ec_cbk_t callback = { .removexattr = func };
ec_fop_data_t * fop = NULL;
@@ -205,9 +206,9 @@ void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
gf_log("ec", GF_LOG_TRACE, "EC(REMOVEXATTR) %p", frame);
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+ VALIDATE_OR_GOTO (this, out);
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
fop = ec_fop_data_allocate(frame, this, GF_FOP_REMOVEXATTR,
EC_FLAG_UPDATE_LOC_INODE, target, minimum,
@@ -252,13 +253,10 @@ void ec_removexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL);
}
}
@@ -319,9 +317,10 @@ void ec_wind_fremovexattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
fop->fd, fop->str[0], fop->xdata);
}
-void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fremovexattr_cbk_t func, void * data,
- fd_t * fd, const char * name, dict_t * xdata)
+void
+ec_fremovexattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_fremovexattr_cbk_t func, void *data,
+ fd_t *fd, const char *name, dict_t *xdata)
{
ec_cbk_t callback = { .fremovexattr = func };
ec_fop_data_t * fop = NULL;
@@ -329,9 +328,9 @@ void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
gf_log("ec", GF_LOG_TRACE, "EC(FREMOVEXATTR) %p", frame);
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+ VALIDATE_OR_GOTO (this, out);
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
fop = ec_fop_data_allocate(frame, this, GF_FOP_FREMOVEXATTR,
EC_FLAG_UPDATE_FD_INODE, target, minimum,
@@ -380,13 +379,10 @@ void ec_fremovexattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL);
}
}
@@ -986,9 +982,10 @@ int32_t ec_manager_setxattr(ec_fop_data_t * fop, int32_t state)
}
}
-void ec_setxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_setxattr_cbk_t func, void * data,
- loc_t * loc, dict_t * dict, int32_t flags, dict_t * xdata)
+void
+ec_setxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_setxattr_cbk_t func, void *data,
+ loc_t *loc, dict_t *dict, int32_t flags, dict_t *xdata)
{
ec_cbk_t callback = { .setxattr = func };
ec_fop_data_t * fop = NULL;
@@ -1046,29 +1043,27 @@ void ec_setxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL);
}
}
/* FOP: fsetxattr */
-int32_t ec_fsetxattr_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
- int32_t op_ret, int32_t op_errno, dict_t * xdata)
+int32_t
+ec_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
+ int32_t op_ret, int32_t op_errno, dict_t *xdata)
{
ec_fop_data_t * fop = NULL;
ec_cbk_data_t * cbk = NULL;
int32_t idx = (int32_t)(uintptr_t)cookie;
- VALIDATE_OR_GOTO(this, out);
- GF_VALIDATE_OR_GOTO(this->name, frame, out);
- GF_VALIDATE_OR_GOTO(this->name, frame->local, out);
- GF_VALIDATE_OR_GOTO(this->name, this->private, out);
+ VALIDATE_OR_GOTO (this, out);
+ GF_VALIDATE_OR_GOTO (this->name, frame, out);
+ GF_VALIDATE_OR_GOTO (this->name, frame->local, out);
+ GF_VALIDATE_OR_GOTO (this->name, this->private, out);
fop = frame->local;
@@ -1112,9 +1107,10 @@ void ec_wind_fsetxattr(ec_t * ec, ec_fop_data_t * fop, int32_t idx)
fop->fd, fop->dict, fop->int32, fop->xdata);
}
-void ec_fsetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
- int32_t minimum, fop_fsetxattr_cbk_t func, void * data,
- fd_t * fd, dict_t * dict, int32_t flags, dict_t * xdata)
+void
+ec_fsetxattr (call_frame_t *frame, xlator_t *this, uintptr_t target,
+ int32_t minimum, fop_fsetxattr_cbk_t func, void *data,
+ fd_t *fd, dict_t *dict, int32_t flags, dict_t *xdata)
{
ec_cbk_t callback = { .fsetxattr = func };
ec_fop_data_t * fop = NULL;
@@ -1176,13 +1172,10 @@ void ec_fsetxattr(call_frame_t * frame, xlator_t * this, uintptr_t target,
error = 0;
out:
- if (fop != NULL)
- {
- ec_manager(fop, error);
- }
- else
- {
- func(frame, NULL, this, -1, EIO, NULL);
+ if (fop != NULL) {
+ ec_manager (fop, error);
+ } else {
+ func (frame, NULL, this, -1, error, NULL);
}
}
diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c
index c6d3b9fe718..bd3fbc717e5 100644
--- a/xlators/cluster/ec/src/ec.c
+++ b/xlators/cluster/ec/src/ec.c
@@ -10,6 +10,7 @@
#include "defaults.h"
#include "statedump.h"
+#include "compat-errno.h"
#include "ec-mem-types.h"
#include "ec-helpers.h"
@@ -25,6 +26,19 @@
*/
#define EC_MAX_NODES min(EC_MAX_FRAGMENTS * 2 - 1, EC_METHOD_MAX_NODES)
+#define EC_INTERNAL_XATTR_OR_GOTO(name, xattr, op_errno, label) \
+ do { \
+ if (ec_is_internal_xattr (NULL, (char *)name, NULL, NULL)) { \
+ op_errno = EPERM; \
+ goto label; \
+ } \
+ if (name && (strlen (name) == 0) && xattr) { \
+ /* Bulk [f]removexattr/[f]setxattr */ \
+ GF_IF_INTERNAL_XATTR_GOTO (EC_XATTR_PREFIX"*", xattr, \
+ op_errno, label); \
+ } \
+ } while (0)
+
int32_t ec_parse_options(xlator_t * this)
{
ec_t * ec = this->private;
@@ -470,22 +484,41 @@ int32_t ec_gf_fsyncdir(call_frame_t * frame, xlator_t * this, fd_t * fd,
return 0;
}
-int32_t ec_gf_getxattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
- const char * name, dict_t * xdata)
+int32_t
+ec_gf_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- ec_getxattr(frame, this, -1, EC_MINIMUM_MIN, default_getxattr_cbk, NULL,
- loc, name, xdata);
+ int error = 0;
- return 0;
+ if (name && strcmp (name, EC_XATTR_HEAL) != 0) {
+ EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out);
+ }
+
+ ec_getxattr (frame, this, -1, EC_MINIMUM_MIN, default_getxattr_cbk,
+ NULL, loc, name, xdata);
+
+ return 0;
+out:
+ error = ENODATA;
+ STACK_UNWIND_STRICT (getxattr, frame, -1, error, NULL, NULL);
+ return 0;
}
-int32_t ec_gf_fgetxattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
- const char * name, dict_t * xdata)
+int32_t
+ec_gf_fgetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- ec_fgetxattr(frame, this, -1, EC_MINIMUM_MIN, default_fgetxattr_cbk, NULL,
- fd, name, xdata);
+ int error = 0;
- return 0;
+ EC_INTERNAL_XATTR_OR_GOTO(name, NULL, error, out);
+
+ ec_fgetxattr (frame, this, -1, EC_MINIMUM_MIN, default_fgetxattr_cbk,
+ NULL, fd, name, xdata);
+ return 0;
+out:
+ error = ENODATA;
+ STACK_UNWIND_STRICT (fgetxattr, frame, -1, error, NULL, NULL);
+ return 0;
}
int32_t ec_gf_inodelk(call_frame_t * frame, xlator_t * this,
@@ -607,22 +640,38 @@ int32_t ec_gf_readv(call_frame_t * frame, xlator_t * this, fd_t * fd,
return 0;
}
-int32_t ec_gf_removexattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
- const char * name, dict_t * xdata)
+int32_t
+ec_gf_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ const char *name, dict_t *xdata)
{
- ec_removexattr(frame, this, -1, EC_MINIMUM_MIN, default_removexattr_cbk,
- NULL, loc, name, xdata);
+ int error = 0;
- return 0;
+ EC_INTERNAL_XATTR_OR_GOTO (name, xdata, error, out);
+
+ ec_removexattr (frame, this, -1, EC_MINIMUM_MIN,
+ default_removexattr_cbk, NULL, loc, name, xdata);
+
+ return 0;
+out:
+ STACK_UNWIND_STRICT (removexattr, frame, -1, error, NULL);
+ return 0;
}
-int32_t ec_gf_fremovexattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
- const char * name, dict_t * xdata)
+int32_t
+ec_gf_fremovexattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ const char *name, dict_t *xdata)
{
- ec_fremovexattr(frame, this, -1, EC_MINIMUM_MIN, default_fremovexattr_cbk,
- NULL, fd, name, xdata);
+ int error = 0;
- return 0;
+ EC_INTERNAL_XATTR_OR_GOTO (name, xdata, error, out);
+
+ ec_fremovexattr (frame, this, -1, EC_MINIMUM_MIN,
+ default_fremovexattr_cbk, NULL, fd, name, xdata);
+
+ return 0;
+out:
+ STACK_UNWIND_STRICT (fremovexattr, frame, -1, error, NULL);
+ return 0;
}
int32_t ec_gf_rename(call_frame_t * frame, xlator_t * this, loc_t * oldloc,
@@ -661,22 +710,38 @@ int32_t ec_gf_fsetattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
return 0;
}
-int32_t ec_gf_setxattr(call_frame_t * frame, xlator_t * this, loc_t * loc,
- dict_t * dict, int32_t flags, dict_t * xdata)
+int32_t
+ec_gf_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- ec_setxattr(frame, this, -1, EC_MINIMUM_MIN, default_setxattr_cbk, NULL,
- loc, dict, flags, xdata);
+ int error = 0;
- return 0;
+ EC_INTERNAL_XATTR_OR_GOTO ("", dict, error, out);
+
+ ec_setxattr (frame, this, -1, EC_MINIMUM_MIN, default_setxattr_cbk,
+ NULL, loc, dict, flags, xdata);
+
+ return 0;
+out:
+ STACK_UNWIND_STRICT (setxattr, frame, -1, error, NULL);
+ return 0;
}
-int32_t ec_gf_fsetxattr(call_frame_t * frame, xlator_t * this, fd_t * fd,
- dict_t * dict, int32_t flags, dict_t * xdata)
+int32_t
+ec_gf_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd,
+ dict_t *dict, int32_t flags, dict_t *xdata)
{
- ec_fsetxattr(frame, this, -1, EC_MINIMUM_MIN, default_fsetxattr_cbk, NULL,
- fd, dict, flags, xdata);
+ int error = 0;
- return 0;
+ EC_INTERNAL_XATTR_OR_GOTO ("", dict, error, out);
+
+ ec_fsetxattr (frame, this, -1, EC_MINIMUM_MIN, default_fsetxattr_cbk,
+ NULL, fd, dict, flags, xdata);
+
+ return 0;
+out:
+ STACK_UNWIND_STRICT (fsetxattr, frame, -1, error, NULL);
+ return 0;
}
int32_t ec_gf_stat(call_frame_t * frame, xlator_t * this, loc_t * loc,
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
index c7db6226e25..2a042ae577f 100644
--- a/xlators/cluster/ec/src/ec.h
+++ b/xlators/cluster/ec/src/ec.h
@@ -14,10 +14,11 @@
#include "xlator.h"
#include "timer.h"
-#define EC_XATTR_CONFIG "trusted.ec.config"
-#define EC_XATTR_SIZE "trusted.ec.size"
-#define EC_XATTR_VERSION "trusted.ec.version"
-#define EC_XATTR_HEAL "trusted.ec.heal"
+#define EC_XATTR_PREFIX "trusted.ec."
+#define EC_XATTR_CONFIG EC_XATTR_PREFIX"config"
+#define EC_XATTR_SIZE EC_XATTR_PREFIX"size"
+#define EC_XATTR_VERSION EC_XATTR_PREFIX"version"
+#define EC_XATTR_HEAL EC_XATTR_PREFIX"heal"
struct _ec;
typedef struct _ec ec_t;