From: Greg Kroah-Hartman Date: Sun, 29 May 2016 21:52:10 +0000 (-0700) Subject: 4.5-stable patches X-Git-Tag: v3.14.71~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0178c9a3a18611999b95a816e84dff666e2c7ddb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.5-stable patches added patches: asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch cifs-create-dedicated-keyring-for-spnego-operations.patch clk-qcom-msm8916-fix-crypto-clock-flags.patch crypto-caam-fix-caam_jr_alloc-ret-code.patch crypto-sun4i-ss-replace-spinlock_bh-by-spin_lock_irq-save-restore.patch crypto-talitos-fix-ahash-algorithms-registration.patch fs-cifs-correctly-to-anonymous-authentication-for-the-lanman-authentication.patch fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v1-authentication.patch fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v2-authentication.patch fs-cifs-correctly-to-anonymous-authentication-via-ntlmssp.patch remove-directory-incorrectly-tries-to-set-delete-on-close-on-non-empty-directories.patch ring-buffer-prevent-overflow-of-size-in-ring_buffer_resize.patch ring-buffer-use-long-for-nr_pages-to-avoid-overflow-failures.patch --- diff --git a/queue-4.5/asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch b/queue-4.5/asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch new file mode 100644 index 00000000000..ed40d274c53 --- /dev/null +++ b/queue-4.5/asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch @@ -0,0 +1,85 @@ +From cd9e2e5d3ff148be9ea210f622ce3e8e8292fcd6 Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Mon, 16 May 2016 20:36:15 -0700 +Subject: asix: Fix offset calculation in asix_rx_fixup() causing slow transmissions + +From: John Stultz + +commit cd9e2e5d3ff148be9ea210f622ce3e8e8292fcd6 upstream. + +In testing with HiKey, we found that since +commit 3f30b158eba5 ("asix: On RX avoid creating bad Ethernet +frames"), +we're seeing lots of noise during network transfers: + +[ 239.027993] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 +[ 239.037310] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x54ebb5ec, offset 4 +[ 239.045519] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0xcdffe7a2, offset 4 +[ 239.275044] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 +[ 239.284355] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x1d36f59d, offset 4 +[ 239.292541] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0xaef3c1e9, offset 4 +[ 239.518996] asix 1-1.1:1.0 eth0: asix_rx_fixup() Data Header synchronisation was lost, remaining 988 +[ 239.528300] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x2881912, offset 4 +[ 239.536413] asix 1-1.1:1.0 eth0: asix_rx_fixup() Bad Header Length 0x5638f7e2, offset 4 + +And network throughput ends up being pretty bursty and slow with +a overall throughput of at best ~30kB/s (where as previously we +got 1.1MB/s with the slower USB1.1 "full speed" host). + +We found the issue also was reproducible on a x86_64 system, +using a "high-speed" USB2.0 port but the throughput did not +measurably drop (possibly due to the scp transfer being cpu +bound on my slow test hardware). + +After lots of debugging, I found the check added in the +problematic commit seems to be calculating the offset +incorrectly. + +In the normal case, in the main loop of the function, we do: +(where offset is zero, or set to "offset += (copy_length + 1) & +0xfffe" in the previous loop) + rx->header = get_unaligned_le32(skb->data + + offset); + offset += sizeof(u32); + +But the problematic patch calculates: + offset = ((rx->remaining + 1) & 0xfffe) + sizeof(u32); + rx->header = get_unaligned_le32(skb->data + offset); + +Adding some debug logic to check those offset calculation used +to find rx->header, the one in problematic code is always too +large by sizeof(u32). + +Thus, this patch removes the incorrect " + sizeof(u32)" addition +in the problematic calculation, and resolves the issue. + +Cc: Dean Jenkins +Cc: "David B. Robins" +Cc: Mark Craske +Cc: Emil Goode +Cc: "David S. Miller" +Cc: YongQin Liu +Cc: Guodong Xu +Cc: Ivan Vecera +Cc: linux-usb@vger.kernel.org +Cc: netdev@vger.kernel.org +Reported-by: Yongqin Liu +Signed-off-by: John Stultz +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/usb/asix_common.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/asix_common.c ++++ b/drivers/net/usb/asix_common.c +@@ -66,7 +66,7 @@ int asix_rx_fixup_internal(struct usbnet + * buffer. + */ + if (rx->remaining && (rx->remaining + sizeof(u32) <= skb->len)) { +- offset = ((rx->remaining + 1) & 0xfffe) + sizeof(u32); ++ offset = ((rx->remaining + 1) & 0xfffe); + rx->header = get_unaligned_le32(skb->data + offset); + offset = 0; + diff --git a/queue-4.5/cifs-create-dedicated-keyring-for-spnego-operations.patch b/queue-4.5/cifs-create-dedicated-keyring-for-spnego-operations.patch new file mode 100644 index 00000000000..373b58f9183 --- /dev/null +++ b/queue-4.5/cifs-create-dedicated-keyring-for-spnego-operations.patch @@ -0,0 +1,167 @@ +From b74cb9a80268be5c80cf4c87c74debf0ff2129ac Mon Sep 17 00:00:00 2001 +From: Sachin Prabhu +Date: Tue, 17 May 2016 18:20:13 -0500 +Subject: cifs: Create dedicated keyring for spnego operations + +From: Sachin Prabhu + +commit b74cb9a80268be5c80cf4c87c74debf0ff2129ac upstream. + +The session key is the default keyring set for request_key operations. +This session key is revoked when the user owning the session logs out. +Any long running daemon processes started by this session ends up with +revoked session keyring which prevents these processes from using the +request_key mechanism from obtaining the krb5 keys. + +The problem has been reported by a large number of autofs users. The +problem is also seen with multiuser mounts where the share may be used +by processes run by a user who has since logged out. A reproducer using +automount is available on the Red Hat bz. + +The patch creates a new keyring which is used to cache cifs spnego +upcalls. + +Red Hat bz: 1267754 + +Signed-off-by: Sachin Prabhu +Reported-by: Scott Mayhew +Reviewed-by: Shirish Pargaonkar +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/cifs_spnego.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++ + fs/cifs/cifsfs.c | 4 +- + fs/cifs/cifsproto.h | 2 + + 3 files changed, 71 insertions(+), 2 deletions(-) + +--- a/fs/cifs/cifs_spnego.c ++++ b/fs/cifs/cifs_spnego.c +@@ -24,10 +24,13 @@ + #include + #include + #include ++#include + #include + #include "cifsglob.h" + #include "cifs_spnego.h" + #include "cifs_debug.h" ++#include "cifsproto.h" ++static const struct cred *spnego_cred; + + /* create a new cifs key */ + static int +@@ -102,6 +105,7 @@ cifs_get_spnego_key(struct cifs_ses *ses + size_t desc_len; + struct key *spnego_key; + const char *hostname = server->hostname; ++ const struct cred *saved_cred; + + /* length of fields (with semicolons): ver=0xyz ip4=ipaddress + host=hostname sec=mechanism uid=0xFF user=username */ +@@ -163,7 +167,9 @@ cifs_get_spnego_key(struct cifs_ses *ses + sprintf(dp, ";pid=0x%x", current->pid); + + cifs_dbg(FYI, "key description = %s\n", description); ++ saved_cred = override_creds(spnego_cred); + spnego_key = request_key(&cifs_spnego_key_type, description, ""); ++ revert_creds(saved_cred); + + #ifdef CONFIG_CIFS_DEBUG2 + if (cifsFYI && !IS_ERR(spnego_key)) { +@@ -177,3 +183,64 @@ out: + kfree(description); + return spnego_key; + } ++ ++int ++init_cifs_spnego(void) ++{ ++ struct cred *cred; ++ struct key *keyring; ++ int ret; ++ ++ cifs_dbg(FYI, "Registering the %s key type\n", ++ cifs_spnego_key_type.name); ++ ++ /* ++ * Create an override credential set with special thread keyring for ++ * spnego upcalls. ++ */ ++ ++ cred = prepare_kernel_cred(NULL); ++ if (!cred) ++ return -ENOMEM; ++ ++ keyring = keyring_alloc(".cifs_spnego", ++ GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, cred, ++ (KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW | KEY_USR_READ, ++ KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); ++ if (IS_ERR(keyring)) { ++ ret = PTR_ERR(keyring); ++ goto failed_put_cred; ++ } ++ ++ ret = register_key_type(&cifs_spnego_key_type); ++ if (ret < 0) ++ goto failed_put_key; ++ ++ /* ++ * instruct request_key() to use this special keyring as a cache for ++ * the results it looks up ++ */ ++ set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); ++ cred->thread_keyring = keyring; ++ cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; ++ spnego_cred = cred; ++ ++ cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring)); ++ return 0; ++ ++failed_put_key: ++ key_put(keyring); ++failed_put_cred: ++ put_cred(cred); ++ return ret; ++} ++ ++void ++exit_cifs_spnego(void) ++{ ++ key_revoke(spnego_cred->thread_keyring); ++ unregister_key_type(&cifs_spnego_key_type); ++ put_cred(spnego_cred); ++ cifs_dbg(FYI, "Unregistered %s key type\n", cifs_spnego_key_type.name); ++} +--- a/fs/cifs/cifsfs.c ++++ b/fs/cifs/cifsfs.c +@@ -1309,7 +1309,7 @@ init_cifs(void) + goto out_destroy_mids; + + #ifdef CONFIG_CIFS_UPCALL +- rc = register_key_type(&cifs_spnego_key_type); ++ rc = init_cifs_spnego(); + if (rc) + goto out_destroy_request_bufs; + #endif /* CONFIG_CIFS_UPCALL */ +@@ -1332,7 +1332,7 @@ out_init_cifs_idmap: + out_register_key_type: + #endif + #ifdef CONFIG_CIFS_UPCALL +- unregister_key_type(&cifs_spnego_key_type); ++ exit_cifs_spnego(); + out_destroy_request_bufs: + #endif + cifs_destroy_request_bufs(); +--- a/fs/cifs/cifsproto.h ++++ b/fs/cifs/cifsproto.h +@@ -60,6 +60,8 @@ do { \ + } while (0) + extern int init_cifs_idmap(void); + extern void exit_cifs_idmap(void); ++extern int init_cifs_spnego(void); ++extern void exit_cifs_spnego(void); + extern char *build_path_from_dentry(struct dentry *); + extern char *cifs_build_path_to_root(struct smb_vol *vol, + struct cifs_sb_info *cifs_sb, diff --git a/queue-4.5/clk-qcom-msm8916-fix-crypto-clock-flags.patch b/queue-4.5/clk-qcom-msm8916-fix-crypto-clock-flags.patch new file mode 100644 index 00000000000..5b5916d2e15 --- /dev/null +++ b/queue-4.5/clk-qcom-msm8916-fix-crypto-clock-flags.patch @@ -0,0 +1,40 @@ +From 2a0974aa1a0b40a92387ea03dbfeacfbc9ba182c Mon Sep 17 00:00:00 2001 +From: Andy Gross +Date: Tue, 3 May 2016 15:24:11 -0500 +Subject: clk: qcom: msm8916: Fix crypto clock flags + +From: Andy Gross + +commit 2a0974aa1a0b40a92387ea03dbfeacfbc9ba182c upstream. + +This patch adds the CLK_SET_RATE_PARENT flag for the crypto core and +ahb blocks. Without this flag, clk_set_rate can fail for certain +frequency requests. + +Signed-off-by: Andy Gross +Fixes: 3966fab8b6ab ("clk: qcom: Add MSM8916 Global Clock Controller support") +Signed-off-by: Stephen Boyd +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/qcom/gcc-msm8916.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/clk/qcom/gcc-msm8916.c ++++ b/drivers/clk/qcom/gcc-msm8916.c +@@ -2346,6 +2346,7 @@ static struct clk_branch gcc_crypto_ahb_ + "pcnoc_bfdcd_clk_src", + }, + .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, +@@ -2381,6 +2382,7 @@ static struct clk_branch gcc_crypto_clk + "crypto_clk_src", + }, + .num_parents = 1, ++ .flags = CLK_SET_RATE_PARENT, + .ops = &clk_branch2_ops, + }, + }, diff --git a/queue-4.5/crypto-caam-fix-caam_jr_alloc-ret-code.patch b/queue-4.5/crypto-caam-fix-caam_jr_alloc-ret-code.patch new file mode 100644 index 00000000000..35df6317118 --- /dev/null +++ b/queue-4.5/crypto-caam-fix-caam_jr_alloc-ret-code.patch @@ -0,0 +1,37 @@ +From e930c765ca5c6b039cd22ebfb4504ea7b5dab43d Mon Sep 17 00:00:00 2001 +From: Catalin Vasile +Date: Fri, 6 May 2016 16:18:53 +0300 +Subject: crypto: caam - fix caam_jr_alloc() ret code + +From: Catalin Vasile + +commit e930c765ca5c6b039cd22ebfb4504ea7b5dab43d upstream. + +caam_jr_alloc() used to return NULL if a JR device could not be +allocated for a session. In turn, every user of this function used +IS_ERR() function to verify if anything went wrong, which does NOT look +for NULL values. This made the kernel crash if the sanity check failed, +because the driver continued to think it had allocated a valid JR dev +instance to the session and at some point it tries to do a caam_jr_free() +on a NULL JR dev pointer. +This patch is a fix for this issue. + +Signed-off-by: Catalin Vasile +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/caam/jr.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/crypto/caam/jr.c ++++ b/drivers/crypto/caam/jr.c +@@ -248,7 +248,7 @@ static void caam_jr_dequeue(unsigned lon + struct device *caam_jr_alloc(void) + { + struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL; +- struct device *dev = NULL; ++ struct device *dev = ERR_PTR(-ENODEV); + int min_tfm_cnt = INT_MAX; + int tfm_cnt; + diff --git a/queue-4.5/crypto-sun4i-ss-replace-spinlock_bh-by-spin_lock_irq-save-restore.patch b/queue-4.5/crypto-sun4i-ss-replace-spinlock_bh-by-spin_lock_irq-save-restore.patch new file mode 100644 index 00000000000..2e6c2098a05 --- /dev/null +++ b/queue-4.5/crypto-sun4i-ss-replace-spinlock_bh-by-spin_lock_irq-save-restore.patch @@ -0,0 +1,77 @@ +From bdb6cf9f6fe6d9af905ea34b7c4bb78ea601329e Mon Sep 17 00:00:00 2001 +From: Corentin LABBE +Date: Wed, 23 Mar 2016 16:11:24 +0100 +Subject: crypto: sun4i-ss - Replace spinlock_bh by spin_lock_irq{save|restore} + +From: Corentin LABBE + +commit bdb6cf9f6fe6d9af905ea34b7c4bb78ea601329e upstream. + +The current sun4i-ss driver could generate data corruption when ciphering/deciphering. +It occurs randomly on end of handled data. +No root cause have been found and the only way to remove it is to replace +all spin_lock_bh by their irq counterparts. + +Fixes: 6298e948215f ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator") +Signed-off-by: LABBE Corentin +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c ++++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +@@ -35,6 +35,7 @@ static int sun4i_ss_opti_poll(struct abl + unsigned int todo; + struct sg_mapping_iter mi, mo; + unsigned int oi, oo; /* offset for in and out */ ++ unsigned long flags; + + if (areq->nbytes == 0) + return 0; +@@ -49,7 +50,7 @@ static int sun4i_ss_opti_poll(struct abl + return -EINVAL; + } + +- spin_lock_bh(&ss->slock); ++ spin_lock_irqsave(&ss->slock, flags); + + for (i = 0; i < op->keylen; i += 4) + writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); +@@ -117,7 +118,7 @@ release_ss: + sg_miter_stop(&mi); + sg_miter_stop(&mo); + writel(0, ss->base + SS_CTL); +- spin_unlock_bh(&ss->slock); ++ spin_unlock_irqrestore(&ss->slock, flags); + return err; + } + +@@ -149,6 +150,7 @@ static int sun4i_ss_cipher_poll(struct a + unsigned int ob = 0; /* offset in buf */ + unsigned int obo = 0; /* offset in bufo*/ + unsigned int obl = 0; /* length of data in bufo */ ++ unsigned long flags; + + if (areq->nbytes == 0) + return 0; +@@ -181,7 +183,7 @@ static int sun4i_ss_cipher_poll(struct a + if (no_chunk == 1) + return sun4i_ss_opti_poll(areq); + +- spin_lock_bh(&ss->slock); ++ spin_lock_irqsave(&ss->slock, flags); + + for (i = 0; i < op->keylen; i += 4) + writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); +@@ -308,7 +310,7 @@ release_ss: + sg_miter_stop(&mi); + sg_miter_stop(&mo); + writel(0, ss->base + SS_CTL); +- spin_unlock_bh(&ss->slock); ++ spin_unlock_irqrestore(&ss->slock, flags); + + return err; + } diff --git a/queue-4.5/crypto-talitos-fix-ahash-algorithms-registration.patch b/queue-4.5/crypto-talitos-fix-ahash-algorithms-registration.patch new file mode 100644 index 00000000000..66843f30614 --- /dev/null +++ b/queue-4.5/crypto-talitos-fix-ahash-algorithms-registration.patch @@ -0,0 +1,192 @@ +From 3639ca840df953f9af6f15fc8a6bf77f19075ab1 Mon Sep 17 00:00:00 2001 +From: Horia Geant? +Date: Thu, 21 Apr 2016 19:24:55 +0300 +Subject: crypto: talitos - fix ahash algorithms registration + +From: Horia Geant? + +commit 3639ca840df953f9af6f15fc8a6bf77f19075ab1 upstream. + +Provide hardware state import/export functionality, as mandated by +commit 8996eafdcbad ("crypto: ahash - ensure statesize is non-zero") + +Reported-by: Jonas Eymann +Signed-off-by: Horia Geant? +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/crypto/talitos.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +--- a/drivers/crypto/talitos.c ++++ b/drivers/crypto/talitos.c +@@ -835,6 +835,16 @@ struct talitos_ahash_req_ctx { + struct scatterlist *psrc; + }; + ++struct talitos_export_state { ++ u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)]; ++ u8 buf[HASH_MAX_BLOCK_SIZE]; ++ unsigned int swinit; ++ unsigned int first; ++ unsigned int last; ++ unsigned int to_hash_later; ++ unsigned int nbuf; ++}; ++ + static int aead_setkey(struct crypto_aead *authenc, + const u8 *key, unsigned int keylen) + { +@@ -1981,6 +1991,46 @@ static int ahash_digest(struct ahash_req + return ahash_process_req(areq, areq->nbytes); + } + ++static int ahash_export(struct ahash_request *areq, void *out) ++{ ++ struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); ++ struct talitos_export_state *export = out; ++ ++ memcpy(export->hw_context, req_ctx->hw_context, ++ req_ctx->hw_context_size); ++ memcpy(export->buf, req_ctx->buf, req_ctx->nbuf); ++ export->swinit = req_ctx->swinit; ++ export->first = req_ctx->first; ++ export->last = req_ctx->last; ++ export->to_hash_later = req_ctx->to_hash_later; ++ export->nbuf = req_ctx->nbuf; ++ ++ return 0; ++} ++ ++static int ahash_import(struct ahash_request *areq, const void *in) ++{ ++ struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq); ++ struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq); ++ const struct talitos_export_state *export = in; ++ ++ memset(req_ctx, 0, sizeof(*req_ctx)); ++ req_ctx->hw_context_size = ++ (crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE) ++ ? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256 ++ : TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512; ++ memcpy(req_ctx->hw_context, export->hw_context, ++ req_ctx->hw_context_size); ++ memcpy(req_ctx->buf, export->buf, export->nbuf); ++ req_ctx->swinit = export->swinit; ++ req_ctx->first = export->first; ++ req_ctx->last = export->last; ++ req_ctx->to_hash_later = export->to_hash_later; ++ req_ctx->nbuf = export->nbuf; ++ ++ return 0; ++} ++ + struct keyhash_result { + struct completion completion; + int err; +@@ -2458,6 +2508,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = MD5_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "md5", + .cra_driver_name = "md5-talitos", +@@ -2473,6 +2524,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA1_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-talitos", +@@ -2488,6 +2540,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA224_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-talitos", +@@ -2503,6 +2556,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA256_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-talitos", +@@ -2518,6 +2572,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA384_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "sha384", + .cra_driver_name = "sha384-talitos", +@@ -2533,6 +2588,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA512_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "sha512", + .cra_driver_name = "sha512-talitos", +@@ -2548,6 +2604,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = MD5_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(md5)", + .cra_driver_name = "hmac-md5-talitos", +@@ -2563,6 +2620,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA1_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(sha1)", + .cra_driver_name = "hmac-sha1-talitos", +@@ -2578,6 +2636,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA224_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(sha224)", + .cra_driver_name = "hmac-sha224-talitos", +@@ -2593,6 +2652,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA256_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(sha256)", + .cra_driver_name = "hmac-sha256-talitos", +@@ -2608,6 +2668,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA384_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(sha384)", + .cra_driver_name = "hmac-sha384-talitos", +@@ -2623,6 +2684,7 @@ static struct talitos_alg_template drive + { .type = CRYPTO_ALG_TYPE_AHASH, + .alg.hash = { + .halg.digestsize = SHA512_DIGEST_SIZE, ++ .halg.statesize = sizeof(struct talitos_export_state), + .halg.base = { + .cra_name = "hmac(sha512)", + .cra_driver_name = "hmac-sha512-talitos", +@@ -2814,6 +2876,8 @@ static struct talitos_crypto_alg *talito + t_alg->algt.alg.hash.finup = ahash_finup; + t_alg->algt.alg.hash.digest = ahash_digest; + t_alg->algt.alg.hash.setkey = ahash_setkey; ++ t_alg->algt.alg.hash.import = ahash_import; ++ t_alg->algt.alg.hash.export = ahash_export; + + if (!(priv->features & TALITOS_FTR_HMAC_OK) && + !strncmp(alg->cra_name, "hmac", 4)) { diff --git a/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-lanman-authentication.patch b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-lanman-authentication.patch new file mode 100644 index 00000000000..e3e7cee4455 --- /dev/null +++ b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-lanman-authentication.patch @@ -0,0 +1,63 @@ +From fa8f3a354bb775ec586e4475bcb07f7dece97e0c Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 3 May 2016 10:52:30 +0200 +Subject: fs/cifs: correctly to anonymous authentication for the LANMAN authentication + +From: Stefan Metzmacher + +commit fa8f3a354bb775ec586e4475bcb07f7dece97e0c upstream. + +Only server which map unknown users to guest will allow +access using a non-null LMChallengeResponse. + +For Samba it's the "map to guest = bad user" option. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11913 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/sess.c | 28 ++++++++++++++++------------ + 1 file changed, 16 insertions(+), 12 deletions(-) + +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -678,20 +678,24 @@ sess_auth_lanman(struct sess_data *sess_ + + pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE; + +- /* no capabilities flags in old lanman negotiation */ +- pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); ++ if (ses->user_name != NULL) { ++ /* no capabilities flags in old lanman negotiation */ ++ pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); + +- /* Calculate hash with password and copy into bcc_ptr. +- * Encryption Key (stored as in cryptkey) gets used if the +- * security mode bit in Negottiate Protocol response states +- * to use challenge/response method (i.e. Password bit is 1). +- */ +- rc = calc_lanman_hash(ses->password, ses->server->cryptkey, +- ses->server->sec_mode & SECMODE_PW_ENCRYPT ? +- true : false, lnm_session_key); ++ /* Calculate hash with password and copy into bcc_ptr. ++ * Encryption Key (stored as in cryptkey) gets used if the ++ * security mode bit in Negottiate Protocol response states ++ * to use challenge/response method (i.e. Password bit is 1). ++ */ ++ rc = calc_lanman_hash(ses->password, ses->server->cryptkey, ++ ses->server->sec_mode & SECMODE_PW_ENCRYPT ? ++ true : false, lnm_session_key); + +- memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE); +- bcc_ptr += CIFS_AUTH_RESP_SIZE; ++ memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE); ++ bcc_ptr += CIFS_AUTH_RESP_SIZE; ++ } else { ++ pSMB->old_req.PasswordLength = 0; ++ } + + /* + * can not sign if LANMAN negotiated so no need diff --git a/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v1-authentication.patch b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v1-authentication.patch new file mode 100644 index 00000000000..40348c34b68 --- /dev/null +++ b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v1-authentication.patch @@ -0,0 +1,76 @@ +From 777f69b8d26bf35ade4a76b08f203c11e048365d Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 3 May 2016 10:52:30 +0200 +Subject: fs/cifs: correctly to anonymous authentication for the NTLM(v1) authentication + +From: Stefan Metzmacher + +commit 777f69b8d26bf35ade4a76b08f203c11e048365d upstream. + +Only server which map unknown users to guest will allow +access using a non-null NTChallengeResponse. + +For Samba it's the "map to guest = bad user" option. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11913 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/sess.c | 41 +++++++++++++++++++++++------------------ + 1 file changed, 23 insertions(+), 18 deletions(-) + +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -781,26 +781,31 @@ sess_auth_ntlm(struct sess_data *sess_da + capabilities = cifs_ssetup_hdr(ses, pSMB); + + pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); +- pSMB->req_no_secext.CaseInsensitivePasswordLength = +- cpu_to_le16(CIFS_AUTH_RESP_SIZE); +- pSMB->req_no_secext.CaseSensitivePasswordLength = +- cpu_to_le16(CIFS_AUTH_RESP_SIZE); ++ if (ses->user_name != NULL) { ++ pSMB->req_no_secext.CaseInsensitivePasswordLength = ++ cpu_to_le16(CIFS_AUTH_RESP_SIZE); ++ pSMB->req_no_secext.CaseSensitivePasswordLength = ++ cpu_to_le16(CIFS_AUTH_RESP_SIZE); + +- /* calculate ntlm response and session key */ +- rc = setup_ntlm_response(ses, sess_data->nls_cp); +- if (rc) { +- cifs_dbg(VFS, "Error %d during NTLM authentication\n", +- rc); +- goto out; +- } ++ /* calculate ntlm response and session key */ ++ rc = setup_ntlm_response(ses, sess_data->nls_cp); ++ if (rc) { ++ cifs_dbg(VFS, "Error %d during NTLM authentication\n", ++ rc); ++ goto out; ++ } + +- /* copy ntlm response */ +- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, +- CIFS_AUTH_RESP_SIZE); +- bcc_ptr += CIFS_AUTH_RESP_SIZE; +- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, +- CIFS_AUTH_RESP_SIZE); +- bcc_ptr += CIFS_AUTH_RESP_SIZE; ++ /* copy ntlm response */ ++ memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, ++ CIFS_AUTH_RESP_SIZE); ++ bcc_ptr += CIFS_AUTH_RESP_SIZE; ++ memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, ++ CIFS_AUTH_RESP_SIZE); ++ bcc_ptr += CIFS_AUTH_RESP_SIZE; ++ } else { ++ pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; ++ pSMB->req_no_secext.CaseSensitivePasswordLength = 0; ++ } + + if (ses->capabilities & CAP_UNICODE) { + /* unicode strings must be word aligned */ diff --git a/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v2-authentication.patch b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v2-authentication.patch new file mode 100644 index 00000000000..b5f97a484a0 --- /dev/null +++ b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v2-authentication.patch @@ -0,0 +1,67 @@ +From 1a967d6c9b39c226be1b45f13acd4d8a5ab3dc44 Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 3 May 2016 10:52:30 +0200 +Subject: fs/cifs: correctly to anonymous authentication for the NTLM(v2) authentication + +From: Stefan Metzmacher + +commit 1a967d6c9b39c226be1b45f13acd4d8a5ab3dc44 upstream. + +Only server which map unknown users to guest will allow +access using a non-null NTLMv2_Response. + +For Samba it's the "map to guest = bad user" option. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11913 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/sess.c | 32 ++++++++++++++++++-------------- + 1 file changed, 18 insertions(+), 14 deletions(-) + +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -895,22 +895,26 @@ sess_auth_ntlmv2(struct sess_data *sess_ + /* LM2 password would be here if we supported it */ + pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; + +- /* calculate nlmv2 response and session key */ +- rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp); +- if (rc) { +- cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc); +- goto out; +- } ++ if (ses->user_name != NULL) { ++ /* calculate nlmv2 response and session key */ ++ rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp); ++ if (rc) { ++ cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc); ++ goto out; ++ } + +- memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, +- ses->auth_key.len - CIFS_SESS_KEY_SIZE); +- bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE; ++ memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, ++ ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE; + +- /* set case sensitive password length after tilen may get +- * assigned, tilen is 0 otherwise. +- */ +- pSMB->req_no_secext.CaseSensitivePasswordLength = +- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ /* set case sensitive password length after tilen may get ++ * assigned, tilen is 0 otherwise. ++ */ ++ pSMB->req_no_secext.CaseSensitivePasswordLength = ++ cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ } else { ++ pSMB->req_no_secext.CaseSensitivePasswordLength = 0; ++ } + + if (ses->capabilities & CAP_UNICODE) { + if (sess_data->iov[0].iov_len % 2) { diff --git a/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-via-ntlmssp.patch b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-via-ntlmssp.patch new file mode 100644 index 00000000000..cb87b47c908 --- /dev/null +++ b/queue-4.5/fs-cifs-correctly-to-anonymous-authentication-via-ntlmssp.patch @@ -0,0 +1,79 @@ +From cfda35d98298131bf38fbad3ce4cd5ecb3cf18db Mon Sep 17 00:00:00 2001 +From: Stefan Metzmacher +Date: Tue, 3 May 2016 10:52:30 +0200 +Subject: fs/cifs: correctly to anonymous authentication via NTLMSSP + +From: Stefan Metzmacher + +commit cfda35d98298131bf38fbad3ce4cd5ecb3cf18db upstream. + +See [MS-NLMP] 3.2.5.1.2 Server Receives an AUTHENTICATE_MESSAGE from the Client: + + ... + Set NullSession to FALSE + If (AUTHENTICATE_MESSAGE.UserNameLen == 0 AND + AUTHENTICATE_MESSAGE.NtChallengeResponse.Length == 0 AND + (AUTHENTICATE_MESSAGE.LmChallengeResponse == Z(1) + OR + AUTHENTICATE_MESSAGE.LmChallengeResponse.Length == 0)) + -- Special case: client requested anonymous authentication + Set NullSession to TRUE + ... + +Only server which map unknown users to guest will allow +access using a non-null NTChallengeResponse. + +For Samba it's the "map to guest = bad user" option. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=11913 + +Signed-off-by: Stefan Metzmacher +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/sess.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +--- a/fs/cifs/sess.c ++++ b/fs/cifs/sess.c +@@ -400,19 +400,27 @@ int build_ntlmssp_auth_blob(unsigned cha + sec_blob->LmChallengeResponse.MaximumLength = 0; + + sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer); +- rc = setup_ntlmv2_rsp(ses, nls_cp); +- if (rc) { +- cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc); +- goto setup_ntlmv2_ret; +- } +- memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE, +- ses->auth_key.len - CIFS_SESS_KEY_SIZE); +- tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE; ++ if (ses->user_name != NULL) { ++ rc = setup_ntlmv2_rsp(ses, nls_cp); ++ if (rc) { ++ cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc); ++ goto setup_ntlmv2_ret; ++ } ++ memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE, ++ ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE; + +- sec_blob->NtChallengeResponse.Length = +- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); +- sec_blob->NtChallengeResponse.MaximumLength = +- cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ sec_blob->NtChallengeResponse.Length = ++ cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ sec_blob->NtChallengeResponse.MaximumLength = ++ cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE); ++ } else { ++ /* ++ * don't send an NT Response for anonymous access ++ */ ++ sec_blob->NtChallengeResponse.Length = 0; ++ sec_blob->NtChallengeResponse.MaximumLength = 0; ++ } + + if (ses->domainName == NULL) { + sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer); diff --git a/queue-4.5/remove-directory-incorrectly-tries-to-set-delete-on-close-on-non-empty-directories.patch b/queue-4.5/remove-directory-incorrectly-tries-to-set-delete-on-close-on-non-empty-directories.patch new file mode 100644 index 00000000000..cc7d482db05 --- /dev/null +++ b/queue-4.5/remove-directory-incorrectly-tries-to-set-delete-on-close-on-non-empty-directories.patch @@ -0,0 +1,102 @@ +From 897fba1172d637d344f009d700f7eb8a1fa262f1 Mon Sep 17 00:00:00 2001 +From: Steve French +Date: Thu, 12 May 2016 21:20:36 -0500 +Subject: remove directory incorrectly tries to set delete on close on non-empty directories + +From: Steve French + +commit 897fba1172d637d344f009d700f7eb8a1fa262f1 upstream. + +Wrong return code was being returned on SMB3 rmdir of +non-empty directory. + +For SMB3 (unlike for cifs), we attempt to delete a directory by +set of delete on close flag on the open. Windows clients set +this flag via a set info (SET_FILE_DISPOSITION to set this flag) +which properly checks if the directory is empty. + +With this patch on smb3 mounts we correctly return + "DIRECTORY NOT EMPTY" +on attempts to remove a non-empty directory. + +Signed-off-by: Steve French +Acked-by: Sachin Prabhu +Signed-off-by: Greg Kroah-Hartman + +--- + fs/cifs/smb2glob.h | 1 + + fs/cifs/smb2inode.c | 8 ++++++-- + fs/cifs/smb2pdu.c | 16 ++++++++++++++++ + fs/cifs/smb2proto.h | 2 ++ + 4 files changed, 25 insertions(+), 2 deletions(-) + +--- a/fs/cifs/smb2glob.h ++++ b/fs/cifs/smb2glob.h +@@ -44,6 +44,7 @@ + #define SMB2_OP_DELETE 7 + #define SMB2_OP_HARDLINK 8 + #define SMB2_OP_SET_EOF 9 ++#define SMB2_OP_RMDIR 10 + + /* Used when constructing chained read requests. */ + #define CHAINED_REQUEST 1 +--- a/fs/cifs/smb2inode.c ++++ b/fs/cifs/smb2inode.c +@@ -80,6 +80,10 @@ smb2_open_op_close(const unsigned int xi + * SMB2_open() call. + */ + break; ++ case SMB2_OP_RMDIR: ++ tmprc = SMB2_rmdir(xid, tcon, fid.persistent_fid, ++ fid.volatile_fid); ++ break; + case SMB2_OP_RENAME: + tmprc = SMB2_rename(xid, tcon, fid.persistent_fid, + fid.volatile_fid, (__le16 *)data); +@@ -191,8 +195,8 @@ smb2_rmdir(const unsigned int xid, struc + struct cifs_sb_info *cifs_sb) + { + return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, +- CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE, +- NULL, SMB2_OP_DELETE); ++ CREATE_NOT_FILE, ++ NULL, SMB2_OP_RMDIR); + } + + int +--- a/fs/cifs/smb2pdu.c ++++ b/fs/cifs/smb2pdu.c +@@ -2575,6 +2575,22 @@ SMB2_rename(const unsigned int xid, stru + } + + int ++SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, ++ u64 persistent_fid, u64 volatile_fid) ++{ ++ __u8 delete_pending = 1; ++ void *data; ++ unsigned int size; ++ ++ data = &delete_pending; ++ size = 1; /* sizeof __u8 */ ++ ++ return send_set_info(xid, tcon, persistent_fid, volatile_fid, ++ current->tgid, FILE_DISPOSITION_INFORMATION, 1, &data, ++ &size); ++} ++ ++int + SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, __le16 *target_file) + { +--- a/fs/cifs/smb2proto.h ++++ b/fs/cifs/smb2proto.h +@@ -141,6 +141,8 @@ extern int SMB2_query_directory(const un + extern int SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + __le16 *target_file); ++extern int SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, ++ u64 persistent_fid, u64 volatile_fid); + extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon, + u64 persistent_fid, u64 volatile_fid, + __le16 *target_file); diff --git a/queue-4.5/ring-buffer-prevent-overflow-of-size-in-ring_buffer_resize.patch b/queue-4.5/ring-buffer-prevent-overflow-of-size-in-ring_buffer_resize.patch new file mode 100644 index 00000000000..a7f55a12724 --- /dev/null +++ b/queue-4.5/ring-buffer-prevent-overflow-of-size-in-ring_buffer_resize.patch @@ -0,0 +1,89 @@ +From 59643d1535eb220668692a5359de22545af579f6 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Fri, 13 May 2016 09:34:12 -0400 +Subject: ring-buffer: Prevent overflow of size in ring_buffer_resize() + +From: Steven Rostedt (Red Hat) + +commit 59643d1535eb220668692a5359de22545af579f6 upstream. + +If the size passed to ring_buffer_resize() is greater than MAX_LONG - BUF_PAGE_SIZE +then the DIV_ROUND_UP() will return zero. + +Here's the details: + + # echo 18014398509481980 > /sys/kernel/debug/tracing/buffer_size_kb + +tracing_entries_write() processes this and converts kb to bytes. + + 18014398509481980 << 10 = 18446744073709547520 + +and this is passed to ring_buffer_resize() as unsigned long size. + + size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); + +Where DIV_ROUND_UP(a, b) is (a + b - 1)/b + +BUF_PAGE_SIZE is 4080 and here + + 18446744073709547520 + 4080 - 1 = 18446744073709551599 + +where 18446744073709551599 is still smaller than 2^64 + + 2^64 - 18446744073709551599 = 17 + +But now 18446744073709551599 / 4080 = 4521260802379792 + +and size = size * 4080 = 18446744073709551360 + +This is checked to make sure its still greater than 2 * 4080, +which it is. + +Then we convert to the number of buffer pages needed. + + nr_page = DIV_ROUND_UP(size, BUF_PAGE_SIZE) + +but this time size is 18446744073709551360 and + + 2^64 - (18446744073709551360 + 4080 - 1) = -3823 + +Thus it overflows and the resulting number is less than 4080, which makes + + 3823 / 4080 = 0 + +an nr_pages is set to this. As we already checked against the minimum that +nr_pages may be, this causes the logic to fail as well, and we crash the +kernel. + +There's no reason to have the two DIV_ROUND_UP() (that's just result of +historical code changes), clean up the code and fix this bug. + +Fixes: 83f40318dab00 ("ring-buffer: Make removal of ring buffer pages atomic") +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ring_buffer.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -1657,14 +1657,13 @@ int ring_buffer_resize(struct ring_buffe + !cpumask_test_cpu(cpu_id, buffer->cpumask)) + return size; + +- size = DIV_ROUND_UP(size, BUF_PAGE_SIZE); +- size *= BUF_PAGE_SIZE; ++ nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); + + /* we need a minimum of two pages */ +- if (size < BUF_PAGE_SIZE * 2) +- size = BUF_PAGE_SIZE * 2; ++ if (nr_pages < 2) ++ nr_pages = 2; + +- nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE); ++ size = nr_pages * BUF_PAGE_SIZE; + + /* + * Don't succeed if resizing is disabled, as a reader might be diff --git a/queue-4.5/ring-buffer-use-long-for-nr_pages-to-avoid-overflow-failures.patch b/queue-4.5/ring-buffer-use-long-for-nr_pages-to-avoid-overflow-failures.patch new file mode 100644 index 00000000000..8538fbb8bcb --- /dev/null +++ b/queue-4.5/ring-buffer-use-long-for-nr_pages-to-avoid-overflow-failures.patch @@ -0,0 +1,161 @@ +From 9b94a8fba501f38368aef6ac1b30e7335252a220 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Thu, 12 May 2016 11:01:24 -0400 +Subject: ring-buffer: Use long for nr_pages to avoid overflow failures + +From: Steven Rostedt (Red Hat) + +commit 9b94a8fba501f38368aef6ac1b30e7335252a220 upstream. + +The size variable to change the ring buffer in ftrace is a long. The +nr_pages used to update the ring buffer based on the size is int. On 64 bit +machines this can cause an overflow problem. + +For example, the following will cause the ring buffer to crash: + + # cd /sys/kernel/debug/tracing + # echo 10 > buffer_size_kb + # echo 8556384240 > buffer_size_kb + +Then you get the warning of: + + WARNING: CPU: 1 PID: 318 at kernel/trace/ring_buffer.c:1527 rb_update_pages+0x22f/0x260 + +Which is: + + RB_WARN_ON(cpu_buffer, nr_removed); + +Note each ring buffer page holds 4080 bytes. + +This is because: + + 1) 10 causes the ring buffer to have 3 pages. + (10kb requires 3 * 4080 pages to hold) + + 2) (2^31 / 2^10 + 1) * 4080 = 8556384240 + The value written into buffer_size_kb is shifted by 10 and then passed + to ring_buffer_resize(). 8556384240 * 2^10 = 8761737461760 + + 3) The size passed to ring_buffer_resize() is then divided by BUF_PAGE_SIZE + which is 4080. 8761737461760 / 4080 = 2147484672 + + 4) nr_pages is subtracted from the current nr_pages (3) and we get: + 2147484669. This value is saved in a signed integer nr_pages_to_update + + 5) 2147484669 is greater than 2^31 but smaller than 2^32, a signed int + turns into the value of -2147482627 + + 6) As the value is a negative number, in update_pages_handler() it is + negated and passed to rb_remove_pages() and 2147482627 pages will + be removed, which is much larger than 3 and it causes the warning + because not all the pages asked to be removed were removed. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=118001 + +Fixes: 7a8e76a3829f1 ("tracing: unified trace buffer") +Reported-by: Hao Qin +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ring_buffer.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -437,7 +437,7 @@ struct ring_buffer_per_cpu { + raw_spinlock_t reader_lock; /* serialize readers */ + arch_spinlock_t lock; + struct lock_class_key lock_key; +- unsigned int nr_pages; ++ unsigned long nr_pages; + unsigned int current_context; + struct list_head *pages; + struct buffer_page *head_page; /* read from head */ +@@ -458,7 +458,7 @@ struct ring_buffer_per_cpu { + u64 write_stamp; + u64 read_stamp; + /* ring buffer pages to update, > 0 to add, < 0 to remove */ +- int nr_pages_to_update; ++ long nr_pages_to_update; + struct list_head new_pages; /* new pages to add */ + struct work_struct update_pages_work; + struct completion update_done; +@@ -1128,10 +1128,10 @@ static int rb_check_pages(struct ring_bu + return 0; + } + +-static int __rb_allocate_pages(int nr_pages, struct list_head *pages, int cpu) ++static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu) + { +- int i; + struct buffer_page *bpage, *tmp; ++ long i; + + for (i = 0; i < nr_pages; i++) { + struct page *page; +@@ -1168,7 +1168,7 @@ free_pages: + } + + static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer, +- unsigned nr_pages) ++ unsigned long nr_pages) + { + LIST_HEAD(pages); + +@@ -1193,7 +1193,7 @@ static int rb_allocate_pages(struct ring + } + + static struct ring_buffer_per_cpu * +-rb_allocate_cpu_buffer(struct ring_buffer *buffer, int nr_pages, int cpu) ++rb_allocate_cpu_buffer(struct ring_buffer *buffer, long nr_pages, int cpu) + { + struct ring_buffer_per_cpu *cpu_buffer; + struct buffer_page *bpage; +@@ -1293,8 +1293,9 @@ struct ring_buffer *__ring_buffer_alloc( + struct lock_class_key *key) + { + struct ring_buffer *buffer; ++ long nr_pages; + int bsize; +- int cpu, nr_pages; ++ int cpu; + + /* keep it in its own cache line */ + buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()), +@@ -1420,12 +1421,12 @@ static inline unsigned long rb_page_writ + } + + static int +-rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages) ++rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages) + { + struct list_head *tail_page, *to_remove, *next_page; + struct buffer_page *to_remove_page, *tmp_iter_page; + struct buffer_page *last_page, *first_page; +- unsigned int nr_removed; ++ unsigned long nr_removed; + unsigned long head_bit; + int page_entries; + +@@ -1642,7 +1643,7 @@ int ring_buffer_resize(struct ring_buffe + int cpu_id) + { + struct ring_buffer_per_cpu *cpu_buffer; +- unsigned nr_pages; ++ unsigned long nr_pages; + int cpu, err = 0; + + /* +@@ -4640,8 +4641,9 @@ static int rb_cpu_notify(struct notifier + struct ring_buffer *buffer = + container_of(self, struct ring_buffer, cpu_notify); + long cpu = (long)hcpu; +- int cpu_i, nr_pages_same; +- unsigned int nr_pages; ++ long nr_pages_same; ++ int cpu_i; ++ unsigned long nr_pages; + + switch (action) { + case CPU_UP_PREPARE: diff --git a/queue-4.5/series b/queue-4.5/series index c867fa6bd84..57cd07aa772 100644 --- a/queue-4.5/series +++ b/queue-4.5/series @@ -7,3 +7,16 @@ arm64-implement-pmdp_set_access_flags-for-hardware-af-dbm.patch arm64-cpuinfo-missing-null-terminator-in-compat_hwcap_str.patch arm-arm64-kvm-enforce-break-before-make-on-stage-2-page-tables.patch kvm-arm64-fix-ec-field-in-inject_abt64.patch +remove-directory-incorrectly-tries-to-set-delete-on-close-on-non-empty-directories.patch +fs-cifs-correctly-to-anonymous-authentication-via-ntlmssp.patch +fs-cifs-correctly-to-anonymous-authentication-for-the-lanman-authentication.patch +fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v1-authentication.patch +fs-cifs-correctly-to-anonymous-authentication-for-the-ntlm-v2-authentication.patch +cifs-create-dedicated-keyring-for-spnego-operations.patch +asix-fix-offset-calculation-in-asix_rx_fixup-causing-slow-transmissions.patch +ring-buffer-use-long-for-nr_pages-to-avoid-overflow-failures.patch +ring-buffer-prevent-overflow-of-size-in-ring_buffer_resize.patch +crypto-caam-fix-caam_jr_alloc-ret-code.patch +crypto-talitos-fix-ahash-algorithms-registration.patch +crypto-sun4i-ss-replace-spinlock_bh-by-spin_lock_irq-save-restore.patch +clk-qcom-msm8916-fix-crypto-clock-flags.patch