887953
From 8c3c6a779b9d1b20c7b413caa25381ab07a08a87 Mon Sep 17 00:00:00 2001
887953
From: Ravishankar N <ravishankar@redhat.com>
887953
Date: Wed, 19 Sep 2018 15:20:27 +0530
887953
Subject: [PATCH 378/385] posix/afr: handle backward compatibility for
887953
 rchecksum fop
887953
887953
Patch on upstream master: https://review.gluster.org/#/c/glusterfs/+/19538/
887953
887953
Added a volume option 'fips-mode-rchecksum' tied to op version 4.
887953
If not set, rchecksum fop will use MD5 instead of SHA256.
887953
887953
Change-Id: I720777c0ab36985774e6bb877689fe45b64eb777
887953
BUG: 1459709
887953
Signed-off-by: Ravishankar N <ravishankar@redhat.com>
887953
Reviewed-on: https://code.engineering.redhat.com/gerrit/150479
887953
Tested-by: RHGS Build Bot <nigelb@redhat.com>
887953
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
887953
Reviewed-by: Sunil Kumar Heggodu Gopala Acharya <sheggodu@redhat.com>
887953
---
887953
 libglusterfs/src/checksum.c                     |  7 +++++
887953
 libglusterfs/src/checksum.h                     |  2 ++
887953
 libglusterfs/src/globals.h                      |  2 ++
887953
 xlators/cluster/afr/src/afr-self-heal-common.c  |  8 ++++-
887953
 xlators/cluster/afr/src/afr-self-heal-data.c    | 29 +++++++++++++-----
887953
 xlators/cluster/afr/src/afr.h                   |  1 +
887953
 xlators/mgmt/glusterd/src/glusterd-volume-set.c |  6 ++++
887953
 xlators/protocol/server/src/server-common.c     |  2 +-
887953
 xlators/storage/posix/src/posix.c               | 39 +++++++++++++++++++++++--
887953
 xlators/storage/posix/src/posix.h               |  2 ++
887953
 10 files changed, 85 insertions(+), 13 deletions(-)
887953
887953
diff --git a/libglusterfs/src/checksum.c b/libglusterfs/src/checksum.c
887953
index a7f9877..561ca04 100644
887953
--- a/libglusterfs/src/checksum.c
887953
+++ b/libglusterfs/src/checksum.c
887953
@@ -8,6 +8,7 @@
887953
   cases as published by the Free Software Foundation.
887953
 */
887953
 
887953
+#include <openssl/md5.h>
887953
 #include <openssl/sha.h>
887953
 #include <zlib.h>
887953
 #include <stdint.h>
887953
@@ -36,3 +37,9 @@ gf_rsync_strong_checksum (unsigned char *data, size_t len,
887953
 {
887953
         SHA256((const unsigned char *)data, len, sha256_md);
887953
 }
887953
+
887953
+void
887953
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5)
887953
+{
887953
+        MD5 (data, len, md5);
887953
+}
887953
diff --git a/libglusterfs/src/checksum.h b/libglusterfs/src/checksum.h
887953
index bf7eeed..677a59a 100644
887953
--- a/libglusterfs/src/checksum.h
887953
+++ b/libglusterfs/src/checksum.h
887953
@@ -17,4 +17,6 @@ gf_rsync_weak_checksum (unsigned char *buf, size_t len);
887953
 void
887953
 gf_rsync_strong_checksum (unsigned char *buf, size_t len, unsigned char *sum);
887953
 
887953
+void
887953
+gf_rsync_md5_checksum (unsigned char *data, size_t len, unsigned char *md5);
887953
 #endif /* __CHECKSUM_H__ */
887953
diff --git a/libglusterfs/src/globals.h b/libglusterfs/src/globals.h
887953
index 39d9716..e810ea7 100644
887953
--- a/libglusterfs/src/globals.h
887953
+++ b/libglusterfs/src/globals.h
887953
@@ -109,6 +109,8 @@
887953
 
887953
 #define GD_OP_VERSION_3_13_2   31302 /* Op-version for GlusterFS 3.13.2 */
