From 8c3c6a779b9d1b20c7b413caa25381ab07a08a87 Mon Sep 17 00:00:00 2001
From: Ravishankar N <ravishankar@redhat.com>
Date: Wed, 19 Sep 2018 15:20:27 +0530
Subject: [PATCH 378/385] posix/afr: handle backward compatibility for
rchecksum fop
Patch on upstream master: https://review.gluster.org/#/c/glusterfs/+/19538/
Added a volume option 'fips-mode-rchecksum' tied to op version 4.
If not set, rchecksum fop will use MD5 instead of SHA256.
Change-Id: I720777c0ab36985774e6bb877689fe45b64eb777
BUG: 1459709
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/150479
Tested-by: RHGS Build Bot <nigelb@redhat.com>
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
---
libglusterfs/src/checksum.c | 7 +++++
libglusterfs/src/checksum.h | 2 ++
libglusterfs/src/globals.h | 2 ++
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 | 6 ++++
xlators/protocol/server/src/server-common.c | 2 +-
xlators/storage/posix/src/posix.c | 39 +++++++++++++++++++++++--
xlators/storage/posix/src/posix.h | 2 ++
10 files changed, 85 insertions(+), 13 deletions(-)
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
index a7f9877..561ca04 100644
--- a/libglusterfs/src/checksum.c
+++ b/libglusterfs/src/checksum.c
@@ -8,6 +8,7 @@
cases as published by the Free Software Foundation.
*/
+#include <openssl/md5.h>
#include <openssl/sha.h>
#include <zlib.h>
#include <stdint.h>
@@ -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 bf7eeed..677a59a 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/globals.h b/libglusterfs/src/globals.h
index 39d9716..e810ea7 100644
--- a/libglusterfs/src/globals.h
+++ b/libglusterfs/src/globals.h
@@ -109,6 +109,8 @@
#define GD_OP_VERSION_3_13_2 31302 /* Op-version for GlusterFS 3.13.2 */
+#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */
+
/* Downstream only change */
#define GD_OP_VERSION_3_11_2 31102 /* Op-version for RHGS 3.3.1-async */
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
index 2989b9e..7e6a691 100644
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
@@ -665,7 +665,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 dd44deb..556a8f9 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 7cb6f00..76ad292 100644
--- a/xlators/cluster/afr/src/afr.h
+++ b/xlators/cluster/afr/src/afr.h
@@ -273,6 +273,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 474587a..0ff512d 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -2868,6 +2868,12 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "storage/posix",
.op_version = GD_OP_VERSION_3_13_0,
},
+ { .option = "fips-mode-rchecksum",
+ .key = "storage.fips-mode-rchecksum",
+ .type = NO_DOC,
+ .voltype = "storage/posix",
+ .op_version = GD_OP_VERSION_4_0_0,
+ },
{ .key = "storage.bd-aio",
.voltype = "storage/bd",
.op_version = GD_OP_VERSION_RHS_3_0
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
index 9c38706..ce33089 100644
--- a/xlators/protocol/server/src/server-common.c
+++ b/xlators/protocol/server/src/server-common.c
@@ -298,7 +298,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;
}
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
index 4e13465..1d3f1ee 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -7000,7 +7000,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;
@@ -7069,13 +7071,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);
@@ -7295,6 +7315,9 @@ reconfigure (xlator_t *this, dict_t *options)
GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count,
options, int32, out);
+ GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum,
+ options, bool, out);
+
ret = 0;
out:
return ret;
@@ -7953,6 +7976,9 @@ init (xlator_t *this)
GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec,
uint32, out);
+
+ GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum,
+ bool, out);
out:
return ret;
}
@@ -8182,5 +8208,12 @@ struct volume_options options[] = {
" Useful for displaying the proper usable size through statvfs() "
"call (df command)",
},
+ {
+ .key = {"fips-mode-rchecksum"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "off",
+ .description = "If enabled, posix_rchecksum uses the FIPS compliant"
+ "SHA256 checksum. MD5 otherwise."
+ },
{ .key = {NULL} }
};
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
index eaf4d0d..bda4172 100644
--- a/xlators/storage/posix/src/posix.h
+++ b/xlators/storage/posix/src/posix.h
@@ -227,6 +227,8 @@ struct posix_private {
/* Option to handle the cases of multiple bricks exported from
same backend. Very much usable in brick-splitting feature. */
int32_t shared_brick_count;
+
+ gf_boolean_t fips_mode_rchecksum;
};
typedef struct {
--
1.8.3.1