forked from mirrors/linux
		
	net-sysfs: Fix reference count leak in rx|netdev_queue_add_kobject
kobject_init_and_add takes reference even when it fails. This has
to be given up by the caller in error handling. Otherwise memory
allocated by kobject_init_and_add is never freed. Originally found
by Syzkaller:
BUG: memory leak
unreferenced object 0xffff8880679f8b08 (size 8):
  comm "netdev_register", pid 269, jiffies 4294693094 (age 12.132s)
  hex dump (first 8 bytes):
    72 78 2d 30 00 36 20 d4                          rx-0.6 .
  backtrace:
    [<000000008c93818e>] __kmalloc_track_caller+0x16e/0x290
    [<000000001f2e4e49>] kvasprintf+0xb1/0x140
    [<000000007f313394>] kvasprintf_const+0x56/0x160
    [<00000000aeca11c8>] kobject_set_name_vargs+0x5b/0x140
    [<0000000073a0367c>] kobject_init_and_add+0xd8/0x170
    [<0000000088838e4b>] net_rx_queue_update_kobjects+0x152/0x560
    [<000000006be5f104>] netdev_register_kobject+0x210/0x380
    [<00000000e31dab9d>] register_netdevice+0xa1b/0xf00
    [<00000000f68b2465>] __tun_chr_ioctl+0x20d5/0x3dd0
    [<000000004c50599f>] tun_chr_ioctl+0x2f/0x40
    [<00000000bbd4c317>] do_vfs_ioctl+0x1c7/0x1510
    [<00000000d4c59e8f>] ksys_ioctl+0x99/0xb0
    [<00000000946aea81>] __x64_sys_ioctl+0x78/0xb0
    [<0000000038d946e5>] do_syscall_64+0x16f/0x580
    [<00000000e0aa5d8f>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
    [<00000000285b3d1a>] 0xffffffffffffffff
Cc: David Miller <davem@davemloft.net>
Cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Signed-off-by: Jouni Hogander <jouni.hogander@unikie.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									6e4ff1c94a
								
							
						
					
					
						commit
						b8eb718348
					
				
					 1 changed files with 13 additions and 11 deletions
				
			
		|  | @ -923,21 +923,23 @@ static int rx_queue_add_kobject(struct net_device *dev, int index) | |||
| 	error = kobject_init_and_add(kobj, &rx_queue_ktype, NULL, | ||||
| 				     "rx-%u", index); | ||||
| 	if (error) | ||||
| 		return error; | ||||
| 		goto err; | ||||
| 
 | ||||
| 	dev_hold(queue->dev); | ||||
| 
 | ||||
| 	if (dev->sysfs_rx_queue_group) { | ||||
| 		error = sysfs_create_group(kobj, dev->sysfs_rx_queue_group); | ||||
| 		if (error) { | ||||
| 			kobject_put(kobj); | ||||
| 			return error; | ||||
| 		} | ||||
| 		if (error) | ||||
| 			goto err; | ||||
| 	} | ||||
| 
 | ||||
| 	kobject_uevent(kobj, KOBJ_ADD); | ||||
| 
 | ||||
| 	return error; | ||||
| 
 | ||||
| err: | ||||
| 	kobject_put(kobj); | ||||
| 	return error; | ||||
| } | ||||
| #endif /* CONFIG_SYSFS */ | ||||
| 
 | ||||
|  | @ -1461,21 +1463,21 @@ static int netdev_queue_add_kobject(struct net_device *dev, int index) | |||
| 	error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL, | ||||
| 				     "tx-%u", index); | ||||
| 	if (error) | ||||
| 		return error; | ||||
| 		goto err; | ||||
| 
 | ||||
| 	dev_hold(queue->dev); | ||||
| 
 | ||||
| #ifdef CONFIG_BQL | ||||
| 	error = sysfs_create_group(kobj, &dql_group); | ||||
| 	if (error) { | ||||
| 		kobject_put(kobj); | ||||
| 		return error; | ||||
| 	} | ||||
| 	if (error) | ||||
| 		goto err; | ||||
| #endif | ||||
| 
 | ||||
| 	kobject_uevent(kobj, KOBJ_ADD); | ||||
| 
 | ||||
| 	return 0; | ||||
| err: | ||||
| 	kobject_put(kobj); | ||||
| 	return error; | ||||
| } | ||||
| #endif /* CONFIG_SYSFS */ | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jouni Hogander
						Jouni Hogander