From 325d714e40b273b99a63f58a4c6c83b7f1143ee5 Mon Sep 17 00:00:00 2001 From: Ravishankar N Date: Sun, 11 Feb 2018 06:54:35 +0530 Subject: posix/afr: handle backward compatibility for rchecksum fop Added a volume option 'fips-mode-rchecksum' tied to op version 4. If not set, rchecksum fop will use MD5 instead of SHA256. updates: #230 Change-Id: Id8ea1303777e6450852c0bc25503cda341a6aec2 Signed-off-by: Ravishankar N (cherry picked from commit 6daa6535692b2c68b493636a9bbfdcbc475b3d80) --- libglusterfs/src/checksum.c | 7 ++++++ libglusterfs/src/checksum.h | 2 ++ libglusterfs/src/libglusterfs.sym | 1 + xlators/cluster/afr/src/afr-self-heal-common.c | 8 ++++++- xlators/cluster/afr/src/afr-self-heal-data.c | 29 ++++++++++++++++++------- xlators/cluster/afr/src/afr.h | 1 + xlators/mgmt/glusterd/src/glusterd-volume-set.c | 7 ++++++ xlators/protocol/server/src/server-common.c | 3 ++- xlators/storage/posix/src/posix-common.c | 16 ++++++++++++++ xlators/storage/posix/src/posix-inode-fd-ops.c | 26 +++++++++++++++++++--- xlators/storage/posix/src/posix.h | 2 ++ 11 files changed, 89 insertions(+), 13 deletions(-) diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c index a7f9877ddf0..561ca04e48b 100644 --- a/libglusterfs/src/checksum.c +++ b/libglusterfs/src/checksum.c @@ -8,6 +8,7 @@ cases as published by the Free Software Foundation. */ +#include #include #include #include @@ -36,3 +37,9 @@ gf_rsync_strong_checksum (unsigned char *data, size_t len, { SHA256((const unsigned char *)data, len, sha256_md); } + +void +gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5) +{ + MD5 (data, len, md5); +} diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h index bf7eeede8fc..677a59aa91e 100644 --- a/libglusterfs/src/checksum.h +++ b/libglusterfs/src/checksum.h @@ -17,4 +17,6 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len); void gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum); +void +gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5); #endif /* __CHECKSUM_H__ */ diff --git a/libglusterfs/src/libglusterfs.sym b/libglusterfs/src/libglusterfs.sym index 500f69a9893..8d263c4cb5c 100644 --- a/libglusterfs/src/libglusterfs.sym +++ b/libglusterfs/src/libglusterfs.sym @@ -638,6 +638,7 @@ gf_resolve_path_parent gf_rev_dns_lookup gf_rev_dns_lookup_cached gf_rsync_strong_checksum +gf_rsync_md5_checksum gf_rsync_weak_checksum gf_set_log_file_path gf_set_log_ident diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c index 7e2a6027126..7195dfe058c 100644 --- a/xlators/cluster/afr/src/afr-self-heal-common.c +++ b/xlators/cluster/afr/src/afr-self-heal-common.c @@ -648,7 +648,13 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src) if (dst->xdata) dict_unref (dst->xdata); dst->xdata = xdata; - memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH); + if (xdata && dict_get_str_boolean (xdata, "fips-mode-rchecksum", + _gf_false) == _gf_true) { + memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH); + } else { + memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH); + } + dst->fips_mode_rchecksum = src->fips_mode_rchecksum; } void diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c index c033a8afc07..30a23de2d5f 100644 --- a/xlators/cluster/afr/src/afr-self-heal-data.c +++ b/xlators/cluster/afr/src/afr-self-heal-data.c @@ -38,11 +38,21 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this, replies[i].valid = 1; replies[i].op_ret = op_ret; replies[i].op_errno = op_errno; - if (xdata) + if (xdata) { replies[i].buf_has_zeroes = dict_get_str_boolean (xdata, "buf-has-zeroes", _gf_false); - if (strong) - memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH); + replies[i].fips_mode_rchecksum = dict_get_str_boolean (xdata, + "fips-mode-rchecksum", _gf_false); + } + if (strong) { + if (replies[i].fips_mode_rchecksum) { + memcpy (local->replies[i].checksum, strong, + SHA256_DIGEST_LENGTH); + } else { + memcpy (local->replies[i].checksum, strong, + MD5_DIGEST_LENGTH); + } + } syncbarrier_wake (&local->barrier); return 0; @@ -58,11 +68,13 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd, afr_local_t *local = NULL; unsigned char *wind_subvols = NULL; gf_boolean_t checksum_match = _gf_true; + struct afr_reply *replies = NULL; dict_t *xdata = NULL; int i = 0; priv = this->private; local = frame->local; + replies = local->replies; xdata = dict_new(); if (!xdata) @@ -83,16 +95,17 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd, if (xdata) dict_unref (xdata); - if (!local->replies[source].valid || local->replies[source].op_ret != 0) + if (!replies[source].valid || replies[source].op_ret != 0) return _gf_false; for (i = 0; i < priv->child_count; i++) { if (i == source) continue; - if (local->replies[i].valid) { - if (memcmp (local->replies[source].checksum, - local->replies[i].checksum, - SHA256_DIGEST_LENGTH)) { + if (replies[i].valid) { + if (memcmp (replies[source].checksum, + replies[i].checksum, + replies[source].fips_mode_rchecksum ? + SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) { checksum_match = _gf_false; break; } diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h index 220cc0b5d41..9f4e34a2afa 100644 --- a/xlators/cluster/afr/src/afr.h +++ b/xlators/cluster/afr/src/afr.h @@ -322,6 +322,7 @@ struct afr_reply { /* For rchecksum */ uint8_t checksum[SHA256_DIGEST_LENGTH]; gf_boolean_t buf_has_zeroes; + gf_boolean_t fips_mode_rchecksum; /* For lookup */ int8_t need_heal; }; diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c index 674769c0b8f..6b601592542 100644 --- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c +++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c @@ -2898,6 +2898,13 @@ struct volopt_map_entry glusterd_volopt_map[] = { }, { .option = "health-check-timeout", .key = "storage.health-check-timeout", + .type = NO_DOC, + .voltype = "storage/posix", + .op_version = GD_OP_VERSION_4_0_0, + }, + { .option = "fips-mode-rchecksum", + .key = "storage.fips-mode-rchecksum", + .type = NO_DOC, .voltype = "storage/posix", .op_version = GD_OP_VERSION_4_0_0, }, diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c index 17660ef475e..071a1cf2714 100644 --- a/xlators/protocol/server/src/server-common.c +++ b/xlators/protocol/server/src/server-common.c @@ -299,7 +299,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum, rsp->weak_checksum = weak_checksum; rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum; - rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH; + rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH; } @@ -670,6 +670,7 @@ server4_post_rchecksum (gfx_rchecksum_rsp *rsp, uint32_t weak_checksum, rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum; rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH; + rsp->flags = 1; /* Indicates SHA256 TYPE */ } diff --git a/xlators/storage/posix/src/posix-common.c b/xlators/storage/posix/src/posix-common.c index fa2655ed8c0..345d35e3e9a 100644 --- a/xlators/storage/posix/src/posix-common.c +++ b/xlators/storage/posix/src/posix-common.c @@ -414,6 +414,9 @@ posix_reconfigure (xlator_t *this, dict_t *options) GF_OPTION_RECONF ("max-hardlinks", priv->max_hardlinks, options, uint32, out); + + GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum, + options, bool, out); ret = 0; out: return ret; @@ -1103,6 +1106,9 @@ posix_init (xlator_t *this) _private->create_directory_mask = create_directory_mask; GF_OPTION_INIT ("max-hardlinks", _private->max_hardlinks, uint32, out); + + GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum, + bool, out); out: if (ret) { if (_private) { @@ -1371,5 +1377,15 @@ struct volume_options options[] = { .description = "max number of hardlinks allowed on any one inode.\n" "0 is unlimited, 1 prevents any hardlinking at all." }, + { + .key = {"fips-mode-rchecksum"}, + .type = GF_OPTION_TYPE_BOOL, + .default_value = "off", + .op_version = {GD_OP_VERSION_4_0_0}, + .flags = OPT_FLAG_SETTABLE, + .tags = {"posix"}, + .description = "If enabled, posix_rchecksum uses the FIPS compliant" + "SHA256 checksum. MD5 otherwise." + }, { .key = {NULL} } }; diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c index 812cf792874..f3a2a7bfb83 100644 --- a/xlators/storage/posix/src/posix-inode-fd-ops.c +++ b/xlators/storage/posix/src/posix-inode-fd-ops.c @@ -4873,7 +4873,9 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, ssize_t bytes_read = 0; int32_t weak_checksum = 0; int32_t zerofillcheck = 0; + unsigned char md5_checksum[MD5_DIGEST_LENGTH] = {0}; unsigned char strong_checksum[SHA256_DIGEST_LENGTH] = {0}; + unsigned char *checksum = NULL; struct posix_private *priv = NULL; dict_t *rsp_xdata = NULL; gf_boolean_t buf_has_zeroes = _gf_false; @@ -4942,13 +4944,31 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this, } } weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret); - gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read, - (unsigned char *) strong_checksum); + if (priv->fips_mode_rchecksum) { + ret = dict_set_int32 (rsp_xdata, "fips-mode-rchecksum", 1); + if (ret) { + gf_msg (this->name, GF_LOG_WARNING, -ret, + P_MSG_DICT_SET_FAILED, "%s: Failed to set " + "dictionary value for key: %s", + uuid_utoa (fd->inode->gfid), + "fips-mode-rchecksum"); + goto out; + } + checksum = strong_checksum; + gf_rsync_strong_checksum ((unsigned char *)buf, + (size_t) bytes_read, + (unsigned char *)checksum); + } else { + checksum = md5_checksum; + gf_rsync_md5_checksum ((unsigned char *)buf, + (size_t) bytes_read, + (unsigned char *)checksum); + } op_ret = 0; out: STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno, - weak_checksum, strong_checksum, rsp_xdata); + weak_checksum, checksum, rsp_xdata); if (rsp_xdata) dict_unref (rsp_xdata); GF_FREE (alloc_buf); diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h index 720c3011f5a..69752ff4c6a 100644 --- a/xlators/storage/posix/src/posix.h +++ b/xlators/storage/posix/src/posix.h @@ -243,6 +243,8 @@ struct posix_private { mode_t create_mask; mode_t create_directory_mask; uint32_t max_hardlinks; + + gf_boolean_t fips_mode_rchecksum; }; typedef struct { -- cgit