diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2018-07-27 13:25:32 -0400 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2018-08-02 15:33:25 -0400 |
commit | cc255c76c70f7a87d97939621eae04b600d9f4a1 (patch) | |
tree | b090dc5237386d76ac1b44e204922ddce79f3428 | |
parent | 6daca13d2e72bedaaacfc08f873114c9307d5aea (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.h | 7 | ||||
-rw-r--r-- | net/ceph/auth_x.c | 73 |
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 | |||
165 | DEFINE_CEPH_FEATURE(59, 1, FS_BTIME) | 165 | DEFINE_CEPH_FEATURE(59, 1, FS_BTIME) |
166 | DEFINE_CEPH_FEATURE(59, 1, FS_CHANGE_ATTR) // overlap | 166 | DEFINE_CEPH_FEATURE(59, 1, FS_CHANGE_ATTR) // overlap |
167 | DEFINE_CEPH_FEATURE(59, 1, MSG_ADDR2) // overlap | 167 | DEFINE_CEPH_FEATURE(59, 1, MSG_ADDR2) // overlap |
168 | DEFINE_CEPH_FEATURE(60, 1, BLKIN_TRACING) // *do not share this bit* | 168 | DEFINE_CEPH_FEATURE(60, 1, OSD_RECOVERY_DELETES) // *do not share this bit* |
169 | DEFINE_CEPH_FEATURE(61, 1, CEPHX_V2) // *do not share this bit* | ||
169 | 170 | ||
170 | DEFINE_CEPH_FEATURE(61, 1, RESERVED2) // unused, but slow down! | ||
171 | DEFINE_CEPH_FEATURE(62, 1, RESERVED) // do not use; used as a sentinal | 171 | DEFINE_CEPH_FEATURE(62, 1, RESERVED) // do not use; used as a sentinal |
172 | DEFINE_CEPH_FEATURE_DEPRECATED(63, 1, RESERVED_BROKEN, LUMINOUS) // client-facing | 172 | DEFINE_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 | ||