887953
 
887953
+#define GD_OP_VERSION_4_0_0 40000 /* Op-version for GlusterFS 4.0.0 */
887953
+
887953
 /* Downstream only change */
887953
 #define GD_OP_VERSION_3_11_2   31102 /* Op-version for RHGS 3.3.1-async */
887953
 
887953
diff --git a/xlators/cluster/afr/src/afr-self-heal-common.c b/xlators/cluster/afr/src/afr-self-heal-common.c
887953
index 2989b9e..7e6a691 100644
887953
--- a/xlators/cluster/afr/src/afr-self-heal-common.c
887953
+++ b/xlators/cluster/afr/src/afr-self-heal-common.c
887953
@@ -665,7 +665,13 @@ afr_reply_copy (struct afr_reply *dst, struct afr_reply *src)
887953
 	if (dst->xdata)
887953
 		dict_unref (dst->xdata);
887953
 	dst->xdata = xdata;
887953
-	memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
887953
+        if (xdata && dict_get_str_boolean (xdata, "fips-mode-rchecksum",
887953
+            _gf_false) == _gf_true) {
887953
+                memcpy (dst->checksum, src->checksum, SHA256_DIGEST_LENGTH);
887953
+        } else {
887953
+                memcpy (dst->checksum, src->checksum, MD5_DIGEST_LENGTH);
887953
+        }
887953
+        dst->fips_mode_rchecksum = src->fips_mode_rchecksum;
887953
 }
887953
 
887953
 void
887953
diff --git a/xlators/cluster/afr/src/afr-self-heal-data.c b/xlators/cluster/afr/src/afr-self-heal-data.c
887953
index dd44deb..556a8f9 100644
887953
--- a/xlators/cluster/afr/src/afr-self-heal-data.c
887953
+++ b/xlators/cluster/afr/src/afr-self-heal-data.c
887953
@@ -38,11 +38,21 @@ __checksum_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
887953
 	replies[i].valid = 1;
887953
 	replies[i].op_ret = op_ret;
887953
 	replies[i].op_errno = op_errno;
887953
-        if (xdata)
887953
+        if (xdata) {
887953
                 replies[i].buf_has_zeroes = dict_get_str_boolean (xdata,
887953
                                                    "buf-has-zeroes", _gf_false);
887953
-	if (strong)
887953
-            memcpy (local->replies[i].checksum, strong, SHA256_DIGEST_LENGTH);
887953
+                replies[i].fips_mode_rchecksum = dict_get_str_boolean (xdata,
887953
+                                              "fips-mode-rchecksum", _gf_false);
887953
+        }
887953
+	if (strong) {
887953
+                if (replies[i].fips_mode_rchecksum) {
887953
+                        memcpy (local->replies[i].checksum, strong,
887953
+                                SHA256_DIGEST_LENGTH);
887953
+                } else {
887953
+                        memcpy (local->replies[i].checksum, strong,
887953
+                                MD5_DIGEST_LENGTH);
887953
+                }
887953
+        }
887953
 
887953
 	syncbarrier_wake (&local->barrier);
887953
 	return 0;
887953
@@ -58,11 +68,13 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
887953
 	afr_local_t *local = NULL;
887953
 	unsigned char *wind_subvols = NULL;
887953
         gf_boolean_t checksum_match = _gf_true;
887953
+        struct afr_reply *replies = NULL;
887953
         dict_t *xdata = NULL;
887953
 	int i = 0;
887953
 
887953
 	priv = this->private;
887953
 	local = frame->local;
887953
+        replies = local->replies;
887953
 
887953
         xdata = dict_new();
887953
         if (!xdata)
