From: Greg Kroah-Hartman Date: Mon, 23 Jan 2017 15:35:01 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.45~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b4f8e296cdef44ca0a8dfdb8a9333211bbacf8e5;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: input-alps-fix-trackstick-support-for-ss5-hardware.patch libceph-ceph_x_encrypt_buflen-takes-in_len.patch libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch libceph-introduce-ceph_x_encrypt_offset.patch libceph-old_key-in-process_one_ticket-is-redundant.patch libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch libceph-tweak-calcu_signature-a-little.patch --- diff --git a/queue-4.9/input-alps-fix-trackstick-support-for-ss5-hardware.patch b/queue-4.9/input-alps-fix-trackstick-support-for-ss5-hardware.patch new file mode 100644 index 00000000000..8bf04ecdeb8 --- /dev/null +++ b/queue-4.9/input-alps-fix-trackstick-support-for-ss5-hardware.patch @@ -0,0 +1,70 @@ +From 864db9295b06837d11a260e5dacf99a3fdf6bce2 Mon Sep 17 00:00:00 2001 +From: Paul Donohue +Date: Mon, 28 Nov 2016 20:11:25 -0800 +Subject: Input: ALPS - fix TrackStick support for SS5 hardware +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Paul Donohue + +commit 864db9295b06837d11a260e5dacf99a3fdf6bce2 upstream. + +The current Alps SS5 (SS4 v2) code generates bogus TouchPad events when +TrackStick packets are processed. + +This causes the xorg synaptics driver to print +"unable to find touch point 0" and +"BUG: triggered 'if (priv->num_active_touches > priv->num_slots)'" +messages. It also causes unexpected TouchPad button release and re-click +event sequences if the TrackStick is moved while holding a TouchPad +button. + +This commit corrects the problem by adjusting alps_process_packet_ss4_v2() +so that it only sends TrackStick reports when processing TrackStick +packets. + +Reviewed-by: Pali Rohár +Signed-off-by: Paul Donohue +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/input/mouse/alps.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/drivers/input/mouse/alps.c ++++ b/drivers/input/mouse/alps.c +@@ -1346,6 +1346,18 @@ static void alps_process_packet_ss4_v2(s + + priv->multi_packet = 0; + ++ /* Report trackstick */ ++ if (alps_get_pkt_id_ss4_v2(packet) == SS4_PACKET_ID_STICK) { ++ if (priv->flags & ALPS_DUALPOINT) { ++ input_report_key(dev2, BTN_LEFT, f->ts_left); ++ input_report_key(dev2, BTN_RIGHT, f->ts_right); ++ input_report_key(dev2, BTN_MIDDLE, f->ts_middle); ++ input_sync(dev2); ++ } ++ return; ++ } ++ ++ /* Report touchpad */ + alps_report_mt_data(psmouse, (f->fingers <= 4) ? f->fingers : 4); + + input_mt_report_finger_count(dev, f->fingers); +@@ -1356,13 +1368,6 @@ static void alps_process_packet_ss4_v2(s + + input_report_abs(dev, ABS_PRESSURE, f->pressure); + input_sync(dev); +- +- if (priv->flags & ALPS_DUALPOINT) { +- input_report_key(dev2, BTN_LEFT, f->ts_left); +- input_report_key(dev2, BTN_RIGHT, f->ts_right); +- input_report_key(dev2, BTN_MIDDLE, f->ts_middle); +- input_sync(dev2); +- } + } + + static bool alps_is_valid_package_ss4_v2(struct psmouse *psmouse) diff --git a/queue-4.9/libceph-ceph_x_encrypt_buflen-takes-in_len.patch b/queue-4.9/libceph-ceph_x_encrypt_buflen-takes-in_len.patch new file mode 100644 index 00000000000..ed6157324d0 --- /dev/null +++ b/queue-4.9/libceph-ceph_x_encrypt_buflen-takes-in_len.patch @@ -0,0 +1,48 @@ +From 36721ece1e84a25130c4befb930509b3f96de020 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:06 +0100 +Subject: libceph: ceph_x_encrypt_buflen() takes in_len + +From: Ilya Dryomov + +commit 36721ece1e84a25130c4befb930509b3f96de020 upstream. + +Pass what's going to be encrypted - that's msg_b, not ticket_blob. +ceph_x_encrypt_buflen() returns the upper bound, so this doesn't change +the maxlen calculation, but makes it a bit clearer. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -308,8 +308,8 @@ static int ceph_x_build_authorizer(struc + if (ret) + goto out_au; + +- maxlen = sizeof(*msg_a) + sizeof(msg_b) + +- ceph_x_encrypt_buflen(ticket_blob_len); ++ maxlen = sizeof(*msg_a) + ticket_blob_len + ++ ceph_x_encrypt_buflen(sizeof(msg_b)); + dout(" need len %d\n", maxlen); + if (au->buf && au->buf->alloc_len < maxlen) { + ceph_buffer_put(au->buf); +@@ -350,11 +350,12 @@ static int ceph_x_build_authorizer(struc + p, end - p); + if (ret < 0) + goto out_au; ++ + p += ret; ++ WARN_ON(p > end); + au->buf->vec.iov_len = p - au->buf->vec.iov_base; + dout(" built authorizer nonce %llx len %d\n", au->nonce, + (int)au->buf->vec.iov_len); +- BUG_ON(au->buf->vec.iov_len > maxlen); + return 0; + + out_au: diff --git a/queue-4.9/libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch b/queue-4.9/libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch new file mode 100644 index 00000000000..63dc6dac385 --- /dev/null +++ b/queue-4.9/libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch @@ -0,0 +1,143 @@ +From a45f795c65b479b4ba107b6ccde29b896d51ee98 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:07 +0100 +Subject: libceph: introduce ceph_crypt() for in-place en/decryption + +From: Ilya Dryomov + +commit a45f795c65b479b4ba107b6ccde29b896d51ee98 upstream. + +Starting with 4.9, kernel stacks may be vmalloced and therefore not +guaranteed to be physically contiguous; the new CONFIG_VMAP_STACK +option is enabled by default on x86. This makes it invalid to use +on-stack buffers with the crypto scatterlist API, as sg_set_buf() +expects a logical address and won't work with vmalloced addresses. + +There isn't a different (e.g. kvec-based) crypto API we could switch +net/ceph/crypto.c to and the current scatterlist.h API isn't getting +updated to accommodate this use case. Allocating a new header and +padding for each operation is a non-starter, so do the en/decryption +in-place on a single pre-assembled (header + data + padding) heap +buffer. This is explicitly supported by the crypto API: + + "... the caller may provide the same scatter/gather list for the + plaintext and cipher text. After the completion of the cipher + operation, the plaintext data is replaced with the ciphertext data + in case of an encryption and vice versa for a decryption." + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/crypto.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + net/ceph/crypto.h | 2 + + 2 files changed, 89 insertions(+) + +--- a/net/ceph/crypto.c ++++ b/net/ceph/crypto.c +@@ -526,6 +526,93 @@ int ceph_encrypt2(struct ceph_crypto_key + } + } + ++static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, ++ void *buf, int buf_len, int in_len, int *pout_len) ++{ ++ struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher(); ++ SKCIPHER_REQUEST_ON_STACK(req, tfm); ++ struct sg_table sgt; ++ struct scatterlist prealloc_sg; ++ char iv[AES_BLOCK_SIZE]; ++ int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1)); ++ int crypt_len = encrypt ? in_len + pad_byte : in_len; ++ int ret; ++ ++ if (IS_ERR(tfm)) ++ return PTR_ERR(tfm); ++ ++ WARN_ON(crypt_len > buf_len); ++ if (encrypt) ++ memset(buf + in_len, pad_byte, pad_byte); ++ ret = setup_sgtable(&sgt, &prealloc_sg, buf, crypt_len); ++ if (ret) ++ goto out_tfm; ++ ++ crypto_skcipher_setkey((void *)tfm, key->key, key->len); ++ memcpy(iv, aes_iv, AES_BLOCK_SIZE); ++ ++ skcipher_request_set_tfm(req, tfm); ++ skcipher_request_set_callback(req, 0, NULL, NULL); ++ skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv); ++ ++ /* ++ print_hex_dump(KERN_ERR, "key: ", DUMP_PREFIX_NONE, 16, 1, ++ key->key, key->len, 1); ++ print_hex_dump(KERN_ERR, " in: ", DUMP_PREFIX_NONE, 16, 1, ++ buf, crypt_len, 1); ++ */ ++ if (encrypt) ++ ret = crypto_skcipher_encrypt(req); ++ else ++ ret = crypto_skcipher_decrypt(req); ++ skcipher_request_zero(req); ++ if (ret) { ++ pr_err("%s %scrypt failed: %d\n", __func__, ++ encrypt ? "en" : "de", ret); ++ goto out_sgt; ++ } ++ /* ++ print_hex_dump(KERN_ERR, "out: ", DUMP_PREFIX_NONE, 16, 1, ++ buf, crypt_len, 1); ++ */ ++ ++ if (encrypt) { ++ *pout_len = crypt_len; ++ } else { ++ pad_byte = *(char *)(buf + in_len - 1); ++ if (pad_byte > 0 && pad_byte <= AES_BLOCK_SIZE && ++ in_len >= pad_byte) { ++ *pout_len = in_len - pad_byte; ++ } else { ++ pr_err("%s got bad padding %d on in_len %d\n", ++ __func__, pad_byte, in_len); ++ ret = -EPERM; ++ goto out_sgt; ++ } ++ } ++ ++out_sgt: ++ teardown_sgtable(&sgt); ++out_tfm: ++ crypto_free_skcipher(tfm); ++ return ret; ++} ++ ++int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, ++ void *buf, int buf_len, int in_len, int *pout_len) ++{ ++ switch (key->type) { ++ case CEPH_CRYPTO_NONE: ++ *pout_len = in_len; ++ return 0; ++ case CEPH_CRYPTO_AES: ++ return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len, ++ pout_len); ++ default: ++ return -ENOTSUPP; ++ } ++} ++ + static int ceph_key_preparse(struct key_preparsed_payload *prep) + { + struct ceph_crypto_key *ckey; +--- a/net/ceph/crypto.h ++++ b/net/ceph/crypto.h +@@ -43,6 +43,8 @@ int ceph_encrypt2(struct ceph_crypto_key + void *dst, size_t *dst_len, + const void *src1, size_t src1_len, + const void *src2, size_t src2_len); ++int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, ++ void *buf, int buf_len, int in_len, int *pout_len); + int ceph_crypto_init(void); + void ceph_crypto_shutdown(void); + diff --git a/queue-4.9/libceph-introduce-ceph_x_encrypt_offset.patch b/queue-4.9/libceph-introduce-ceph_x_encrypt_offset.patch new file mode 100644 index 00000000000..47473c17642 --- /dev/null +++ b/queue-4.9/libceph-introduce-ceph_x_encrypt_offset.patch @@ -0,0 +1,36 @@ +From 55d9cc834f933698fc864f0d36f3cca533d30a8d Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:07 +0100 +Subject: libceph: introduce ceph_x_encrypt_offset() + +From: Ilya Dryomov + +commit 55d9cc834f933698fc864f0d36f3cca533d30a8d upstream. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -39,10 +39,14 @@ static int ceph_x_should_authenticate(st + return need != 0; + } + ++static int ceph_x_encrypt_offset(void) ++{ ++ return sizeof(u32) + sizeof(struct ceph_x_encrypt_header); ++} ++ + static int ceph_x_encrypt_buflen(int ilen) + { +- return sizeof(struct ceph_x_encrypt_header) + ilen + 16 + +- sizeof(u32); ++ return ceph_x_encrypt_offset() + ilen + 16; + } + + static int ceph_x_encrypt(struct ceph_crypto_key *secret, diff --git a/queue-4.9/libceph-old_key-in-process_one_ticket-is-redundant.patch b/queue-4.9/libceph-old_key-in-process_one_ticket-is-redundant.patch new file mode 100644 index 00000000000..9b3d7e9e4ff --- /dev/null +++ b/queue-4.9/libceph-old_key-in-process_one_ticket-is-redundant.patch @@ -0,0 +1,47 @@ +From 462e650451c577d15eeb4d883d70fa9e4e529fad Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:06 +0100 +Subject: libceph: old_key in process_one_ticket() is redundant + +From: Ilya Dryomov + +commit 462e650451c577d15eeb4d883d70fa9e4e529fad upstream. + +Since commit 0a990e709356 ("ceph: clean up service ticket decoding"), +th->session_key isn't assigned until everything is decoded. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -148,7 +148,6 @@ static int process_one_ticket(struct cep + int dlen; + char is_enc; + struct timespec validity; +- struct ceph_crypto_key old_key; + void *ticket_buf = NULL; + void *tp, *tpend; + void **ptp; +@@ -187,7 +186,6 @@ static int process_one_ticket(struct cep + if (tkt_struct_v != 1) + goto bad; + +- memcpy(&old_key, &th->session_key, sizeof(old_key)); + ret = ceph_crypto_key_decode(&new_session_key, &dp, dend); + if (ret) + goto out; +@@ -204,7 +202,7 @@ static int process_one_ticket(struct cep + if (is_enc) { + /* encrypted */ + dout(" encrypted ticket\n"); +- dlen = ceph_x_decrypt(&old_key, p, end, &ticket_buf, 0); ++ dlen = ceph_x_decrypt(&th->session_key, p, end, &ticket_buf, 0); + if (dlen < 0) { + ret = dlen; + goto out; diff --git a/queue-4.9/libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch b/queue-4.9/libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch new file mode 100644 index 00000000000..b702eb0fe40 --- /dev/null +++ b/queue-4.9/libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch @@ -0,0 +1,419 @@ +From 2b1e1a7cd0a615d57455567a549f9965023321b5 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:08 +0100 +Subject: libceph: remove now unused ceph_*{en,de}crypt*() functions + +From: Ilya Dryomov + +commit 2b1e1a7cd0a615d57455567a549f9965023321b5 upstream. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/crypto.c | 369 ------------------------------------------------------ + net/ceph/crypto.h | 14 -- + 2 files changed, 383 deletions(-) + +--- a/net/ceph/crypto.c ++++ b/net/ceph/crypto.c +@@ -157,375 +157,6 @@ static void teardown_sgtable(struct sg_t + sg_free_table(sgt); + } + +-static int ceph_aes_encrypt(const void *key, int key_len, +- void *dst, size_t *dst_len, +- const void *src, size_t src_len) +-{ +- struct scatterlist sg_in[2], prealloc_sg; +- struct sg_table sg_out; +- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher(); +- SKCIPHER_REQUEST_ON_STACK(req, tfm); +- int ret; +- char iv[AES_BLOCK_SIZE]; +- size_t zero_padding = (0x10 - (src_len & 0x0f)); +- char pad[16]; +- +- if (IS_ERR(tfm)) +- return PTR_ERR(tfm); +- +- memset(pad, zero_padding, zero_padding); +- +- *dst_len = src_len + zero_padding; +- +- sg_init_table(sg_in, 2); +- sg_set_buf(&sg_in[0], src, src_len); +- sg_set_buf(&sg_in[1], pad, zero_padding); +- ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); +- if (ret) +- goto out_tfm; +- +- crypto_skcipher_setkey((void *)tfm, key, key_len); +- memcpy(iv, aes_iv, AES_BLOCK_SIZE); +- +- skcipher_request_set_tfm(req, tfm); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, sg_in, sg_out.sgl, +- src_len + zero_padding, iv); +- +- /* +- print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, +- key, key_len, 1); +- print_hex_dump(KERN_ERR, "enc src: ", DUMP_PREFIX_NONE, 16, 1, +- src, src_len, 1); +- print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, +- pad, zero_padding, 1); +- */ +- ret = crypto_skcipher_encrypt(req); +- skcipher_request_zero(req); +- if (ret < 0) { +- pr_err("ceph_aes_crypt failed %d\n", ret); +- goto out_sg; +- } +- /* +- print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, +- dst, *dst_len, 1); +- */ +- +-out_sg: +- teardown_sgtable(&sg_out); +-out_tfm: +- crypto_free_skcipher(tfm); +- return ret; +-} +- +-static int ceph_aes_encrypt2(const void *key, int key_len, void *dst, +- size_t *dst_len, +- const void *src1, size_t src1_len, +- const void *src2, size_t src2_len) +-{ +- struct scatterlist sg_in[3], prealloc_sg; +- struct sg_table sg_out; +- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher(); +- SKCIPHER_REQUEST_ON_STACK(req, tfm); +- int ret; +- char iv[AES_BLOCK_SIZE]; +- size_t zero_padding = (0x10 - ((src1_len + src2_len) & 0x0f)); +- char pad[16]; +- +- if (IS_ERR(tfm)) +- return PTR_ERR(tfm); +- +- memset(pad, zero_padding, zero_padding); +- +- *dst_len = src1_len + src2_len + zero_padding; +- +- sg_init_table(sg_in, 3); +- sg_set_buf(&sg_in[0], src1, src1_len); +- sg_set_buf(&sg_in[1], src2, src2_len); +- sg_set_buf(&sg_in[2], pad, zero_padding); +- ret = setup_sgtable(&sg_out, &prealloc_sg, dst, *dst_len); +- if (ret) +- goto out_tfm; +- +- crypto_skcipher_setkey((void *)tfm, key, key_len); +- memcpy(iv, aes_iv, AES_BLOCK_SIZE); +- +- skcipher_request_set_tfm(req, tfm); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, sg_in, sg_out.sgl, +- src1_len + src2_len + zero_padding, iv); +- +- /* +- print_hex_dump(KERN_ERR, "enc key: ", DUMP_PREFIX_NONE, 16, 1, +- key, key_len, 1); +- print_hex_dump(KERN_ERR, "enc src1: ", DUMP_PREFIX_NONE, 16, 1, +- src1, src1_len, 1); +- print_hex_dump(KERN_ERR, "enc src2: ", DUMP_PREFIX_NONE, 16, 1, +- src2, src2_len, 1); +- print_hex_dump(KERN_ERR, "enc pad: ", DUMP_PREFIX_NONE, 16, 1, +- pad, zero_padding, 1); +- */ +- ret = crypto_skcipher_encrypt(req); +- skcipher_request_zero(req); +- if (ret < 0) { +- pr_err("ceph_aes_crypt2 failed %d\n", ret); +- goto out_sg; +- } +- /* +- print_hex_dump(KERN_ERR, "enc out: ", DUMP_PREFIX_NONE, 16, 1, +- dst, *dst_len, 1); +- */ +- +-out_sg: +- teardown_sgtable(&sg_out); +-out_tfm: +- crypto_free_skcipher(tfm); +- return ret; +-} +- +-static int ceph_aes_decrypt(const void *key, int key_len, +- void *dst, size_t *dst_len, +- const void *src, size_t src_len) +-{ +- struct sg_table sg_in; +- struct scatterlist sg_out[2], prealloc_sg; +- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher(); +- SKCIPHER_REQUEST_ON_STACK(req, tfm); +- char pad[16]; +- char iv[AES_BLOCK_SIZE]; +- int ret; +- int last_byte; +- +- if (IS_ERR(tfm)) +- return PTR_ERR(tfm); +- +- sg_init_table(sg_out, 2); +- sg_set_buf(&sg_out[0], dst, *dst_len); +- sg_set_buf(&sg_out[1], pad, sizeof(pad)); +- ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); +- if (ret) +- goto out_tfm; +- +- crypto_skcipher_setkey((void *)tfm, key, key_len); +- memcpy(iv, aes_iv, AES_BLOCK_SIZE); +- +- skcipher_request_set_tfm(req, tfm); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, sg_in.sgl, sg_out, +- src_len, iv); +- +- /* +- print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1, +- key, key_len, 1); +- print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, +- src, src_len, 1); +- */ +- ret = crypto_skcipher_decrypt(req); +- skcipher_request_zero(req); +- if (ret < 0) { +- pr_err("ceph_aes_decrypt failed %d\n", ret); +- goto out_sg; +- } +- +- if (src_len <= *dst_len) +- last_byte = ((char *)dst)[src_len - 1]; +- else +- last_byte = pad[src_len - *dst_len - 1]; +- if (last_byte <= 16 && src_len >= last_byte) { +- *dst_len = src_len - last_byte; +- } else { +- pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n", +- last_byte, (int)src_len); +- return -EPERM; /* bad padding */ +- } +- /* +- print_hex_dump(KERN_ERR, "dec out: ", DUMP_PREFIX_NONE, 16, 1, +- dst, *dst_len, 1); +- */ +- +-out_sg: +- teardown_sgtable(&sg_in); +-out_tfm: +- crypto_free_skcipher(tfm); +- return ret; +-} +- +-static int ceph_aes_decrypt2(const void *key, int key_len, +- void *dst1, size_t *dst1_len, +- void *dst2, size_t *dst2_len, +- const void *src, size_t src_len) +-{ +- struct sg_table sg_in; +- struct scatterlist sg_out[3], prealloc_sg; +- struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher(); +- SKCIPHER_REQUEST_ON_STACK(req, tfm); +- char pad[16]; +- char iv[AES_BLOCK_SIZE]; +- int ret; +- int last_byte; +- +- if (IS_ERR(tfm)) +- return PTR_ERR(tfm); +- +- sg_init_table(sg_out, 3); +- sg_set_buf(&sg_out[0], dst1, *dst1_len); +- sg_set_buf(&sg_out[1], dst2, *dst2_len); +- sg_set_buf(&sg_out[2], pad, sizeof(pad)); +- ret = setup_sgtable(&sg_in, &prealloc_sg, src, src_len); +- if (ret) +- goto out_tfm; +- +- crypto_skcipher_setkey((void *)tfm, key, key_len); +- memcpy(iv, aes_iv, AES_BLOCK_SIZE); +- +- skcipher_request_set_tfm(req, tfm); +- skcipher_request_set_callback(req, 0, NULL, NULL); +- skcipher_request_set_crypt(req, sg_in.sgl, sg_out, +- src_len, iv); +- +- /* +- print_hex_dump(KERN_ERR, "dec key: ", DUMP_PREFIX_NONE, 16, 1, +- key, key_len, 1); +- print_hex_dump(KERN_ERR, "dec in: ", DUMP_PREFIX_NONE, 16, 1, +- src, src_len, 1); +- */ +- ret = crypto_skcipher_decrypt(req); +- skcipher_request_zero(req); +- if (ret < 0) { +- pr_err("ceph_aes_decrypt failed %d\n", ret); +- goto out_sg; +- } +- +- if (src_len <= *dst1_len) +- last_byte = ((char *)dst1)[src_len - 1]; +- else if (src_len <= *dst1_len + *dst2_len) +- last_byte = ((char *)dst2)[src_len - *dst1_len - 1]; +- else +- last_byte = pad[src_len - *dst1_len - *dst2_len - 1]; +- if (last_byte <= 16 && src_len >= last_byte) { +- src_len -= last_byte; +- } else { +- pr_err("ceph_aes_decrypt got bad padding %d on src len %d\n", +- last_byte, (int)src_len); +- return -EPERM; /* bad padding */ +- } +- +- if (src_len < *dst1_len) { +- *dst1_len = src_len; +- *dst2_len = 0; +- } else { +- *dst2_len = src_len - *dst1_len; +- } +- /* +- print_hex_dump(KERN_ERR, "dec out1: ", DUMP_PREFIX_NONE, 16, 1, +- dst1, *dst1_len, 1); +- print_hex_dump(KERN_ERR, "dec out2: ", DUMP_PREFIX_NONE, 16, 1, +- dst2, *dst2_len, 1); +- */ +- +-out_sg: +- teardown_sgtable(&sg_in); +-out_tfm: +- crypto_free_skcipher(tfm); +- return ret; +-} +- +- +-int ceph_decrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, +- const void *src, size_t src_len) +-{ +- switch (secret->type) { +- case CEPH_CRYPTO_NONE: +- if (*dst_len < src_len) +- return -ERANGE; +- memcpy(dst, src, src_len); +- *dst_len = src_len; +- return 0; +- +- case CEPH_CRYPTO_AES: +- return ceph_aes_decrypt(secret->key, secret->len, dst, +- dst_len, src, src_len); +- +- default: +- return -EINVAL; +- } +-} +- +-int ceph_decrypt2(struct ceph_crypto_key *secret, +- void *dst1, size_t *dst1_len, +- void *dst2, size_t *dst2_len, +- const void *src, size_t src_len) +-{ +- size_t t; +- +- switch (secret->type) { +- case CEPH_CRYPTO_NONE: +- if (*dst1_len + *dst2_len < src_len) +- return -ERANGE; +- t = min(*dst1_len, src_len); +- memcpy(dst1, src, t); +- *dst1_len = t; +- src += t; +- src_len -= t; +- if (src_len) { +- t = min(*dst2_len, src_len); +- memcpy(dst2, src, t); +- *dst2_len = t; +- } +- return 0; +- +- case CEPH_CRYPTO_AES: +- return ceph_aes_decrypt2(secret->key, secret->len, +- dst1, dst1_len, dst2, dst2_len, +- src, src_len); +- +- default: +- return -EINVAL; +- } +-} +- +-int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, +- const void *src, size_t src_len) +-{ +- switch (secret->type) { +- case CEPH_CRYPTO_NONE: +- if (*dst_len < src_len) +- return -ERANGE; +- memcpy(dst, src, src_len); +- *dst_len = src_len; +- return 0; +- +- case CEPH_CRYPTO_AES: +- return ceph_aes_encrypt(secret->key, secret->len, dst, +- dst_len, src, src_len); +- +- default: +- return -EINVAL; +- } +-} +- +-int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len, +- const void *src1, size_t src1_len, +- const void *src2, size_t src2_len) +-{ +- switch (secret->type) { +- case CEPH_CRYPTO_NONE: +- if (*dst_len < src1_len + src2_len) +- return -ERANGE; +- memcpy(dst, src1, src1_len); +- memcpy(dst + src1_len, src2, src2_len); +- *dst_len = src1_len + src2_len; +- return 0; +- +- case CEPH_CRYPTO_AES: +- return ceph_aes_encrypt2(secret->key, secret->len, dst, dst_len, +- src1, src1_len, src2, src2_len); +- +- default: +- return -EINVAL; +- } +-} +- + static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt, + void *buf, int buf_len, int in_len, int *pout_len) + { +--- a/net/ceph/crypto.h ++++ b/net/ceph/crypto.h +@@ -29,20 +29,6 @@ int ceph_crypto_key_decode(struct ceph_c + int ceph_crypto_key_unarmor(struct ceph_crypto_key *key, const char *in); + + /* crypto.c */ +-int ceph_decrypt(struct ceph_crypto_key *secret, +- void *dst, size_t *dst_len, +- const void *src, size_t src_len); +-int ceph_encrypt(struct ceph_crypto_key *secret, +- void *dst, size_t *dst_len, +- const void *src, size_t src_len); +-int ceph_decrypt2(struct ceph_crypto_key *secret, +- void *dst1, size_t *dst1_len, +- void *dst2, size_t *dst2_len, +- const void *src, size_t src_len); +-int ceph_encrypt2(struct ceph_crypto_key *secret, +- void *dst, size_t *dst_len, +- const void *src1, size_t src1_len, +- const void *src2, size_t src2_len); + int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt, + void *buf, int buf_len, int in_len, int *pout_len); + int ceph_crypto_init(void); diff --git a/queue-4.9/libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch b/queue-4.9/libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch new file mode 100644 index 00000000000..758cf44c823 --- /dev/null +++ b/queue-4.9/libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch @@ -0,0 +1,68 @@ +From 7882a26d2e2e520099e2961d5e2e870f8e4172dc Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:07 +0100 +Subject: libceph: rename and align ceph_x_authorizer::reply_buf + +From: Ilya Dryomov + +commit 7882a26d2e2e520099e2961d5e2e870f8e4172dc upstream. + +It's going to be used as a temporary buffer for in-place en/decryption +with ceph_crypt() instead of on-stack buffers, so rename to enc_buf. +Ensure alignment to avoid GFP_ATOMIC allocations in the crypto stack. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 10 +++++----- + net/ceph/auth_x.h | 3 ++- + 2 files changed, 7 insertions(+), 6 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -603,8 +603,8 @@ static int ceph_x_create_authorizer( + auth->authorizer = (struct ceph_authorizer *) au; + auth->authorizer_buf = au->buf->vec.iov_base; + auth->authorizer_buf_len = au->buf->vec.iov_len; +- auth->authorizer_reply_buf = au->reply_buf; +- auth->authorizer_reply_buf_len = sizeof (au->reply_buf); ++ auth->authorizer_reply_buf = au->enc_buf; ++ auth->authorizer_reply_buf_len = CEPHX_AU_ENC_BUF_LEN; + auth->sign_message = ac->ops->sign_message; + auth->check_message_signature = ac->ops->check_message_signature; + +@@ -638,10 +638,10 @@ static int ceph_x_verify_authorizer_repl + int ret = 0; + struct ceph_x_authorize_reply reply; + void *preply = &reply; +- void *p = au->reply_buf; +- void *end = p + sizeof(au->reply_buf); ++ void *p = au->enc_buf; + +- ret = ceph_x_decrypt(&au->session_key, &p, end, &preply, sizeof(reply)); ++ ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN, ++ &preply, sizeof(reply)); + if (ret < 0) + return ret; + if (ret != sizeof(reply)) +--- a/net/ceph/auth_x.h ++++ b/net/ceph/auth_x.h +@@ -24,6 +24,7 @@ struct ceph_x_ticket_handler { + unsigned long renew_after, expires; + }; + ++#define CEPHX_AU_ENC_BUF_LEN 128 /* big enough for encrypted blob */ + + struct ceph_x_authorizer { + struct ceph_authorizer base; +@@ -32,7 +33,7 @@ struct ceph_x_authorizer { + unsigned int service; + u64 nonce; + u64 secret_id; +- char reply_buf[128]; /* big enough for encrypted blob */ ++ char enc_buf[CEPHX_AU_ENC_BUF_LEN] __aligned(8); + }; + + struct ceph_x_info { diff --git a/queue-4.9/libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch b/queue-4.9/libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch new file mode 100644 index 00000000000..a3e1f3bddcd --- /dev/null +++ b/queue-4.9/libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch @@ -0,0 +1,162 @@ +From e15fd0a11db00fc7f470a9fc804657ec3f6d04a5 Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:08 +0100 +Subject: libceph: switch ceph_x_decrypt() to ceph_crypt() + +From: Ilya Dryomov + +commit e15fd0a11db00fc7f470a9fc804657ec3f6d04a5 upstream. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 78 ++++++++++++++++++++++-------------------------------- + 1 file changed, 32 insertions(+), 46 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -69,32 +69,28 @@ static int ceph_x_encrypt(struct ceph_cr + return sizeof(u32) + ciphertext_len; + } + +-static int ceph_x_decrypt(struct ceph_crypto_key *secret, +- void **p, void *end, void **obuf, size_t olen) ++static int ceph_x_decrypt(struct ceph_crypto_key *secret, void **p, void *end) + { +- struct ceph_x_encrypt_header head; +- size_t head_len = sizeof(head); +- int len, ret; +- +- len = ceph_decode_32(p); +- if (*p + len > end) +- return -EINVAL; ++ struct ceph_x_encrypt_header *hdr = *p + sizeof(u32); ++ int ciphertext_len, plaintext_len; ++ int ret; + +- dout("ceph_x_decrypt len %d\n", len); +- if (*obuf == NULL) { +- *obuf = kmalloc(len, GFP_NOFS); +- if (!*obuf) +- return -ENOMEM; +- olen = len; +- } ++ ceph_decode_32_safe(p, end, ciphertext_len, e_inval); ++ ceph_decode_need(p, end, ciphertext_len, e_inval); + +- ret = ceph_decrypt2(secret, &head, &head_len, *obuf, &olen, *p, len); ++ ret = ceph_crypt(secret, false, *p, end - *p, ciphertext_len, ++ &plaintext_len); + if (ret) + return ret; +- if (head.struct_v != 1 || le64_to_cpu(head.magic) != CEPHX_ENC_MAGIC) ++ ++ if (hdr->struct_v != 1 || le64_to_cpu(hdr->magic) != CEPHX_ENC_MAGIC) + return -EPERM; +- *p += len; +- return olen; ++ ++ *p += ciphertext_len; ++ return plaintext_len - sizeof(struct ceph_x_encrypt_header); ++ ++e_inval: ++ return -EINVAL; + } + + /* +@@ -149,12 +145,10 @@ static int process_one_ticket(struct cep + int type; + u8 tkt_struct_v, blob_struct_v; + struct ceph_x_ticket_handler *th; +- void *dbuf = NULL; + void *dp, *dend; + int dlen; + char is_enc; + struct timespec validity; +- void *ticket_buf = NULL; + void *tp, *tpend; + void **ptp; + struct ceph_crypto_key new_session_key; +@@ -179,14 +173,12 @@ static int process_one_ticket(struct cep + } + + /* blob for me */ +- dlen = ceph_x_decrypt(secret, p, end, &dbuf, 0); +- if (dlen <= 0) { +- ret = dlen; ++ dp = *p + ceph_x_encrypt_offset(); ++ ret = ceph_x_decrypt(secret, p, end); ++ if (ret < 0) + goto out; +- } +- dout(" decrypted %d bytes\n", dlen); +- dp = dbuf; +- dend = dp + dlen; ++ dout(" decrypted %d bytes\n", ret); ++ dend = dp + ret; + + tkt_struct_v = ceph_decode_8(&dp); + if (tkt_struct_v != 1) +@@ -207,15 +199,13 @@ static int process_one_ticket(struct cep + ceph_decode_8_safe(p, end, is_enc, bad); + if (is_enc) { + /* encrypted */ +- dout(" encrypted ticket\n"); +- dlen = ceph_x_decrypt(&th->session_key, p, end, &ticket_buf, 0); +- if (dlen < 0) { +- ret = dlen; ++ tp = *p + ceph_x_encrypt_offset(); ++ ret = ceph_x_decrypt(&th->session_key, p, end); ++ if (ret < 0) + goto out; +- } +- tp = ticket_buf; ++ dout(" encrypted ticket, decrypted %d bytes\n", ret); + ptp = &tp; +- tpend = *ptp + dlen; ++ tpend = tp + ret; + } else { + /* unencrypted */ + ptp = p; +@@ -246,8 +236,6 @@ static int process_one_ticket(struct cep + xi->have_keys |= th->service; + + out: +- kfree(ticket_buf); +- kfree(dbuf); + return ret; + + bad: +@@ -638,24 +626,22 @@ static int ceph_x_verify_authorizer_repl + struct ceph_authorizer *a, size_t len) + { + struct ceph_x_authorizer *au = (void *)a; +- int ret = 0; +- struct ceph_x_authorize_reply reply; +- void *preply = &reply; + void *p = au->enc_buf; ++ struct ceph_x_authorize_reply *reply = p + ceph_x_encrypt_offset(); ++ int ret; + +- ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN, +- &preply, sizeof(reply)); ++ ret = ceph_x_decrypt(&au->session_key, &p, p + CEPHX_AU_ENC_BUF_LEN); + if (ret < 0) + return ret; +- if (ret != sizeof(reply)) ++ if (ret != sizeof(*reply)) + return -EPERM; + +- if (au->nonce + 1 != le64_to_cpu(reply.nonce_plus_one)) ++ if (au->nonce + 1 != le64_to_cpu(reply->nonce_plus_one)) + ret = -EPERM; + else + ret = 0; + dout("verify_authorizer_reply nonce %llx got %llx ret %d\n", +- au->nonce, le64_to_cpu(reply.nonce_plus_one), ret); ++ au->nonce, le64_to_cpu(reply->nonce_plus_one), ret); + return ret; + } + diff --git a/queue-4.9/libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch b/queue-4.9/libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch new file mode 100644 index 00000000000..bd715104ef7 --- /dev/null +++ b/queue-4.9/libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch @@ -0,0 +1,161 @@ +From d03857c63bb036edff0aa7a107276360173aca4e Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:07 +0100 +Subject: libceph: switch ceph_x_encrypt() to ceph_crypt() + +From: Ilya Dryomov + +commit d03857c63bb036edff0aa7a107276360173aca4e upstream. + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 71 ++++++++++++++++++++++++++++-------------------------- + 1 file changed, 37 insertions(+), 34 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -49,22 +49,24 @@ static int ceph_x_encrypt_buflen(int ile + return ceph_x_encrypt_offset() + ilen + 16; + } + +-static int ceph_x_encrypt(struct ceph_crypto_key *secret, +- void *ibuf, int ilen, void *obuf, size_t olen) ++static int ceph_x_encrypt(struct ceph_crypto_key *secret, void *buf, ++ int buf_len, int plaintext_len) + { +- struct ceph_x_encrypt_header head = { +- .struct_v = 1, +- .magic = cpu_to_le64(CEPHX_ENC_MAGIC) +- }; +- size_t len = olen - sizeof(u32); ++ struct ceph_x_encrypt_header *hdr = buf + sizeof(u32); ++ int ciphertext_len; + int ret; + +- ret = ceph_encrypt2(secret, obuf + sizeof(u32), &len, +- &head, sizeof(head), ibuf, ilen); ++ hdr->struct_v = 1; ++ hdr->magic = cpu_to_le64(CEPHX_ENC_MAGIC); ++ ++ ret = ceph_crypt(secret, true, buf + sizeof(u32), buf_len - sizeof(u32), ++ plaintext_len + sizeof(struct ceph_x_encrypt_header), ++ &ciphertext_len); + if (ret) + return ret; +- ceph_encode_32(&obuf, len); +- return len + sizeof(u32); ++ ++ ceph_encode_32(&buf, ciphertext_len); ++ return sizeof(u32) + ciphertext_len; + } + + static int ceph_x_decrypt(struct ceph_crypto_key *secret, +@@ -296,7 +298,7 @@ static int ceph_x_build_authorizer(struc + { + int maxlen; + struct ceph_x_authorize_a *msg_a; +- struct ceph_x_authorize_b msg_b; ++ struct ceph_x_authorize_b *msg_b; + void *p, *end; + int ret; + int ticket_blob_len = +@@ -311,7 +313,7 @@ static int ceph_x_build_authorizer(struc + goto out_au; + + maxlen = sizeof(*msg_a) + ticket_blob_len + +- ceph_x_encrypt_buflen(sizeof(msg_b)); ++ ceph_x_encrypt_buflen(sizeof(*msg_b)); + dout(" need len %d\n", maxlen); + if (au->buf && au->buf->alloc_len < maxlen) { + ceph_buffer_put(au->buf); +@@ -345,11 +347,11 @@ static int ceph_x_build_authorizer(struc + p += ticket_blob_len; + end = au->buf->vec.iov_base + au->buf->vec.iov_len; + ++ msg_b = p + ceph_x_encrypt_offset(); ++ msg_b->struct_v = 1; + get_random_bytes(&au->nonce, sizeof(au->nonce)); +- msg_b.struct_v = 1; +- msg_b.nonce = cpu_to_le64(au->nonce); +- ret = ceph_x_encrypt(&au->session_key, &msg_b, sizeof(msg_b), +- p, end - p); ++ msg_b->nonce = cpu_to_le64(au->nonce); ++ ret = ceph_x_encrypt(&au->session_key, p, end - p, sizeof(*msg_b)); + if (ret < 0) + goto out_au; + +@@ -455,8 +457,9 @@ static int ceph_x_build_request(struct c + if (need & CEPH_ENTITY_TYPE_AUTH) { + struct ceph_x_authenticate *auth = (void *)(head + 1); + void *p = auth + 1; +- struct ceph_x_challenge_blob tmp; +- char tmp_enc[40]; ++ void *enc_buf = xi->auth_authorizer.enc_buf; ++ struct ceph_x_challenge_blob *blob = enc_buf + ++ ceph_x_encrypt_offset(); + u64 *u; + + if (p > end) +@@ -467,16 +470,16 @@ static int ceph_x_build_request(struct c + + /* encrypt and hash */ + get_random_bytes(&auth->client_challenge, sizeof(u64)); +- tmp.client_challenge = auth->client_challenge; +- tmp.server_challenge = cpu_to_le64(xi->server_challenge); +- ret = ceph_x_encrypt(&xi->secret, &tmp, sizeof(tmp), +- tmp_enc, sizeof(tmp_enc)); ++ blob->client_challenge = auth->client_challenge; ++ blob->server_challenge = cpu_to_le64(xi->server_challenge); ++ ret = ceph_x_encrypt(&xi->secret, enc_buf, CEPHX_AU_ENC_BUF_LEN, ++ sizeof(*blob)); + if (ret < 0) + return ret; + + auth->struct_v = 1; + auth->key = 0; +- for (u = (u64 *)tmp_enc; u + 1 <= (u64 *)(tmp_enc + ret); u++) ++ for (u = (u64 *)enc_buf; u + 1 <= (u64 *)(enc_buf + ret); u++) + auth->key ^= *(__le64 *)u; + dout(" server_challenge %llx client_challenge %llx key %llx\n", + xi->server_challenge, le64_to_cpu(auth->client_challenge), +@@ -710,27 +713,27 @@ static void ceph_x_invalidate_authorizer + static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, + __le64 *psig) + { +- char tmp_enc[40]; ++ void *enc_buf = au->enc_buf; + struct { + __le32 len; + __le32 header_crc; + __le32 front_crc; + __le32 middle_crc; + __le32 data_crc; +- } __packed sigblock; ++ } __packed *sigblock = enc_buf + ceph_x_encrypt_offset(); + int ret; + +- sigblock.len = cpu_to_le32(4*sizeof(u32)); +- sigblock.header_crc = msg->hdr.crc; +- sigblock.front_crc = msg->footer.front_crc; +- sigblock.middle_crc = msg->footer.middle_crc; +- sigblock.data_crc = msg->footer.data_crc; +- ret = ceph_x_encrypt(&au->session_key, &sigblock, sizeof(sigblock), +- tmp_enc, sizeof(tmp_enc)); ++ sigblock->len = cpu_to_le32(4*sizeof(u32)); ++ sigblock->header_crc = msg->hdr.crc; ++ sigblock->front_crc = msg->footer.front_crc; ++ sigblock->middle_crc = msg->footer.middle_crc; ++ sigblock->data_crc = msg->footer.data_crc; ++ ret = ceph_x_encrypt(&au->session_key, enc_buf, CEPHX_AU_ENC_BUF_LEN, ++ sizeof(*sigblock)); + if (ret < 0) + return ret; + +- *psig = *(__le64 *)(tmp_enc + sizeof(u32)); ++ *psig = *(__le64 *)(enc_buf + sizeof(u32)); + return 0; + } + diff --git a/queue-4.9/libceph-tweak-calcu_signature-a-little.patch b/queue-4.9/libceph-tweak-calcu_signature-a-little.patch new file mode 100644 index 00000000000..1215c55b417 --- /dev/null +++ b/queue-4.9/libceph-tweak-calcu_signature-a-little.patch @@ -0,0 +1,96 @@ +From 4eb4517ce7c9c573b6c823de403aeccb40018cfc Mon Sep 17 00:00:00 2001 +From: Ilya Dryomov +Date: Fri, 2 Dec 2016 16:35:07 +0100 +Subject: libceph: tweak calcu_signature() a little + +From: Ilya Dryomov + +commit 4eb4517ce7c9c573b6c823de403aeccb40018cfc upstream. + +- replace an ad-hoc array with a struct +- rename to calc_signature() for consistency + +Signed-off-by: Ilya Dryomov +Reviewed-by: Sage Weil +Signed-off-by: Greg Kroah-Hartman + +--- + net/ceph/auth_x.c | 43 ++++++++++++++++++++++++++++--------------- + 1 file changed, 28 insertions(+), 15 deletions(-) + +--- a/net/ceph/auth_x.c ++++ b/net/ceph/auth_x.c +@@ -707,35 +707,48 @@ static void ceph_x_invalidate_authorizer + invalidate_ticket(ac, CEPH_ENTITY_TYPE_AUTH); + } + +-static int calcu_signature(struct ceph_x_authorizer *au, +- struct ceph_msg *msg, __le64 *sig) ++static int calc_signature(struct ceph_x_authorizer *au, struct ceph_msg *msg, ++ __le64 *psig) + { +- int ret; + char tmp_enc[40]; +- __le32 tmp[5] = { +- cpu_to_le32(16), msg->hdr.crc, msg->footer.front_crc, +- msg->footer.middle_crc, msg->footer.data_crc, +- }; +- ret = ceph_x_encrypt(&au->session_key, &tmp, sizeof(tmp), ++ struct { ++ __le32 len; ++ __le32 header_crc; ++ __le32 front_crc; ++ __le32 middle_crc; ++ __le32 data_crc; ++ } __packed sigblock; ++ int ret; ++ ++ sigblock.len = cpu_to_le32(4*sizeof(u32)); ++ sigblock.header_crc = msg->hdr.crc; ++ sigblock.front_crc = msg->footer.front_crc; ++ sigblock.middle_crc = msg->footer.middle_crc; ++ sigblock.data_crc = msg->footer.data_crc; ++ ret = ceph_x_encrypt(&au->session_key, &sigblock, sizeof(sigblock), + tmp_enc, sizeof(tmp_enc)); + if (ret < 0) + return ret; +- *sig = *(__le64*)(tmp_enc + 4); ++ ++ *psig = *(__le64 *)(tmp_enc + sizeof(u32)); + return 0; + } + + static int ceph_x_sign_message(struct ceph_auth_handshake *auth, + struct ceph_msg *msg) + { ++ __le64 sig; + int ret; + + if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN)) + return 0; + +- ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer, +- msg, &msg->footer.sig); +- if (ret < 0) ++ ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer, ++ msg, &sig); ++ if (ret) + return ret; ++ ++ msg->footer.sig = sig; + msg->footer.flags |= CEPH_MSG_FOOTER_SIGNED; + return 0; + } +@@ -749,9 +762,9 @@ static int ceph_x_check_message_signatur + if (ceph_test_opt(from_msgr(msg->con->msgr), NOMSGSIGN)) + return 0; + +- ret = calcu_signature((struct ceph_x_authorizer *)auth->authorizer, +- msg, &sig_check); +- if (ret < 0) ++ ret = calc_signature((struct ceph_x_authorizer *)auth->authorizer, ++ msg, &sig_check); ++ if (ret) + return ret; + if (sig_check == msg->footer.sig) + return 0; diff --git a/queue-4.9/series b/queue-4.9/series index 78983c6ad00..0d7c60ab699 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -72,3 +72,13 @@ arm64-ptrace-preserve-previous-registers-for-short-regset-write-2.patch arm64-ptrace-preserve-previous-registers-for-short-regset-write-3.patch arm64-ptrace-avoid-uninitialised-struct-padding-in-fpr_set.patch arm64-ptrace-reject-attempts-to-set-incomplete-hardware-breakpoint-fields.patch +input-alps-fix-trackstick-support-for-ss5-hardware.patch +libceph-ceph_x_encrypt_buflen-takes-in_len.patch +libceph-old_key-in-process_one_ticket-is-redundant.patch +libceph-introduce-ceph_x_encrypt_offset.patch +libceph-introduce-ceph_crypt-for-in-place-en-decryption.patch +libceph-rename-and-align-ceph_x_authorizer-reply_buf.patch +libceph-tweak-calcu_signature-a-little.patch +libceph-switch-ceph_x_encrypt-to-ceph_crypt.patch +libceph-switch-ceph_x_decrypt-to-ceph_crypt.patch +libceph-remove-now-unused-ceph_-en-de-crypt-functions.patch