* [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
@ 2024-03-05 8:09 Roman Smirnov
2024-03-06 1:48 ` Chao Yu
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Roman Smirnov @ 2024-03-05 8:09 UTC (permalink / raw)
To: Jaegeuk Kim, Chao Yu
Cc: Roman Smirnov, Sergey Shtylyov, Karina Yankevich,
linux-f2fs-devel, linux-kernel, lvc-project
Cast expression type to unsigned long in __count_extent_cache()
to prevent integer overflow.
Found by Linux Verification Center (linuxtesting.org) with Svace.
Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
---
fs/f2fs/shrinker.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
index 83d6fb97dcae..bb86a06c5d5e 100644
--- a/fs/f2fs/shrinker.c
+++ b/fs/f2fs/shrinker.c
@@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
{
struct extent_tree_info *eti = &sbi->extent_tree[type];
- return atomic_read(&eti->total_zombie_tree) +
+ return (unsigned long)atomic_read(&eti->total_zombie_tree) +
atomic_read(&eti->total_ext_node);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
2024-03-05 8:09 [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache() Roman Smirnov
@ 2024-03-06 1:48 ` Chao Yu
2024-03-06 17:50 ` [f2fs-dev] " patchwork-bot+f2fs
2024-03-10 17:46 ` David Laight
2 siblings, 0 replies; 6+ messages in thread
From: Chao Yu @ 2024-03-06 1:48 UTC (permalink / raw)
To: Roman Smirnov, Jaegeuk Kim
Cc: Sergey Shtylyov, Karina Yankevich, linux-f2fs-devel, linux-kernel,
lvc-project
On 2024/3/5 16:09, Roman Smirnov wrote:
> Cast expression type to unsigned long in __count_extent_cache()
> to prevent integer overflow.
>
> Found by Linux Verification Center (linuxtesting.org) with Svace.
>
> Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
> Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
Reviewed-by: Chao Yu <chao@kernel.org>
Thanks,
> ---
> fs/f2fs/shrinker.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> index 83d6fb97dcae..bb86a06c5d5e 100644
> --- a/fs/f2fs/shrinker.c
> +++ b/fs/f2fs/shrinker.c
> @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
> {
> struct extent_tree_info *eti = &sbi->extent_tree[type];
>
> - return atomic_read(&eti->total_zombie_tree) +
> + return (unsigned long)atomic_read(&eti->total_zombie_tree) +
> atomic_read(&eti->total_ext_node);
> }
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [f2fs-dev] [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
2024-03-05 8:09 [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache() Roman Smirnov
2024-03-06 1:48 ` Chao Yu
@ 2024-03-06 17:50 ` patchwork-bot+f2fs
2024-03-10 17:46 ` David Laight
2 siblings, 0 replies; 6+ messages in thread
From: patchwork-bot+f2fs @ 2024-03-06 17:50 UTC (permalink / raw)
To: Roman Smirnov
Cc: jaegeuk, chao, s.shtylyov, lvc-project, linux-kernel, k.yankevich,
linux-f2fs-devel
Hello:
This patch was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:
On Tue, 5 Mar 2024 11:09:43 +0300 you wrote:
> Cast expression type to unsigned long in __count_extent_cache()
> to prevent integer overflow.
>
> Found by Linux Verification Center (linuxtesting.org) with Svace.
>
> Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
> Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
>
> [...]
Here is the summary with links:
- [f2fs-dev] f2fs: Cast expression type to unsigned long in __count_extent_cache()
https://git.kernel.org/jaegeuk/f2fs/c/e88f4647d82f
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
2024-03-05 8:09 [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache() Roman Smirnov
2024-03-06 1:48 ` Chao Yu
2024-03-06 17:50 ` [f2fs-dev] " patchwork-bot+f2fs
@ 2024-03-10 17:46 ` David Laight
2024-03-11 20:37 ` Jaegeuk Kim
2 siblings, 1 reply; 6+ messages in thread
From: David Laight @ 2024-03-10 17:46 UTC (permalink / raw)
To: 'Roman Smirnov', Jaegeuk Kim, Chao Yu
Cc: Sergey Shtylyov, Karina Yankevich,
linux-f2fs-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org
From: Roman Smirnov
> Sent: 05 March 2024 08:10
>
> Cast expression type to unsigned long in __count_extent_cache()
> to prevent integer overflow.
>
> Found by Linux Verification Center (linuxtesting.org) with Svace.
Another broken analysis tool :-)
> Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
> Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
> ---
> fs/f2fs/shrinker.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> index 83d6fb97dcae..bb86a06c5d5e 100644
> --- a/fs/f2fs/shrinker.c
> +++ b/fs/f2fs/shrinker.c
> @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
> {
> struct extent_tree_info *eti = &sbi->extent_tree[type];
>
> - return atomic_read(&eti->total_zombie_tree) +
> + return (unsigned long)atomic_read(&eti->total_zombie_tree) +
> atomic_read(&eti->total_ext_node);
Makes diddly-squit difference.
Both total_zombie_tree and totat_ext_node are 'int'.
If they are large enough that their sum wraps then the values
can individually wrap (to negative values).
You really don't want to cast 'int' to 'unsigned long' here
at all - implicitly or explicitly.
The cast will first promote 'int' to 'signed long'.
So a negative value will get sign extended to a very big value.
The best you can hope for is a 33bit result from wrapped 32bit
signed counters.
To get that you need to convert 'int' => 'unsigned int' => 'unsigned long'.
One way would be:
return (atomic_read(&eti->total_zombie_tree) + 0u + 0ul) +
(atomic_read(&eti->total_ext_node) + 0u);
Although changing the return type to 'unsigned int' would probably
be better.
I don't know what the values are, but if they are stats counters
then that would give a value that nicely wraps at 2^32 rather
that the strange wrap that the sum of two wrapping 32bit counters
has.
OTOH it may be that they are counts - and just can't get any where
near that big.
David
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
2024-03-10 17:46 ` David Laight
@ 2024-03-11 20:37 ` Jaegeuk Kim
2024-03-11 21:19 ` David Laight
0 siblings, 1 reply; 6+ messages in thread
From: Jaegeuk Kim @ 2024-03-11 20:37 UTC (permalink / raw)
To: David Laight
Cc: 'Roman Smirnov', Chao Yu, Sergey Shtylyov,
Karina Yankevich, linux-f2fs-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org
On 03/10, David Laight wrote:
> From: Roman Smirnov
> > Sent: 05 March 2024 08:10
> >
> > Cast expression type to unsigned long in __count_extent_cache()
> > to prevent integer overflow.
> >
> > Found by Linux Verification Center (linuxtesting.org) with Svace.
>
> Another broken analysis tool :-)
>
> > Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
> > Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
> > ---
> > fs/f2fs/shrinker.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> > index 83d6fb97dcae..bb86a06c5d5e 100644
> > --- a/fs/f2fs/shrinker.c
> > +++ b/fs/f2fs/shrinker.c
> > @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
> > {
> > struct extent_tree_info *eti = &sbi->extent_tree[type];
> >
> > - return atomic_read(&eti->total_zombie_tree) +
> > + return (unsigned long)atomic_read(&eti->total_zombie_tree) +
> > atomic_read(&eti->total_ext_node);
>
> Makes diddly-squit difference.
>
> Both total_zombie_tree and totat_ext_node are 'int'.
> If they are large enough that their sum wraps then the values
> can individually wrap (to negative values).
>
> You really don't want to cast 'int' to 'unsigned long' here
> at all - implicitly or explicitly.
> The cast will first promote 'int' to 'signed long'.
> So a negative value will get sign extended to a very big value.
I thought, since total_zombie_tree won't get overflowed theoritically, the first
cast to (unsigned long) could expand the space to cover the following
total_ext_node.
>
> The best you can hope for is a 33bit result from wrapped 32bit
> signed counters.
> To get that you need to convert 'int' => 'unsigned int' => 'unsigned long'.
> One way would be:
> return (atomic_read(&eti->total_zombie_tree) + 0u + 0ul) +
> (atomic_read(&eti->total_ext_node) + 0u);
>
> Although changing the return type to 'unsigned int' would probably
> be better.
> I don't know what the values are, but if they are stats counters
> then that would give a value that nicely wraps at 2^32 rather
> that the strange wrap that the sum of two wrapping 32bit counters
> has.
>
> OTOH it may be that they are counts - and just can't get any where
> near that big.
>
> David
>
> -
> Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache()
2024-03-11 20:37 ` Jaegeuk Kim
@ 2024-03-11 21:19 ` David Laight
0 siblings, 0 replies; 6+ messages in thread
From: David Laight @ 2024-03-11 21:19 UTC (permalink / raw)
To: 'Jaegeuk Kim'
Cc: 'Roman Smirnov', Chao Yu, Sergey Shtylyov,
Karina Yankevich, linux-f2fs-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org, lvc-project@linuxtesting.org
From: Jaegeuk Kim
> Sent: 11 March 2024 20:37
> On 03/10, David Laight wrote:
> > From: Roman Smirnov
> > > Sent: 05 March 2024 08:10
> > >
> > > Cast expression type to unsigned long in __count_extent_cache()
> > > to prevent integer overflow.
> > >
> > > Found by Linux Verification Center (linuxtesting.org) with Svace.
> >
> > Another broken analysis tool :-)
> >
> > > Signed-off-by: Roman Smirnov <r.smirnov@omp.ru>
> > > Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
> > > ---
> > > fs/f2fs/shrinker.c | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/fs/f2fs/shrinker.c b/fs/f2fs/shrinker.c
> > > index 83d6fb97dcae..bb86a06c5d5e 100644
> > > --- a/fs/f2fs/shrinker.c
> > > +++ b/fs/f2fs/shrinker.c
> > > @@ -33,7 +33,7 @@ static unsigned long __count_extent_cache(struct f2fs_sb_info *sbi,
> > > {
> > > struct extent_tree_info *eti = &sbi->extent_tree[type];
> > >
> > > - return atomic_read(&eti->total_zombie_tree) +
> > > + return (unsigned long)atomic_read(&eti->total_zombie_tree) +
> > > atomic_read(&eti->total_ext_node);
> >
> > Makes diddly-squit difference.
> >
> > Both total_zombie_tree and totat_ext_node are 'int'.
> > If they are large enough that their sum wraps then the values
> > can individually wrap (to negative values).
> >
> > You really don't want to cast 'int' to 'unsigned long' here
> > at all - implicitly or explicitly.
> > The cast will first promote 'int' to 'signed long'.
> > So a negative value will get sign extended to a very big value.
>
> I thought, since total_zombie_tree won't get overflowed theoritically, the first
> cast to (unsigned long) could expand the space to cover the following
> total_ext_node.
If will force the arithmetic be done as 'unsigned long' so the
second value will go through the integer promotion rules to
get from 'int' to 'unsigned long', there is an intermediate
stage of 'signed long'.
So (on 64bit) the 32bit signed value is sign extended to a
64bit signed value and the converted to 64 bit unsigned (same
bit pattern on 2s compliment systems).
The cast itself will have done the same sign extension on the
first value.
If toal_ext_node can get anywhere near 31 bits it is also likely
to get negative as well.
At which point very silly things happen is pretty much all cases
unless you only zero-extend to 64 bits.
>
> >
> > The best you can hope for is a 33bit result from wrapped 32bit
> > signed counters.
> > To get that you need to convert 'int' => 'unsigned int' => 'unsigned long'.
> > One way would be:
> > return (atomic_read(&eti->total_zombie_tree) + 0u + 0ul) +
> > (atomic_read(&eti->total_ext_node) + 0u);
> >
> > Although changing the return type to 'unsigned int' would probably
> > be better.
> > I don't know what the values are, but if they are stats counters
> > then that would give a value that nicely wraps at 2^32 rather
> > that the strange wrap that the sum of two wrapping 32bit counters
> > has.
> >
> > OTOH it may be that they are counts - and just can't get any where
> > near that big.
> >
> > David
> >
> > -
> > Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
> > Registration No: 1397386 (Wales)
-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK
Registration No: 1397386 (Wales)
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2024-03-11 21:19 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-05 8:09 [PATCH] f2fs: Cast expression type to unsigned long in __count_extent_cache() Roman Smirnov
2024-03-06 1:48 ` Chao Yu
2024-03-06 17:50 ` [f2fs-dev] " patchwork-bot+f2fs
2024-03-10 17:46 ` David Laight
2024-03-11 20:37 ` Jaegeuk Kim
2024-03-11 21:19 ` David Laight
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox