diff mbox series

net: fix potential refcount leak in ndisc_router_discovery()

Message ID 20220813124907.3396-1-xiongx18@fudan.edu.cn (mailing list archive)
State Accepted
Commit 7396ba87f1edf549284869451665c7c4e74ecd4f
Delegated to: Netdev Maintainers
Headers show
Series net: fix potential refcount leak in ndisc_router_discovery() | expand

Checks

Context Check Description
netdev/tree_selection success Guessed tree name to be net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cover_letter success Single patches do not need cover letters
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 86 this patch: 86
netdev/cc_maintainers success CCed 9 of 9 maintainers
netdev/build_clang success Errors and warnings before: 0 this patch: 0
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
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: 85 this patch: 85
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 9 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Xin Xiong Aug. 13, 2022, 12:49 p.m. UTC
The issue happens on specific paths in the function. After both the
object `rt` and `neigh` are grabbed successfully, when `lifetime` is
nonzero but the metric needs change, the function just deletes the
route and set `rt` to NULL. Then, it may try grabbing `rt` and `neigh`
again if above conditions hold. The function simply overwrite `neigh`
if succeeds or returns if fails, without decreasing the reference
count of previous `neigh`. This may result in memory leaks.

Fix it by decrementing the reference count of `neigh` in place.

Fixes: 6b2e04bc240f ("net: allow user to set metric on default route learned via Router Advertisement")
Signed-off-by: Xin Xiong <xiongx18@fudan.edu.cn>
Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
---
 net/ipv6/ndisc.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

patchwork-bot+netdevbpf@kernel.org Aug. 15, 2022, 10:50 a.m. UTC | #1
Hello:

This patch was applied to netdev/net.git (master)
by David S. Miller <davem@davemloft.net>:

On Sat, 13 Aug 2022 20:49:08 +0800 you wrote:
> The issue happens on specific paths in the function. After both the
> object `rt` and `neigh` are grabbed successfully, when `lifetime` is
> nonzero but the metric needs change, the function just deletes the
> route and set `rt` to NULL. Then, it may try grabbing `rt` and `neigh`
> again if above conditions hold. The function simply overwrite `neigh`
> if succeeds or returns if fails, without decreasing the reference
> count of previous `neigh`. This may result in memory leaks.
> 
> [...]

Here is the summary with links:
  - net: fix potential refcount leak in ndisc_router_discovery()
    https://git.kernel.org/netdev/net/c/7396ba87f1ed

You are awesome, thank you!
Praveen Chaudhary Aug. 15, 2022, 6:03 p.m. UTC | #2
Hi Xin

Any reason why you are not adding this code under the
if (rt && (lifetime == 0 || rt->fib6_metric != defrtr_usr_metric))  block ?

i.e. while route deletion.
diff mbox series

Patch

diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 98453693e400..3a553494ff16 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1378,6 +1378,9 @@  static void ndisc_router_discovery(struct sk_buff *skb)
 	if (!rt && lifetime) {
 		ND_PRINTK(3, info, "RA: adding default router\n");
 
+		if (neigh)
+			neigh_release(neigh);
+
 		rt = rt6_add_dflt_router(net, &ipv6_hdr(skb)->saddr,
 					 skb->dev, pref, defrtr_usr_metric);
 		if (!rt) {