887953
@@ -83,16 +95,17 @@ __afr_can_skip_data_block_heal (call_frame_t *frame, xlator_t *this, fd_t *fd,
887953
         if (xdata)
887953
                 dict_unref (xdata);
887953
 
887953
-	if (!local->replies[source].valid || local->replies[source].op_ret != 0)
887953
+	if (!replies[source].valid || replies[source].op_ret != 0)
887953
 		return _gf_false;
887953
 
887953
 	for (i = 0; i < priv->child_count; i++) {
887953
 		if (i == source)
887953
 			continue;
887953
-                if (local->replies[i].valid) {
887953
-                        if (memcmp (local->replies[source].checksum,
887953
-                                    local->replies[i].checksum,
887953
-                                    SHA256_DIGEST_LENGTH)) {
887953
+                if (replies[i].valid) {
887953
+                        if (memcmp (replies[source].checksum,
887953
+                                    replies[i].checksum,
887953
+                                    replies[source].fips_mode_rchecksum ?
887953
+                                    SHA256_DIGEST_LENGTH : MD5_DIGEST_LENGTH)) {
887953
                                 checksum_match = _gf_false;
887953
                                 break;
887953
                         }
887953
diff --git a/xlators/cluster/afr/src/afr.h b/xlators/cluster/afr/src/afr.h
887953
index 7cb6f00..76ad292 100644
887953
--- a/xlators/cluster/afr/src/afr.h
887953
+++ b/xlators/cluster/afr/src/afr.h
887953
@@ -273,6 +273,7 @@ struct afr_reply {
887953
         /* For rchecksum */
887953
 	uint8_t checksum[SHA256_DIGEST_LENGTH];
887953
         gf_boolean_t buf_has_zeroes;
887953
+        gf_boolean_t fips_mode_rchecksum;
887953
         /* For lookup */
887953
         int8_t need_heal;
887953
 };
887953
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
887953
index 474587a..0ff512d 100644
887953
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
887953
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
887953
@@ -2868,6 +2868,12 @@ struct volopt_map_entry glusterd_volopt_map[] = {
887953
           .voltype     = "storage/posix",
887953
           .op_version  = GD_OP_VERSION_3_13_0,
887953
         },
887953
+        { .option      = "fips-mode-rchecksum",
887953
+          .key         = "storage.fips-mode-rchecksum",
887953
+          .type        = NO_DOC,
887953
+          .voltype     = "storage/posix",
887953
+          .op_version  = GD_OP_VERSION_4_0_0,
887953
+        },
887953
         { .key         = "storage.bd-aio",
887953
           .voltype     = "storage/bd",
887953
           .op_version  = GD_OP_VERSION_RHS_3_0
887953
diff --git a/xlators/protocol/server/src/server-common.c b/xlators/protocol/server/src/server-common.c
887953
index 9c38706..ce33089 100644
887953
--- a/xlators/protocol/server/src/server-common.c
887953
+++ b/xlators/protocol/server/src/server-common.c
887953
@@ -298,7 +298,7 @@ server_post_rchecksum (gfs3_rchecksum_rsp *rsp, uint32_t weak_checksum,
887953
         rsp->weak_checksum = weak_checksum;
887953
 
887953
         rsp->strong_checksum.strong_checksum_val = (char *)strong_checksum;
887953
-        rsp->strong_checksum.strong_checksum_len = SHA256_DIGEST_LENGTH;
887953
+        rsp->strong_checksum.strong_checksum_len = MD5_DIGEST_LENGTH;
887953
 
887953
 }
887953
 
887953
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
887953
index 4e13465..1d3f1ee 100644
887953
--- a/xlators/storage/posix/src/posix.c
887953
+++ b/xlators/storage/posix/src/posix.c
887953
@@ -7000,7 +7000,9 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
887953
         ssize_t                 bytes_read      = 0;
887953
         int32_t                 weak_checksum   = 0;
887953
         int32_t                 zerofillcheck   = 0;
887953
+        unsigned char           md5_checksum[MD5_DIGEST_LENGTH] = {0};
887953
         unsigned char           strong_checksum[SHA256_DIGEST_LENGTH] = {0};
887953
+        unsigned char           *checksum = NULL;
887953
         struct posix_private    *priv           = NULL;
887953
         dict_t                  *rsp_xdata      = NULL;
887953
         gf_boolean_t            buf_has_zeroes  = _gf_false;
887953
@@ -7069,13 +7071,31 @@ posix_rchecksum (call_frame_t *frame, xlator_t *this,
887953
                 }
887953
         }
887953
         weak_checksum = gf_rsync_weak_checksum ((unsigned char *) buf, (size_t) ret);
887953
-        gf_rsync_strong_checksum ((unsigned char *) buf, (size_t) bytes_read,
887953
-                                  (unsigned char *) strong_checksum);
887953
 
887953
+        if (priv->fips_mode_rchecksum) {
887953
+                ret = dict_set_int32 (rsp_xdata, "fips-mode-rchecksum", 1);
887953
+                if (ret) {
887953
+                        gf_msg (this->name, GF_LOG_WARNING, -ret,
887953
+                                P_MSG_DICT_SET_FAILED, "%s: Failed to set "
887953
+                                "dictionary value for key: %s",
887953
+                                uuid_utoa (fd->inode->gfid),
887953
+                                "fips-mode-rchecksum");
887953
+                        goto out;
887953
+                }
887953
+                checksum = strong_checksum;
887953
+                gf_rsync_strong_checksum ((unsigned char *)buf,
887953
+                                          (size_t) bytes_read,
887953
+                                          (unsigned char *)checksum);
887953
+        } else {
887953
+                checksum = md5_checksum;
887953
+                gf_rsync_md5_checksum ((unsigned char *)buf,
887953
+                                       (size_t) bytes_read,
887953
+                                       (unsigned char *)checksum);
887953
+        }
887953
         op_ret = 0;
887953
 out:
887953
         STACK_UNWIND_STRICT (rchecksum, frame, op_ret, op_errno,
887953
-                             weak_checksum, strong_checksum, rsp_xdata);
887953
+                             weak_checksum, checksum, rsp_xdata);
887953
         if (rsp_xdata)
887953
                 dict_unref (rsp_xdata);
887953
         GF_FREE (alloc_buf);
887953
@@ -7295,6 +7315,9 @@ reconfigure (xlator_t *this, dict_t *options)
887953
         GF_OPTION_RECONF ("shared-brick-count", priv->shared_brick_count,
887953
                           options, int32, out);
887953
 
887953
+        GF_OPTION_RECONF ("fips-mode-rchecksum", priv->fips_mode_rchecksum,
887953
+                          options, bool, out);
887953
+
887953
 	ret = 0;
887953
 out:
887953
 	return ret;
887953
@@ -7953,6 +7976,9 @@ init (xlator_t *this)
887953
 
887953
         GF_OPTION_INIT ("batch-fsync-delay-usec", _private->batch_fsync_delay_usec,
887953
                         uint32, out);
887953
+
887953
+        GF_OPTION_INIT ("fips-mode-rchecksum", _private->fips_mode_rchecksum,
887953
+                        bool, out);
887953
 out:
887953
         return ret;
887953
 }
887953
@@ -8182,5 +8208,12 @@ struct volume_options options[] = {
887953
           " Useful for displaying the proper usable size through statvfs() "
887953
           "call (df command)",
887953
         },
887953
+        {
887953
+          .key = {"fips-mode-rchecksum"},
887953
+          .type = GF_OPTION_TYPE_BOOL,
887953
+          .default_value = "off",
887953
+          .description = "If enabled, posix_rchecksum uses the FIPS compliant"
887953
+                         "SHA256 checksum. MD5 otherwise."
887953
+        },
887953
         { .key  = {NULL} }
887953
 };
887953
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
887953
index eaf4d0d..bda4172 100644
887953
--- a/xlators/storage/posix/src/posix.h
887953
+++ b/xlators/storage/posix/src/posix.h
887953
@@ -227,6 +227,8 @@ struct posix_private {
887953
         /* Option to handle the cases of multiple bricks exported from
887953
            same backend. Very much usable in brick-splitting feature. */
887953
         int32_t shared_brick_count;
887953
+
887953
+        gf_boolean_t fips_mode_rchecksum;
887953
 };
887953
 
887953
 typedef struct {
887953
-- 
887953
1.8.3.1
887953