diff mbox series

net: Avoid calling WARN_ON() on -ENOMEM in __dev_change_net_namespace()

Message ID 20250328011302.743860-1-i.abramov@mt-integration.ru (mailing list archive)
State Rejected
Delegated to: Netdev Maintainers
Headers show
Series net: Avoid calling WARN_ON() on -ENOMEM in __dev_change_net_namespace() | expand

Checks

Context Check Description
netdev/series_format warning Single patches do not need cover letters; Target tree name not specified in the subject
netdev/tree_selection success Guessed tree name to be net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 518 this patch: 518
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 6 of 6 maintainers
netdev/build_clang success Errors and warnings before: 966 this patch: 966
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 15128 this patch: 15128
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 8 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 69 this patch: 69
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2025-03-28--06-00 (tests: 891)

Commit Message

Ivan Abramov March 28, 2025, 1:12 a.m. UTC
It's pointless to call WARN_ON() in case of an allocation failure in
device_rename(), since it only leads to useless splats caused by deliberate
fault injections, so avoid it.

Found by Linux Verification Center (linuxtesting.org) with Syzkaller.

Fixes: 8b41d1887db7 ("[NET]: Fix running without sysfs")
Signed-off-by: Ivan Abramov <i.abramov@mt-integration.ru>
---
 net/core/dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Kuniyuki Iwashima March 28, 2025, 2:15 a.m. UTC | #1
> Subject: [PATCH] net: Avoid calling WARN_ON() on -ENOMEM in __dev_change_net_namespace()

s/__dev_change_net_namespace/netif_change_net_namespace/

Also, please specify the target tree: [PATCH v2 net]


From: Ivan Abramov <i.abramov@mt-integration.ru>
Date: Fri, 28 Mar 2025 04:12:57 +0300
> It's pointless to call WARN_ON() in case of an allocation failure in
> device_rename(), since it only leads to useless splats caused by deliberate
> fault injections, so avoid it.
> 
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
> 
> Fixes: 8b41d1887db7 ("[NET]: Fix running without sysfs")

Reported-by: syzbot+1df6ffa7a6274ae264db@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/000000000000a45a92061ce6cc7d@google.com/


> Signed-off-by: Ivan Abramov <i.abramov@mt-integration.ru>
> ---
>  net/core/dev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 2f7f5fd9ffec..14726cc8796b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -12102,7 +12102,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,

It applies cleanly but please make sure to use the latest tree.



>  	dev_set_uevent_suppress(&dev->dev, 1);
>  	err = device_rename(&dev->dev, dev->name);
>  	dev_set_uevent_suppress(&dev->dev, 0);
> -	WARN_ON(err);
> +	WARN_ON(err && err != -ENOMEM);
>  
>  	/* Send a netdev-add uevent to the new namespace */
>  	kobject_uevent(&dev->dev.kobj, KOBJ_ADD);
> -- 
> 2.39.5
Breno Leitao March 28, 2025, 1:25 p.m. UTC | #2
Hello Ivan,

On Fri, Mar 28, 2025 at 04:12:57AM +0300, Ivan Abramov wrote:
> It's pointless to call WARN_ON() in case of an allocation failure in
> device_rename(), since it only leads to useless splats caused by deliberate
> fault injections, so avoid it.
> 
> Found by Linux Verification Center (linuxtesting.org) with Syzkaller.
> 
> Fixes: 8b41d1887db7 ("[NET]: Fix running without sysfs")
> Signed-off-by: Ivan Abramov <i.abramov@mt-integration.ru>
> ---
>  net/core/dev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/net/core/dev.c b/net/core/dev.c
> index 2f7f5fd9ffec..14726cc8796b 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -12102,7 +12102,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
>  	dev_set_uevent_suppress(&dev->dev, 1);
>  	err = device_rename(&dev->dev, dev->name);
>  	dev_set_uevent_suppress(&dev->dev, 0);
> -	WARN_ON(err);
> +	WARN_ON(err && err != -ENOMEM);


I am curious if we shouldn't skip the rest of that function if
device_rename failed. Something as:

	if (WARN_ON(err && err != -ENOMEM))
		goto out;
Eric W. Biederman March 28, 2025, 2:17 p.m. UTC | #3
Kuniyuki Iwashima <kuniyu@amazon.com> writes:

>> Subject: [PATCH] net: Avoid calling WARN_ON() on -ENOMEM in __dev_change_net_namespace()
>
> s/__dev_change_net_namespace/netif_change_net_namespace/
>
> Also, please specify the target tree: [PATCH v2 net]
>
>
> From: Ivan Abramov <i.abramov@mt-integration.ru>
> Date: Fri, 28 Mar 2025 04:12:57 +0300
>> It's pointless to call WARN_ON() in case of an allocation failure in
>> device_rename(), since it only leads to useless splats caused by deliberate
>> fault injections, so avoid it.

No.  It is not pointless.  The WARN_ON is there because the code can not
rollback if device_rename fails in
__dev_change_net_namespace/netif_change_net_namespace.

If device_rename fails it means that the kernel's device tree
are inconsistent with the actual network devices.

If anything we need a way to guarantee that the device_rename will
succeed, so that all of the parts that may fail may be performed
before we commit ourselves by notifying userspace that the device
is being renamed.

As for Breno Leitao <leitao@debian.org>'s question should we fail
immediately.  That will put us in a far worse state.

As I recall the WARN_ON exists there because someone at the last minute
stuffed network devices into sysfs, and no one has taken the time to
handle the practically impossible case of a device_rename failure.

If you are going to do something with this logic please figure out how
to handle a failure instead just shutting up the error message that
let's you know something bad is wrong in the kernel.

Eric
Ivan Abramov March 31, 2025, 9:17 a.m. UTC | #4
On Fri, 28 Mar 2025 09:17:42 -0500, Eric W. Biederman wrote:
> Kuniyuki Iwashima <kuniyu@amazon.com> writes:

>>> Subject: [PATCH] net: Avoid calling WARN_ON() on -ENOMEM in __dev_change_net_namespace()
>>
>> s/__dev_change_net_namespace/netif_change_net_namespace/
>>
>> Also, please specify the target tree: [PATCH v2 net]
>>
>>
>> From: Ivan Abramov <i.abramov@mt-integration.ru>
>> Date: Fri, 28 Mar 2025 04:12:57 +0300
>>> It's pointless to call WARN_ON() in case of an allocation failure in
>>> device_rename(), since it only leads to useless splats caused by deliberate
>>> fault injections, so avoid it.

> No.  It is not pointless.  The WARN_ON is there because the code can not
> rollback if device_rename fails in
> __dev_change_net_namespace/netif_change_net_namespace.

It's pointless in the sense that failure to allocate a few hundred bytes is
practically impossible and can only happen due to deliberate fault
injection during testing/fuzzing. The proposition is to avoid just that,
not to remove WARN_ON() altogether.

> If device_rename fails it means that the kernel's device tree
> are inconsistent with the actual network devices.

> If anything we need a way to guarantee that the device_rename will
> succeed, so that all of the parts that may fail may be performed
> before we commit ourselves by notifying userspace that the device
> is being renamed.
 
> As for Breno Leitao <leitao@debian.org>'s question should we fail
> immediately.  That will put us in a far worse state.

> As I recall the WARN_ON exists there because someone at the last minute
> stuffed network devices into sysfs, and no one has taken the time to
> handle the practically impossible case of a device_rename failure.

> If you are going to do something with this logic please figure out how
> to handle a failure instead just shutting up the error message that
> let's you know something bad is wrong in the kernel.

Although the issue of properly handling failure of device_rename deserves
a good thought and another patch/series, it's a much bigger problem to
solve, compared to what I try to achieve here.

> Eric

Thank you for detailed response!
diff mbox series

Patch

diff --git a/net/core/dev.c b/net/core/dev.c
index 2f7f5fd9ffec..14726cc8796b 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -12102,7 +12102,7 @@  int __dev_change_net_namespace(struct net_device *dev, struct net *net,
 	dev_set_uevent_suppress(&dev->dev, 1);
 	err = device_rename(&dev->dev, dev->name);
 	dev_set_uevent_suppress(&dev->dev, 0);
-	WARN_ON(err);
+	WARN_ON(err && err != -ENOMEM);
 
 	/* Send a netdev-add uevent to the new namespace */
 	kobject_uevent(&dev->dev.kobj, KOBJ_ADD);