From: Rabin Vincent <rabin.vincent-VrBV9hrLPhE@public.gmane.org>
To: Sachin Prabhu <sprabhu-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: sfrench-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org,
linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [PATCH] cifs: fix crash due to race in hmac(md5) handling
Date: Thu, 21 Jul 2016 09:30:53 +0200 [thread overview]
Message-ID: <20160721073053.GA31832@axis.com> (raw)
In-Reply-To: <1469023049.4942.21.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Wed, Jul 20, 2016 at 02:57:29PM +0100, Sachin Prabhu wrote:
> Rabin, do you have a reliable reproducer for this case? If yes, can you
> please point me to it.
I have only seen one report of the oops in real testing, so I don't have
a case that would reproduce easily on an unmodified kernel, but while
investigating this I made a debug patch which forces the faulty sequence
to occur and provides a 100% reliable reproducer.
The below patched forces the race condition by making two mount.cifs
processes wait for each other in the appropriate places.
With the force-race patch applied and without this fix, the crash occurs
every time when the following sequence of commands is run. Tested in a
KVM guest on latest mainline with my "unbreak TCP session reuse" patch
applied.
With the force-race patch applied and with this fix, the mount processes
hang since the race condition can never be satisfied.
cp /sbin/mount.cifs /sbin/cifs1
cp /sbin/mount.cifs /sbin/cifs2
mkdir -p cifs cifs2
cifs1 //192.168.1.1/test cifs -o credentials=/creds &
sleep 2
cifs2 //192.168.1.1/test2 cifs2 -o credentials=/creds
8<-------------------------
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 8347c90..1ed6dfd 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -35,6 +35,32 @@
#include <linux/highmem.h>
#include <crypto/skcipher.h>
+static struct completion completions[100];
+
+void hack_set_state(int newstate)
+{
+ printk("%s: caller %pF sets state to %d\n", current->comm, (void *)_RET_IP_, newstate);
+ complete(&completions[newstate]);
+}
+
+void hack_wait_for_state(int state)
+{
+ printk("%s caller %pF wants state %d\n", current->comm, (void *)_RET_IP_, state);
+ wait_for_completion(&completions[state]);
+ printk("%s caller %pF got state %d\n", current->comm, (void *)_RET_IP_, state);
+}
+
+static int hack_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(completions); i++)
+ init_completion(&completions[i]);
+
+ return 0;
+}
+late_initcall(hack_init);
+
static int
cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
{
@@ -54,6 +80,7 @@ cifs_crypto_shash_md5_allocate(struct TCP_Server_Info *server)
size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.md5);
+
server->secmech.sdescmd5 = kmalloc(size, GFP_KERNEL);
if (!server->secmech.sdescmd5) {
crypto_free_shash(server->secmech.md5);
@@ -661,8 +688,10 @@ static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
unsigned int size;
/* check if already allocated */
- if (server->secmech.sdeschmacmd5)
+ if (server->secmech.sdeschmacmd5) {
+ printk("%s: server %p already allocated\n", __func__, server);
return 0;
+ }
server->secmech.hmacmd5 = crypto_alloc_shash("hmac(md5)", 0, 0);
if (IS_ERR(server->secmech.hmacmd5)) {
@@ -674,12 +703,28 @@ static int crypto_hmacmd5_alloc(struct TCP_Server_Info *server)
size = sizeof(struct shash_desc) +
crypto_shash_descsize(server->secmech.hmacmd5);
+
+ if (!strcmp(current->comm, "cifs1")) {
+ hack_wait_for_state(10);
+ }
+ if (!strcmp(current->comm, "cifs2")) {
+ hack_set_state(10);
+ hack_wait_for_state(20);
+ }
+
server->secmech.sdeschmacmd5 = kmalloc(size, GFP_KERNEL);
+ printk("%s: %s: server %p alloc sdeschmacmd5=%p\n", __func__, current->comm, server, server->secmech.sdeschmacmd5);
if (!server->secmech.sdeschmacmd5) {
crypto_free_shash(server->secmech.hmacmd5);
server->secmech.hmacmd5 = NULL;
return -ENOMEM;
}
+
+ if (!strcmp(current->comm, "cifs2")) {
+ hack_set_state(30);
+ hack_wait_for_state(40);
+ }
+
server->secmech.sdeschmacmd5->shash.tfm = server->secmech.hmacmd5;
server->secmech.sdeschmacmd5->shash.flags = 0x0;
@@ -745,6 +790,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
mutex_lock(&ses->server->srv_mutex);
+ printk("%s: ses %p ses->server %p\n", __func__, ses, ses->server);
rc = crypto_hmacmd5_alloc(ses->server);
if (rc) {
cifs_dbg(VFS, "could not crypto alloc hmacmd5 rc %d\n", rc);
@@ -780,6 +826,11 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
goto unlock;
}
+ if (!strcmp(current->comm, "cifs1")) {
+ hack_set_state(20);
+ hack_wait_for_state(30);
+ }
+
rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
ntlmv2->ntlmv2_hash,
CIFS_HMAC_MD5_HASH_SIZE);
@@ -788,6 +839,8 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
goto unlock;
}
+ hack_set_state(40);
+
rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
ses->auth_key.response);
if (rc)
next prev parent reply other threads:[~2016-07-21 7:30 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-19 7:26 [PATCH] cifs: fix crash due to race in hmac(md5) handling Rabin Vincent
[not found] ` <1468913181-28163-1-git-send-email-rabin.vincent-VrBV9hrLPhE@public.gmane.org>
2016-07-20 13:57 ` Sachin Prabhu
[not found] ` <1469023049.4942.21.camel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2016-07-21 7:30 ` Rabin Vincent [this message]
[not found] ` <20160721073053.GA31832-VrBV9hrLPhE@public.gmane.org>
2016-07-25 9:51 ` Sachin Prabhu
2016-07-20 15:54 ` Steve French
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160721073053.GA31832@axis.com \
--to=rabin.vincent-vrbv9hrlphe@public.gmane.org \
--cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=sfrench-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org \
--cc=sprabhu-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox