aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2018-07-27 13:25:32 -0400
committerIlya Dryomov <idryomov@gmail.com>2018-08-02 15:33:25 -0400
commitcc255c76c70f7a87d97939621eae04b600d9f4a1 (patch)
treeb090dc5237386d76ac1b44e204922ddce79f3428
parent6daca13d2e72bedaaacfc08f873114c9307d5aea (diff)
libceph: implement CEPHX_V2 calculation mode
Derive the signature from the entire buffer (both AES cipher blocks) instead of using just the first half of the first block, leaving out data_crc entirely. This addresses CVE-2018-1129. Link: http://tracker.ceph.com/issues/24837 Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Sage Weil <sage@redhat.com>
-rw-r--r--include/linux/ceph/ceph_features.h7
-rw-r--r--net/ceph/auth_x.c73
2 files changed, 60 insertions, 20 deletions
diff --git a/include/linux/ceph/ceph_features.h b/include/linux/ceph/ceph_features.h
index 3901927cf6a0..6b92b3395fa9 100644
--- a/include/linux/ceph/ceph_features.h
+++ b/include/linux/ceph/ceph_features.h
@@ -165,9 +165,9 @@ DEFINE_CEPH_FEATURE(58, 1, FS_FILE_LAYOUT_V2) // overlap
165DEFINE_CEPH_FEATURE(59, 1, FS_BTIME) 165DEFINE_CEPH_FEATURE(59, 1, FS_BTIME)
166DEFINE_CEPH_FEATURE(59, 1, FS_CHANGE_ATTR) // overlap 166DEFINE_CEPH_FEATURE(59, 1, FS_CHANGE_ATTR) // overlap
167DEFINE_CEPH_FEATURE(59, 1, MSG_ADDR2) // overlap 167DEFINE_CEPH_FEATURE(59, 1, MSG_ADDR2) // overlap
168DEFINE_CEPH_FEATURE(60, 1, BLKIN_TRACING) // *do not share this bit* 168DEFINE_CEPH_FEATURE(60, 1, OSD_RECOVERY_DELETES) // *do not share this bit*
169DEFINE_CEPH_FEATURE(61, 1, CEPHX_V2) // *do not share this bit*
169 170
170DEFINE_CEPH_FEATURE(61, 1, RESERVED2) // unused, but slow down!
171DEFINE_CEPH_FEATURE(62, 1, RESERVED) // do not use; used as a sentinal 171DEFINE_CEPH_FEATURE(62, 1, RESERVED) // do not use; used as a sentinal
172DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facing 172DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facing
173 173
@@ -210,7 +210,8 @@ DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facin
210 CEPH_FEATURE_SERVER_JEWEL | \ 210 CEPH_FEATURE_SERVER_JEWEL | \
211 CEPH_FEATURE_MON_STATEFUL_SUB | \ 211 CEPH_FEATURE_MON_STATEFUL_SUB | \
212 CEPH_FEATURE_CRUSH_TUNABLES5 | \ 212 CEPH_FEATURE_CRUSH_TUNABLES5 | \
213 CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING) 213 CEPH_FEATURE_NEW_OSDOPREPLY_ENCODING | \
214 CEPH_FEATURE_CEPHX_V2)
214 215
215#define CEPH_FEATURES_REQUIRED_DEFAULT \ 216#define CEPH_FEATURES_REQUIRED_DEFAULT \
216 (CEPH_FEATURE_NOSRCADDR | \ 217 (CEPH_FEATURE_NOSRCADDR | \
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 512eed4291fe..462786f571e7 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/ceph/decode.h> 10#include <linux/ceph/decode.h>
11#include <linux/ceph/auth.h> 11#include <linux/ceph/auth.h>
12#include <linux/ceph/ceph_features.h>
12#include <linux/ceph/libceph.h> 13#include <linux/ceph/libceph.h>
13#include <linux/ceph/messenger.h> 14#include <linux/ceph/messenger.h>
14 15
@@ -803,26 +804,64 @@ static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg,
803 __le64 *psig) 804 __le64 *psig)
804{ 805{
805 void *enc_buf = au->enc_buf; 806 void *enc_buf = au->enc_buf;
806 struct {
807 __le32 len;
808 __le32 header_crc;
809 __le32 front_crc;
810 __le32 middle_crc;
811 __le32 data_crc;
812 } __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
813 int ret; 807 int ret;
814 808
815 sigblock->len = cpu_to_le32(4*sizeof(u32)); 809 if (!CEPH_HAVE_FEATURE(msg->con->peer_features, CEPHX_V2)) {
816 sigblock->header_crc = msg->hdr.crc; 810 struct {
817 sigblock->front_crc = msg->footer.front_crc; 811 __le32 len;
818 sigblock->middle_crc = msg->footer.middle_crc; 812 __le32 header_crc;
819 sigblock->data_crc = msg->footer.data_crc; 813 __le32 front_crc;
820 ret = ceph_x_encrypt(&au->session_key, enc_buf, CEPHX_AU_ENC_BUF_LEN, 814 __le32 middle_crc;
821 sizeof(*sigblock)); 815 __le32 data_crc;
822 if (ret < 0) 816 } __packed *sigblock = enc_buf + ceph_x_encrypt_offset();
823 return ret; 817
818 sigblock->len = cpu_to_le32(4*sizeof(u32));
819 sigblock->header_crc = msg->hdr.crc;
820 sigblock->front_crc = msg->footer.front_crc;
821 sigblock->middle_crc = msg->footer.middle_crc;
822 sigblock->data_crc = msg->footer.data_crc;
823
824 ret = ceph_x_encrypt(&au->session_key, enc_buf,
825 CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock));
826 if (ret < 0)
827 return ret;
828
829 *psig = *(__le64 *)(enc_buf + sizeof(u32));
830 } else {
831 struct {
832 __le32 header_crc;
833 __le32 front_crc;
834 __le32 front_len;
835 __le32 middle_crc;
836 __le32 middle_len;
837 __le32 data_crc;
838 __le32 data_len;
839 __le32 seq_lower_word;
840 } __packed *sigblock = enc_buf;
841 struct {
842 __le64 a, b, c, d;
843 } __packed *penc = enc_buf;
844 int ciphertext_len;
845
846 sigblock->header_crc = msg->hdr.crc;
847 sigblock->front_crc = msg->footer.front_crc;
848 sigblock->front_len = msg->hdr.front_len;
849 sigblock->middle_crc = msg->footer.middle_crc;
850 sigblock->middle_len = msg->hdr.middle_len;
851 sigblock->data_crc = msg->footer.data_crc;
852 sigblock->data_len = msg->hdr.data_len;
853 sigblock->seq_lower_word = *(__le32 *)&msg->hdr.seq;
854
855 /* no leading len, no ceph_x_encrypt_header */
856 ret = ceph_crypt(&au->session_key, true, enc_buf,
857 CEPHX_AU_ENC_BUF_LEN, sizeof(*sigblock),
858 &ciphertext_len);
859 if (ret)
860 return ret;
861
862 *psig = penc->a ^ penc->b ^ penc->c ^ penc->d;
863 }
824 864
825 *psig = *(__le64 *)(enc_buf + sizeof(u32));
826 return 0; 865 return 0;
827} 866}
828 867