From: Eric Dumazet <eric.dumazet@gmail.com>
To: stranche@codeaurora.org, fw@strlen.de, netfilter-devel@vger.kernel.org
Cc: Subashab <subashab@codeaurora.org>
Subject: Re: UAF in ip6_do_table on 4.19 kernel
Date: Mon, 11 Nov 2019 14:09:26 -0800 [thread overview]
Message-ID: <44a69247-87bd-905d-bd1c-e9dcb5027641@gmail.com> (raw)
In-Reply-To: <e7501cbd85e96b111f5c404200a3a330@codeaurora.org>
On 11/11/19 12:49 PM, stranche@codeaurora.org wrote:
> Hi all,
>
> We recently had a crash reported to us on the 4.19 kernel where ip6_do_table() appeared to be referencing a jumpstack that had already been freed.
> Based on the dump, it appears that the scenario was a concurrent use of iptables-restore and active data transfer. The kernel has Florian's commit
> to wait in xt_replace_table instead of get_counters(), 80055dab5de0 ("netfilter: x_tables: make xt_replace_table wait until old rules are not used
> anymore"), so it appears that xt_replace_table is somehow returning prematurely, allowing __do_replace() to free the table while it is still in use.
>
> After reviewing the code, we had a question about the following section:
> /* ... so wait for even xt_recseq on all cpus */
> for_each_possible_cpu(cpu) {
> seqcount_t *s = &per_cpu(xt_recseq, cpu);
> u32 seq = raw_read_seqcount(s);
>
> if (seq & 1) {
> do {
> cond_resched();
> cpu_relax();
> } while (seq == raw_read_seqcount(s));
> }
> }
The intent of this code is to check that each cpu went through a phase where the seq was even at least once.
>
> Based on the other uses of seqcount locks, there should be a paired read_seqcount_retry() to mark the end of the read section like below:
> for_each_possible_cpu(cpu) {
> seqcount_t *s = &per_cpu(xt_recseq, cpu);
> u32 seq;
>
> do {
> seq = raw_read_seqcount(s);
> if (seq & 1) {
> cond_resched();
> cpu_relax();
> }
> } while (read_seqcount_retry(s, seq);
This would loop possibly more times, since you exit if the count is _currently_ even.
If we are unlucky this could loop for a very long time.
> }
>
> These two snippets are very similar, as the original seems like it attempted to open-code this retry() helper, but there is a slight difference in
> the smp_rmb() placement relative to the "retry" read of the sequence value.
> Original:
> READ_ONCE(s->sequence);
> smp_rmb();
> ... //check and resched
> READ_ONCE(s->sequence);
> smp_rmb();
> ... //compare the two sequence values
>
> Modified using read_seqcount_retry():
> READ_ONCE(s->sequence);
> smp_rmb();
> ... //check and and resched
> smp_rmb();
> READ_ONCE(s->sequence);
> ... //compare the two sequence values
>
> Is it possible that this difference in ordering could lead to an incorrect read of the sequence in certain neurotic scenarios? Alternatively, is there
> some other place that this jumpstack could be freed while still in use?
>
4.19 has many bugs really. Please upgrade to v4.19.83
prev parent reply other threads:[~2019-11-11 22:09 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-11 20:49 UAF in ip6_do_table on 4.19 kernel stranche
2019-11-11 22:09 ` Eric Dumazet [this message]
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=44a69247-87bd-905d-bd1c-e9dcb5027641@gmail.com \
--to=eric.dumazet@gmail.com \
--cc=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=stranche@codeaurora.org \
--cc=subashab@codeaurora.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.