diff options
| author | Raghavendra Bhat <raghavendra@redhat.com> | 2015-06-24 20:06:01 +0530 | 
|---|---|---|
| committer | Venky Shankar <vshankar@redhat.com> | 2015-06-27 04:18:47 -0700 | 
| commit | 0a24b8f2be5f8b124d76a13f2a4b6cb9058c9a30 (patch) | |
| tree | 5a6a5a6ebd138cf9d1bc342418dbccde7924ccfc /xlators/features/bit-rot/src/stub/bit-rot-stub.c | |
| parent | 15dcfe98caa573e87d898cb66c13ef7187730c6b (diff) | |
features/bit-rot-stub: do not allow setxattr and removexattr on bit-rot xattrs
* setxattr and {f}removexattr of versioning, signature and bad-file xattrs are
  returned with error.
Change-Id: Ib423466195d1d8e4c6f80c2906a574e21ed624fb
BUG: 1210689
Signed-off-by: Raghavendra Bhat <raghavendra@redhat.com>
Reviewed-on: http://review.gluster.org/11389
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Reviewed-by: Venky Shankar <vshankar@redhat.com>
Diffstat (limited to 'xlators/features/bit-rot/src/stub/bit-rot-stub.c')
| -rw-r--r-- | xlators/features/bit-rot/src/stub/bit-rot-stub.c | 103 | 
1 files changed, 97 insertions, 6 deletions
diff --git a/xlators/features/bit-rot/src/stub/bit-rot-stub.c b/xlators/features/bit-rot/src/stub/bit-rot-stub.c index 440ad7e30e9..2efb63e7db5 100644 --- a/xlators/features/bit-rot/src/stub/bit-rot-stub.c +++ b/xlators/features/bit-rot/src/stub/bit-rot-stub.c @@ -988,6 +988,37 @@ unwind:          return 0;  } + +/** + * As of now, versioning is done by the stub (though as a setxattr + * operation) as part of inode modification operations such as writev, + * truncate, ftruncate. And signing is done by BitD by a fsetxattr call. + * So any kind of setxattr coming on the versioning and the signing xattr is + * not allowed (i.e. BITROT_CURRENT_VERSION_KEY and BITROT_SIGNING_VERSION_KEY). + * In future if BitD/scrubber are allowed to change the versioning + * xattrs (though I cannot see a reason for it as of now), then the below + * function can be modified to block setxattr on version for only applications. + * + * NOTE: BitD sends sign request on GLUSTERFS_SET_OBJECT_SIGNATURE key. + *       BITROT_SIGNING_VERSION_KEY is the xattr used to save the signature. + * + */ +static int32_t +br_stub_handle_internal_xattr (call_frame_t *frame, xlator_t *this, fd_t *fd, +                               char *key) +{ +        int32_t          op_ret   = -1; +        int32_t          op_errno = EINVAL; + +        gf_msg (this->name, GF_LOG_ERROR, 0, +                BRS_MSG_SET_INTERNAL_XATTR, "setxattr called" +                " on the internal xattr %s for inode %s", key, +                uuid_utoa (fd->inode->gfid)); + +        STACK_UNWIND_STRICT (fsetxattr, frame, op_ret, op_errno, NULL); +        return 0; +} +  int  br_stub_fsetxattr (call_frame_t *frame, xlator_t *this,                     fd_t *fd, dict_t *dict, int flags, dict_t *xdata) @@ -1008,6 +1039,20 @@ br_stub_fsetxattr (call_frame_t *frame, xlator_t *this,                  goto done;          } +        /* signing xattr */ +        if (dict_get(dict, BITROT_SIGNING_VERSION_KEY)) { +                br_stub_handle_internal_xattr (frame, this, fd, +                                               BITROT_SIGNING_VERSION_KEY); +                goto done; +        } + +        /* version xattr */ +        if (dict_get(dict, BITROT_CURRENT_VERSION_KEY)) { +                br_stub_handle_internal_xattr (frame, this, fd, +                                               BITROT_CURRENT_VERSION_KEY); +                goto done; +        } +          /* object reopen request */          ret = dict_get_uint32 (dict, BR_REOPEN_SIGN_HINT_KEY, &val);          if (!ret) { @@ -1030,6 +1075,45 @@ done:          return 0;  } + +/** + * Currently BitD and scrubber are doing fsetxattr to either sign the object + * or to mark it as bad. Hence setxattr on any of those keys is denied directly + * without checking from where the fop is coming. + * Later, if BitD or Scrubber does setxattr of those keys, then appropriate + * check has to be added below. + */ +int +br_stub_setxattr (call_frame_t *frame, xlator_t *this, +                  loc_t *loc, dict_t *dict, int flags, dict_t *xdata) +{ +        int32_t  op_ret                    = -1; +        int32_t  op_errno                  = EINVAL; +        char     dump[64*1024]             = {0,}; +        char    *format                    = "(%s:%s)"; + +        if (dict_get (dict, GLUSTERFS_SET_OBJECT_SIGNATURE) || +            dict_get (dict, BR_REOPEN_SIGN_HINT_KEY) || +            dict_get (dict, BITROT_OBJECT_BAD_KEY) || +            dict_get (dict, BITROT_SIGNING_VERSION_KEY) || +            dict_get (dict, BITROT_CURRENT_VERSION_KEY)) { +                dict_dump_to_str (dict, dump, sizeof(dump), format); +                gf_msg (this->name, GF_LOG_ERROR, 0, +                        BRS_MSG_SET_INTERNAL_XATTR, "setxattr called on " +                        "internal xattr %s", dump); +                goto unwind; +        } + + +        STACK_WIND_TAIL (frame, FIRST_CHILD (this), +                         FIRST_CHILD (this)->fops->setxattr, loc, dict, flags, +                         xdata); +        return 0; +unwind: +        STACK_UNWIND_STRICT (setxattr, frame, op_ret, op_errno, NULL); +        return 0; +} +  /** }}} */ @@ -1044,13 +1128,16 @@ br_stub_removexattr (call_frame_t *frame, xlator_t *this,          int32_t op_ret    = -1;          int32_t op_errno  = EINVAL; -        if (!strcmp (BITROT_OBJECT_BAD_KEY, name)) { +        if (!strcmp (BITROT_OBJECT_BAD_KEY, name) || +            !strcmp (BITROT_SIGNING_VERSION_KEY, name) || +            !strcmp (BITROT_CURRENT_VERSION_KEY, name)) {                  gf_msg (this->name, GF_LOG_WARNING, 0, -                        BRS_MSG_REMOVE_BAD_OBJECT_XATTR, "Remove xattr called" -                        " on bad object xattr for file %s", loc->path); +                        BRS_MSG_REMOVE_INTERNAL_XATTR, "removexattr called" +                        " on internal xattr %s for file %s", name, loc->path);                  goto unwind;          } +          STACK_WIND_TAIL (frame, FIRST_CHILD(this),                           FIRST_CHILD(this)->fops->removexattr,                           loc, name, xdata); @@ -1067,14 +1154,17 @@ br_stub_fremovexattr (call_frame_t *frame, xlator_t *this,          int32_t op_ret    = -1;          int32_t op_errno  = EINVAL; -        if (!strcmp (BITROT_OBJECT_BAD_KEY, name)) { +        if (!strcmp (BITROT_OBJECT_BAD_KEY, name) || +            !strcmp (BITROT_SIGNING_VERSION_KEY, name) || +            !strcmp (BITROT_CURRENT_VERSION_KEY, name)) {                  gf_msg (this->name, GF_LOG_WARNING, 0, -                        BRS_MSG_REMOVE_BAD_OBJECT_XATTR, "Remove xattr called" -                        " on bad object xattr for inode %s", +                        BRS_MSG_REMOVE_INTERNAL_XATTR, "removexattr called" +                        " on internal xattr %s for inode %s", name,                          uuid_utoa (fd->inode->gfid));                  goto unwind;          } +          STACK_WIND_TAIL (frame, FIRST_CHILD(this),                           FIRST_CHILD(this)->fops->fremovexattr,                           fd, name, xdata); @@ -2588,6 +2678,7 @@ struct xlator_fops fops = {          .readv     = br_stub_readv,          .removexattr = br_stub_removexattr,          .fremovexattr = br_stub_fremovexattr, +        .setxattr  = br_stub_setxattr,  };  struct xlator_cbks cbks = {  | 
