From: Tom Talpey <tom@talpey.com>
To: Enzo Matsumiya <ematsumiya@suse.de>, linux-cifs@vger.kernel.org
Cc: smfrench@gmail.com, pc@cjr.nz, ronniesahlberg@gmail.com,
nspmangalore@gmail.com
Subject: Re: [RFC PATCH] cifs: fix signature check for error responses
Date: Wed, 28 Sep 2022 11:05:08 -0400 [thread overview]
Message-ID: <2cbf804b-a692-ad45-4ec4-4676f15d48f2@talpey.com> (raw)
In-Reply-To: <20220922223216.4730-1-ematsumiya@suse.de>
On 9/22/2022 6:32 PM, Enzo Matsumiya wrote:
> Hi all,
>
> This patch is the (apparent) correct way to fix the issues regarding some
> messages with invalid signatures. My previous patch
> https://lore.kernel.org/linux-cifs/20220918235442.2981-1-ematsumiya@suse.de/
> was wrong because a) it covered up the real issue (*), and b) I could never
> again "reproduce" the "race" -- I had other patches in place when I tested it,
> and (thus?) the system memory was not in "pristine" conditions, so it's very
> likely that there's no race at all.
>
> (*) Thanks a lot to Tom Talpey for pointing me to the right direction here.
>
> Since it sucks to be wrong twice, I'm sending this one as RFC because I
> wanted to confirm some things:
>
> 1) Can I rely on the fact that status != STATUS_SUCCESS means no variable
> data in the message? I could only infer from the spec, but not really
> confirm.
Technically, I think the answer is "no" but practically speaking maybe
"yes".
Not all errors are actually errors however, e.g. STOPPED_ON_SYMLINK and
the additional error contexts which accompany it. We definitely don't
want to skip validation of those.
There's also STATUS_PENDING, but that's special because it isn't actually
a response, it's just a "hang on I'm busy" that carries no other
data.
Finally, MS-SMB2 lists a few others in section 2.2.2.2, all of which
need validation I think.
> 2) (probably only in async cases) When the signature fails, for whatever
> reason, we don't take any action. This doesn't seem right IMHO,
> e.g. if the message is spoofed, we show a warning that the signatures
> doesn't match, but I would expect at least for the operation to stop,
> or maybe even a complete dis/reconnect.
I don't think so. The spec calls for dropping the message, and after
all it could have been simple packet corruption. The retries will sort
it out.
Absolutely positively do not print a message for each received packet,
good or bad.
> 3) For SMB1, I couldn't really use generic/465 as a real confirmation for
> this because it says "O_DIRECT is not supported". From reading the
> code and 'man mount.cifs' I understood that this is supported, so what
> gives? Worth noting that I don't follow/use/test SMB1 too much.
> The patch does work for other cases I tried though.
Honestly, I don't think we care. No amount of patching can possibly
save SMB1.
Tom.
> I hope someone can address my questions/concerts above, and please let me
> know if the patch is technically and semantically correct.
>
> Patch follows.
>
>
> Enzo
>
> --------
> When verifying a response's signature, the computation will go through
> the iov buffer (header + response structs) and the over the page data, to
> verify any dynamic data appended to the message (usually on an SMB2 READ
> response).
>
> When the response is an error, however, specifically on async reads,
> the page data is allocated before receiving the expected data. Being
> "valid" data (from the signature computation POV; non-NULL, >0 pages),
> it's included in the parsing and generates an invalid signature for the
> message.
>
> Fix this by checking if the status is non-zero, and skip the page data
> if it is. The issue happens in all protocol versions, and this fix
> applies to all.
>
> This issue can be observed with xfstests generic/465.
>
> Signed-off-by: Enzo Matsumiya <ematsumiya@suse.de>
> ---
> fs/cifs/cifsencrypt.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
> index 46f5718754f9..e3260bb436b3 100644
> --- a/fs/cifs/cifsencrypt.c
> +++ b/fs/cifs/cifsencrypt.c
> @@ -32,15 +32,28 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
> int rc;
> struct kvec *iov = rqst->rq_iov;
> int n_vec = rqst->rq_nvec;
> + bool has_error = false;
>
> /* iov[0] is actual data and not the rfc1002 length for SMB2+ */
> if (!is_smb1(server)) {
> + struct smb2_hdr *shdr = (struct smb2_hdr *)iov[0].iov_base;
> +
> if (iov[0].iov_len <= 4)
> return -EIO;
> +
> + if (shdr->Status != 0)
> + has_error = true;
> +
> i = 0;
> } else {
> + struct smb_hdr *hdr = (struct smb_hdr *)iov[1].iov_base;
> +
> if (n_vec < 2 || iov[0].iov_len != 4)
> return -EIO;
> +
> + if (hdr->Status.CifsError != 0)
> + has_error = true;
> +
> i = 1; /* skip rfc1002 length */
> }
>
> @@ -61,6 +74,9 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
> }
> }
>
> + if (has_error)
> + goto out_final;
> +
> /* now hash over the rq_pages array */
> for (i = 0; i < rqst->rq_npages; i++) {
> void *kaddr;
> @@ -81,6 +97,7 @@ int __cifs_calc_signature(struct smb_rqst *rqst,
> kunmap(rqst->rq_pages[i]);
> }
>
> +out_final:
> rc = crypto_shash_final(shash, signature);
> if (rc)
> cifs_dbg(VFS, "%s: Could not generate hash\n", __func__);
next prev parent reply other threads:[~2022-09-28 15:05 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-22 22:32 [RFC PATCH] cifs: fix signature check for error responses Enzo Matsumiya
2022-09-28 15:05 ` Tom Talpey [this message]
2022-09-28 16:30 ` Enzo Matsumiya
2022-09-28 19:33 ` Tom Talpey
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=2cbf804b-a692-ad45-4ec4-4676f15d48f2@talpey.com \
--to=tom@talpey.com \
--cc=ematsumiya@suse.de \
--cc=linux-cifs@vger.kernel.org \
--cc=nspmangalore@gmail.com \
--cc=pc@cjr.nz \
--cc=ronniesahlberg@gmail.com \
--cc=smfrench@gmail.com \
/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