diff options
author | Rajesh Amaravathi <rajesh@redhat.com> | 2011-12-06 11:35:33 +0530 |
---|---|---|
committer | Anand Avati <avati@gluster.com> | 2012-01-14 04:57:59 -0800 |
commit | 36cedb338ec1d021e189379f30100f0d983e3e01 (patch) | |
tree | 18f6cf77cb43bccd4f31a683e80341d47c10fa66 /xlators | |
parent | 4e76cea78b11e9290b16c2faa85cf81b8e32b7ea (diff) |
core/setxattr: prevent users from setting glusterfs xattrs
* Each xlator prevents the user from setting glusterfs-internal
xattrs like trusted.gfid by handling it in respective setxattr
functions. The speacial case of trusted.gfid is handled in
fuse (Not in posix because posix_setxattr is used to set gfid).
* For xlators which did not define setxattr and/or fsetxattr,
the functions have been implemented with appropriate checks.
xlator | fops-added
_______________|__________________________
|
1. afr | fsetxattr
2. stripe | setxatrr and fsetxattr
3. quota | setxattr and fsetxattr
Change-Id: Ib62abb7067415b23a708002f884d30e8866fbf48
BUG: 765487
Signed-off-by: Rajesh Amaravathi <rajesh@redhat.com>
Reviewed-on: http://review.gluster.com/685
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Amar Tumballi <amar@gluster.com>
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/afr/src/afr-common.c | 5 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.c | 227 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr-inode-write.h | 6 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.c | 1 | ||||
-rw-r--r-- | xlators/cluster/afr/src/afr.h | 5 | ||||
-rw-r--r-- | xlators/cluster/afr/src/pump.c | 7 | ||||
-rw-r--r-- | xlators/cluster/dht/src/dht-common.c | 8 | ||||
-rw-r--r-- | xlators/cluster/stripe/src/stripe.c | 70 | ||||
-rw-r--r-- | xlators/features/quota/src/quota.c | 72 | ||||
-rw-r--r-- | xlators/mount/fuse/src/fuse-bridge.c | 6 |
10 files changed, 387 insertions, 20 deletions
diff --git a/xlators/cluster/afr/src/afr-common.c b/xlators/cluster/afr/src/afr-common.c index 22b30fdfa2e..c247d56b705 100644 --- a/xlators/cluster/afr/src/afr-common.c +++ b/xlators/cluster/afr/src/afr-common.c @@ -940,6 +940,11 @@ afr_local_cleanup (afr_local_t *local, xlator_t *this) dict_unref (local->cont.setxattr.dict); } + { /* fsetxattr */ + if (local->cont.fsetxattr.dict) + dict_unref (local->cont.fsetxattr.dict); + } + { /* removexattr */ GF_FREE (local->cont.removexattr.name); } diff --git a/xlators/cluster/afr/src/afr-inode-write.c b/xlators/cluster/afr/src/afr-inode-write.c index 48094931f2e..cd6ba5e7df8 100644 --- a/xlators/cluster/afr/src/afr-inode-write.c +++ b/xlators/cluster/afr/src/afr-inode-write.c @@ -1355,8 +1355,8 @@ afr_setxattr_unwind (call_frame_t *frame, xlator_t *this) if (main_frame) { AFR_STACK_UNWIND (setxattr, main_frame, - local->op_ret, local->op_errno) - } + local->op_ret, local->op_errno); + } return 0; } @@ -1365,10 +1365,10 @@ int afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno) { - afr_local_t * local = NULL; - afr_private_t * priv = NULL; - int call_count = -1; - int need_unwind = 0; + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int call_count = -1; + int need_unwind = 0; local = frame->local; priv = this->private; @@ -1406,10 +1406,10 @@ afr_setxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int afr_setxattr_wind (call_frame_t *frame, xlator_t *this) { - afr_local_t *local = NULL; - afr_private_t *priv = NULL; - int call_count = -1; - int i = 0; + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int call_count = -1; + int i = 0; local = frame->local; priv = this->private; @@ -1446,7 +1446,7 @@ afr_setxattr_wind (call_frame_t *frame, xlator_t *this) int afr_setxattr_done (call_frame_t *frame, xlator_t *this) { - afr_local_t * local = frame->local; + afr_local_t *local = frame->local; local->transaction.unwind (frame, this); @@ -1459,16 +1459,23 @@ int afr_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict, int32_t flags) { - afr_private_t * priv = NULL; - afr_local_t * local = NULL; + afr_private_t *priv = NULL; + afr_local_t *local = NULL; call_frame_t *transaction_frame = NULL; - int ret = -1; - int op_errno = 0; + data_pair_t *trav = NULL; + int ret = -1; + int op_errno = EINVAL; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (this->private, out); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict, + trav, op_errno, out); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict, + trav, op_errno, out); + priv = this->private; QUORUM_CHECK(setxattr,out); @@ -1511,6 +1518,196 @@ out: return 0; } +/* {{{ fsetxattr */ + + +int +afr_fsetxattr_unwind (call_frame_t *frame, xlator_t *this) +{ + afr_local_t *local = NULL; + call_frame_t *main_frame = NULL; + + local = frame->local; + + LOCK (&frame->lock); + { + if (local->transaction.main_frame) + main_frame = local->transaction.main_frame; + local->transaction.main_frame = NULL; + } + UNLOCK (&frame->lock); + + if (main_frame) { + AFR_STACK_UNWIND (fsetxattr, main_frame, + local->op_ret, local->op_errno); + } + return 0; +} + + +int +afr_fsetxattr_wind_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno) +{ + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int call_count = -1; + int need_unwind = 0; + + local = frame->local; + priv = this->private; + + LOCK (&frame->lock); + { + if (op_ret != -1) { + if (local->success_count == 0) { + local->op_ret = op_ret; + } + local->success_count++; + + if (local->success_count == priv->child_count) { + need_unwind = 1; + } + } + + local->op_errno = op_errno; + } + UNLOCK (&frame->lock); + + if (need_unwind) + local->transaction.unwind (frame, this); + + call_count = afr_frame_return (frame); + + if (call_count == 0) { + local->transaction.resume (frame, this); + } + + return 0; +} + + +int +afr_fsetxattr_wind (call_frame_t *frame, xlator_t *this) +{ + afr_local_t *local = NULL; + afr_private_t *priv = NULL; + int call_count = -1; + int i = 0; + + local = frame->local; + priv = this->private; + + call_count = afr_pre_op_done_children_count (local->transaction.pre_op, + priv->child_count); + + if (call_count == 0) { + local->transaction.resume (frame, this); + return 0; + } + + local->call_count = call_count; + + for (i = 0; i < priv->child_count; i++) { + if (local->transaction.pre_op[i]) { + STACK_WIND_COOKIE (frame, afr_fsetxattr_wind_cbk, + (void *) (long) i, + priv->children[i], + priv->children[i]->fops->fsetxattr, + local->fd, + local->cont.fsetxattr.dict, + local->cont.fsetxattr.flags); + + if (!--call_count) + break; + } + } + + return 0; +} + + +int +afr_fsetxattr_done (call_frame_t *frame, xlator_t *this) +{ + afr_local_t *local = frame->local; + + local->transaction.unwind (frame, this); + + AFR_STACK_DESTROY (frame); + + return 0; +} + +int +afr_fsetxattr (call_frame_t *frame, xlator_t *this, + fd_t *fd, dict_t *dict, int32_t flags) +{ + afr_private_t *priv = NULL; + afr_local_t *local = NULL; + call_frame_t *transaction_frame = NULL; + int ret = -1; + int op_errno = EINVAL; + data_pair_t *trav = NULL; + + VALIDATE_OR_GOTO (frame, out); + VALIDATE_OR_GOTO (this, out); + VALIDATE_OR_GOTO (this->private, out); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.afr.*", dict, + trav, op_errno, out); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.afr.*", dict, + trav, op_errno, out); + + if (ret) + goto out; + + priv = this->private; + + QUORUM_CHECK(fsetxattr,out); + + ALLOC_OR_GOTO (local, afr_local_t, out); + + ret = afr_local_init (local, priv, &op_errno); + if (ret < 0) + goto out; + + transaction_frame = copy_frame (frame); + if (!transaction_frame) { + goto out; + } + + transaction_frame->local = local; + + local->op_ret = -1; + + local->cont.fsetxattr.dict = dict_ref (dict); + local->cont.fsetxattr.flags = flags; + + local->transaction.fop = afr_fsetxattr_wind; + local->transaction.done = afr_fsetxattr_done; + local->transaction.unwind = afr_fsetxattr_unwind; + + local->fd = fd_ref (fd); + + local->transaction.main_frame = frame; + local->transaction.start = LLONG_MAX - 1; + local->transaction.len = 0; + + afr_transaction (transaction_frame, this, AFR_METADATA_TRANSACTION); + + ret = 0; +out: + if (ret < 0) { + if (transaction_frame) + AFR_STACK_DESTROY (transaction_frame); + AFR_STACK_UNWIND (fsetxattr, frame, -1, op_errno); + } + + return 0; +} + /* }}} */ /* {{{ removexattr */ diff --git a/xlators/cluster/afr/src/afr-inode-write.h b/xlators/cluster/afr/src/afr-inode-write.h index f9aa7bd36f6..a2c3520f99f 100644 --- a/xlators/cluster/afr/src/afr-inode-write.h +++ b/xlators/cluster/afr/src/afr-inode-write.h @@ -63,7 +63,11 @@ afr_fsetattr (call_frame_t *frame, xlator_t *this, int32_t afr_setxattr (call_frame_t *frame, xlator_t *this, - loc_t *loc, dict_t *dict, int32_t flags); + loc_t *loc, dict_t *dict, int32_t flags); + +int32_t +afr_fsetxattr (call_frame_t *frame, xlator_t *this, + fd_t *fd, dict_t *dict, int32_t flags); int32_t afr_removexattr (call_frame_t *frame, xlator_t *this, diff --git a/xlators/cluster/afr/src/afr.c b/xlators/cluster/afr/src/afr.c index f3c3e7e7a82..22be68a65e4 100644 --- a/xlators/cluster/afr/src/afr.c +++ b/xlators/cluster/afr/src/afr.c @@ -396,6 +396,7 @@ struct xlator_fops fops = { .truncate = afr_truncate, .ftruncate = afr_ftruncate, .setxattr = afr_setxattr, + .fsetxattr = afr_fsetxattr, .setattr = afr_setattr, .fsetattr = afr_fsetattr, .removexattr = afr_removexattr, diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 8568f1fd8d6..544c9142471 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -550,6 +550,11 @@ typedef struct _afr_local { } setxattr; struct { + dict_t *dict; + int32_t flags; + } fsetxattr; + + struct { char *name; } removexattr; diff --git a/xlators/cluster/afr/src/pump.c b/xlators/cluster/afr/src/pump.c index 1814c8b9ddc..8044fb85bf2 100644 --- a/xlators/cluster/afr/src/pump.c +++ b/xlators/cluster/afr/src/pump.c @@ -20,6 +20,7 @@ #include <unistd.h> #include <sys/time.h> #include <stdlib.h> +#include <fnmatch.h> #ifndef _CONFIG_H #define _CONFIG_H @@ -1642,15 +1643,17 @@ pump_setxattr (call_frame_t *frame, xlator_t *this, afr_private_t * priv = NULL; afr_local_t * local = NULL; call_frame_t *transaction_frame = NULL; - + data_pair_t * trav = NULL; int ret = -1; - int op_errno = 0; VALIDATE_OR_GOTO (frame, out); VALIDATE_OR_GOTO (this, out); VALIDATE_OR_GOTO (this->private, out); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.pump*", dict, + trav, op_errno, out); + priv = this->private; if (!priv->use_afr_in_pump) { STACK_WIND (frame, default_setxattr_cbk, diff --git a/xlators/cluster/dht/src/dht-common.c b/xlators/cluster/dht/src/dht-common.c index 16bb2c9cc7d..785ecbc615c 100644 --- a/xlators/cluster/dht/src/dht-common.c +++ b/xlators/cluster/dht/src/dht-common.c @@ -1706,12 +1706,16 @@ dht_fsetxattr (call_frame_t *frame, xlator_t *this, xlator_t *subvol = NULL; dht_local_t *local = NULL; int op_errno = EINVAL; + data_pair_t *trav = NULL; VALIDATE_OR_GOTO (frame, err); VALIDATE_OR_GOTO (this, err); VALIDATE_OR_GOTO (fd, err); VALIDATE_OR_GOTO (fd->inode, err); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.dht*", xattr, + trav, op_errno, err); + local = dht_local_init (frame, NULL, fd, GF_FOP_FSETXATTR); if (!local) { op_errno = ENOMEM; @@ -1806,6 +1810,7 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, char value[4096] = {0,}; int forced_rebalance = 0; int call_cnt = 0; + data_pair_t *trav = NULL; VALIDATE_OR_GOTO (frame, err); @@ -1814,6 +1819,9 @@ dht_setxattr (call_frame_t *frame, xlator_t *this, VALIDATE_OR_GOTO (loc->inode, err); VALIDATE_OR_GOTO (loc->path, err); + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.dht*", xattr, + trav, op_errno, err); + conf = this->private; local = dht_local_init (frame, loc, NULL, GF_FOP_SETXATTR); if (!local) { diff --git a/xlators/cluster/stripe/src/stripe.c b/xlators/cluster/stripe/src/stripe.c index 01064cd51d9..15cfb8f60e9 100644 --- a/xlators/cluster/stripe/src/stripe.c +++ b/xlators/cluster/stripe/src/stripe.c @@ -32,6 +32,7 @@ * very much necessary, or else, use it in combination with AFR, to have a * backup copy. */ +#include <fnmatch.h> #include "stripe.h" #include "libxlator.h" @@ -4167,6 +4168,72 @@ out: } +int +stripe_setxattr_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno) +{ + STRIPE_STACK_UNWIND (setxattr, frame, op_ret, op_errno); + return 0; +} + +int +stripe_setxattr (call_frame_t *frame, xlator_t *this, + loc_t *loc, dict_t *dict, int flags) +{ + data_pair_t *trav = NULL; + int32_t op_errno = EINVAL; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + VALIDATE_OR_GOTO (loc, err); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.*stripe*", dict, + trav, op_errno, err); + + STACK_WIND (frame, stripe_setxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, + loc, dict, flags); + return 0; +err: + STRIPE_STACK_UNWIND (setxattr, frame, -1, op_errno); + return 0; +} + + +int +stripe_fsetxattr_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno) +{ + STRIPE_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno); + return 0; +} + +int +stripe_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + dict_t *dict, int flags) +{ + data_pair_t *trav = NULL; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + VALIDATE_OR_GOTO (fd, err); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.*stripe*", dict, + trav, op_errno, err); + + STACK_WIND (frame, stripe_fsetxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, + fd, dict, flags); + return 0; + err: + STRIPE_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno); + return 0; +} + int32_t stripe_readdirp_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, gf_dirent_t *orig_entries) @@ -4918,7 +4985,8 @@ struct xlator_fops fops = { .fsetattr = stripe_fsetattr, .lookup = stripe_lookup, .mknod = stripe_mknod, - + .setxattr = stripe_setxattr, + .fsetxattr = stripe_fsetxattr, .getxattr = stripe_getxattr, .readdirp = stripe_readdirp, }; diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 3d147bdb2b4..b2f53048f84 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -17,6 +17,8 @@ <http://www.gnu.org/licenses/>. */ +#include <fnmatch.h> + #include "quota.h" #include "common-utils.h" #include "defaults.h" @@ -2650,6 +2652,72 @@ err: return 0; } +int +quota_setxattr_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno) +{ + QUOTA_STACK_UNWIND (setxattr, frame, op_ret, op_errno); + return 0; +} + +int +quota_setxattr (call_frame_t *frame, xlator_t *this, + loc_t *loc, dict_t *dict, int flags) +{ + data_pair_t *trav = NULL; + int op_errno = EINVAL; + int op_ret = -1; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + VALIDATE_OR_GOTO (loc, err); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict, + trav, op_errno, err); + + STACK_WIND (frame, quota_setxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->setxattr, + loc, dict, flags); + return 0; +err: + QUOTA_STACK_UNWIND (setxattr, frame, op_ret, op_errno); + return 0; +} + +int +quota_fsetxattr_cbk (call_frame_t *frame, void *cookie, + xlator_t *this, int op_ret, int op_errno) +{ + QUOTA_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno); + return 0; +} + +int +quota_fsetxattr (call_frame_t *frame, xlator_t *this, fd_t *fd, + dict_t *dict, int flags) +{ + data_pair_t *trav = NULL; + int32_t op_ret = -1; + int32_t op_errno = EINVAL; + + VALIDATE_OR_GOTO (frame, err); + VALIDATE_OR_GOTO (this, err); + VALIDATE_OR_GOTO (fd, err); + + GF_IF_INTERNAL_XATTR_GOTO ("trusted.glusterfs.quota*", dict, + trav, op_errno, err); + + STACK_WIND (frame, quota_fsetxattr_cbk, + FIRST_CHILD(this), + FIRST_CHILD(this)->fops->fsetxattr, + fd, dict, flags); + return 0; + err: + QUOTA_STACK_UNWIND (fsetxattr, frame, op_ret, op_errno); + return 0; +} + int32_t quota_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, @@ -2950,7 +3018,9 @@ struct xlator_fops fops = { .fsync = quota_fsync, .setattr = quota_setattr, .fsetattr = quota_fsetattr, - .mknod = quota_mknod + .mknod = quota_mknod, + .setxattr = quota_setxattr, + .fsetxattr = quota_fsetxattr }; struct xlator_cbks cbks = { diff --git a/xlators/mount/fuse/src/fuse-bridge.c b/xlators/mount/fuse/src/fuse-bridge.c index 32c80075356..8c1cd8f7568 100644 --- a/xlators/mount/fuse/src/fuse-bridge.c +++ b/xlators/mount/fuse/src/fuse-bridge.c @@ -2641,6 +2641,12 @@ fuse_setxattr (xlator_t *this, fuse_in_header_t *finh, void *msg) return; } + if (!strcmp (GFID_XATTR_KEY, name)) { + send_fuse_err (this, finh, EPERM); + GF_FREE (finh); + return; + } + GET_STATE (this, finh, state); state->size = fsi->size; ret = fuse_loc_fill (&state->loc, state, finh->nodeid, 0, NULL); |