lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <2d002841-402c-2bc3-2b33-3e6d1cd14c23@gmail.com>
Date:   Tue, 10 Aug 2021 00:16:57 +0300
From:   Pavel Skripkin <paskripkin@...il.com>
To:     Florian Westphal <fw@...len.de>
Cc:     syzbot <syzbot+649e339fa6658ee623d3@...kaller.appspotmail.com>,
        coreteam@...filter.org, davem@...emloft.net, kadlec@...filter.org,
        kuba@...nel.org, linux-kernel@...r.kernel.org,
        netdev@...r.kernel.org, netfilter-devel@...r.kernel.org,
        pablo@...filter.org, syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] KASAN: use-after-free Write in nft_ct_tmpl_put_pcpu

On 8/9/21 11:39 PM, Florian Westphal wrote:
> Pavel Skripkin <paskripkin@...il.com> wrote:
>> I think, there a missing lock in this function:
>> 
>> 	for_each_possible_cpu(cpu) {
>> 		ct = per_cpu(nft_ct_pcpu_template, cpu);

(*)

>> 		if (!ct) >> 			break;
>> 		nf_ct_put(ct);
>> 		per_cpu(nft_ct_pcpu_template, cpu) = NULL;
>> 		
>> 	}
>> 
>> Syzbot hit a UAF in nft_ct_tmpl_put_pcpu() (*), but freed template should be
>> NULL.
>> 
>> So I suspect following scenario:
>> 
>> 
>> CPU0:			CPU1:
>> = per_cpu()
>> 			= per_cpu()
>> 
>> nf_ct_put
>> per_cpu = NULL
>> 			nf_ct_put()
>> 			* UAF *

Hi, Florian!

> 
> Yes and no.  The above is fine since pcpu will return different pointers
> for cpu 0 and 1.
> 

Dumb question: why per_cpu() will return 2 different pointers for CPU 1 
and CPU 0? As I understand for_each_possible_cpu() will iterate over all
CPUs which could ever be enabled. So, we can hit situation when 2 
concurrent processes call per_cpu() with same cpu value (*).

> The race is between two different net namespaces that race when
> changing nft_ct_pcpu_template_refcnt.
> This happens since
> 
> commit f102d66b335a417d4848da9441f585695a838934
> netfilter: nf_tables: use dedicated mutex to guard transactions
> 
> Before this, all transactions were serialized by a global mutex,
> now we only serialize transactions in the same netns.
> 
> Its probably best to add
> DEFINE_MUTEX(nft_ct_pcpu_mutex) and then acquire that when we need to
> inc/dec the nft_ct_pcpu_template_refcnt so we can't have two distinct
> cpus hitting a zero refcount.
> 
> Would you send a patch for this?
> 

Anyway, I think, moving locking a bit higher is good here, let's test 
it. I will prepare a patch, if it will pass syzbot testing, thanks!


#syz test
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master



With regards,
Pavel Skripkin



View attachment "0001-netfiler-protect-nft_ct_pcpu_template_refcnt-with-mu.patch" of type "text/x-patch" (1637 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