Bug 174236 - [modules] "kldunload ipdivert" corrupts kernel
Summary: [modules] "kldunload ipdivert" corrupts kernel
Status: Closed Feedback Timeout
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 8.3-RELEASE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-12-06 15:00 UTC by Lutz Donnerhacke
Modified: 2017-03-07 23:42 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lutz Donnerhacke freebsd_committer freebsd_triage 2012-12-06 15:00:00 UTC
After unsuccessful kldunload of ipdivert.ko, all kernel module maintainence operations block.

Fix: 

Reboot
How-To-Repeat: Reboot the server to a fresh state. In short:
 # kldload ipfw
 # kldload ipdivert
 # kldunload ipdivert
 # kldstat
 {hangs]

And now the glory details:

[root@server6 ~]# cat /boot/loader.conf
aacu64_load="YES"
if_lagg_load="YES"
net.inet.ip.fw.default_to_accept=1
ipfw_load="YES"
ipfw_nat_load="YES"

[root@server6 ~]# grep firewall /etc/rc.conf
firewall_enable="YES"
firewall_type="/etc/firewall.rules"

[root@server6 ~]# cat /etc/firewall.rules
-f flush
# defining NAT pools
nat 128 config ip x.y.z.128 log same_ports
[... same up to ...]
nat 159 config ip x.y.z.159 log same_ports
# active ruleset
add   10 deny log ip4 from any to any not verrevpath in
add 1128 nat 128 ipv4 from 100.64.0.0:255.192.0.31 to any out
[... same up to ...]
add 1159 nat 159 ipv4 from 100.64.0.31:255.192.0.31 to any out
add 2128 nat 128 ip4 from any to x.y.z.128
[... same up to ...]
add 2159 nat 159 ip4 from any to x.y.z.159
# Diverting dhpcv6 in future
# add 9000 divert 12345 ipv6 from fe80::/16 to ff02::1:2 via ng* in
# Allow everything
add 9999 allow all from any to any

[root@server6 ~]# kldstat
Id Refs Address            Size     Name
 1   34 0xffffffff80100000 e56d68   kernel
 2    2 0xffffffff80f57000 1a3e0    ipfw.ko
 3    1 0xffffffff80f72000 192b0    aacu64.ko
 4    1 0xffffffff80f8c000 c470     if_lagg.ko
 5    1 0xffffffff80f99000 4088     ipfw_nat.ko
 6    2 0xffffffff80f9e000 14320    libalias.ko
 7    1 0xffffffff81012000 1e2c     ng_socket.ko
 8    7 0xffffffff81014000 8d38     netgraph.ko
 9    1 0xffffffff8101d000 186a     ng_mppc.ko
10    1 0xffffffff8101f000 28c      rc4.ko
11    1 0xffffffff81020000 2a08     ng_l2tp.ko
12    1 0xffffffff81023000 2080     ng_ksocket.ko
13    1 0xffffffff81026000 aa8      ng_tee.ko
14    1 0xffffffff81027000 13b0     ng_iface.ko
15    1 0xffffffff81029000 45e8     ng_ppp.ko
[root@server6 ~]# kldload ipdivert
[root@server6 ~]# kldstat
Id Refs Address            Size     Name
 1   36 0xffffffff80100000 e56d68   kernel
 2    3 0xffffffff80f57000 1a3e0    ipfw.ko
 3    1 0xffffffff80f72000 192b0    aacu64.ko
 4    1 0xffffffff80f8c000 c470     if_lagg.ko
 5    1 0xffffffff80f99000 4088     ipfw_nat.ko
 6    2 0xffffffff80f9e000 14320    libalias.ko
 7    1 0xffffffff81012000 1e2c     ng_socket.ko
 8    7 0xffffffff81014000 8d38     netgraph.ko
 9    1 0xffffffff8101d000 186a     ng_mppc.ko
10    1 0xffffffff8101f000 28c      rc4.ko
11    1 0xffffffff81020000 2a08     ng_l2tp.ko
12    1 0xffffffff81023000 2080     ng_ksocket.ko
13    1 0xffffffff81026000 aa8      ng_tee.ko
14    1 0xffffffff81027000 13b0     ng_iface.ko
15    1 0xffffffff81029000 45e8     ng_ppp.ko
16    1 0xffffffff8102e000 1649     ipdivert.ko
[root@server6 ~]# kldunload ipdivert
kldunload: can't unload file: Operation not permitted
[root@server6 ~]# kldstat
Id Refs Address            Size     Name
[hangs]
<CTRL+T>
load: 0.00  cmd: kldstat 15366 [kernel linker] 98.04r 0.00u 0.00s 0% 1052k


Logging into the maschine again again.
[root@server6 ~]# ps ax | grep 1536[6]
15366   0  T+     0:00.00 kldstat
[root@server6 ~]# procstat -k 15366
  PID    TID COMM             TDNAME           KSTACK
[hangs]

Even "procstat"ing the hanging procstat hangs.
Comment 1 Lutz Donnerhacke freebsd_committer freebsd_triage 2012-12-07 14:45:00 UTC
Any module which returns an error on unload will cause the problem.
It's not specific to ipdivert.ko or ipfw.ko or anything else.

Relevant code section is:

static int
div_modevent(module_t mod, int type, void *unused)
{
        int err = 0;
        switch (type) {
	[...]
        case MOD_QUIESCE:
		err = EPERM;
		break;
	[...]
	}
        return err;
}

Please note: Forced unload of ipdivert.ko works fine.
Comment 2 Eitan Adler freebsd_committer freebsd_triage 2012-12-07 18:42:29 UTC
On 7 December 2012 09:50, Lutz Donnerhacke <lutz@donnerhacke.de> wrote:
> The following reply was made to PR kern/174236; it has been noted by GNATS.
>
> From: Lutz Donnerhacke <lutz@donnerhacke.de>
> To: bug-followup@FreeBSD.org
> Cc:
> Subject: Re: kern/174236: "kldunload ipdivert" corrupts kernel
> Date: Fri, 7 Dec 2012 15:45:00 +0100
>
>  Any module which returns an error on unload will cause the problem.
>  It's not specific to ipdivert.ko or ipfw.ko or anything else.
>
>  Relevant code section is:
>
>  static int
>  div_modevent(module_t mod, int type, void *unused)
>  {
>          int err = 0;
>          switch (type) {
>         [...]
>          case MOD_QUIESCE:
>                 err = EPERM;
>                 break;
>         [...]
>         }
>          return err;
>  }
>
>  Please note: Forced unload of ipdivert.ko works fine.

If you are able and willing to debug:

<avg> I'd recommend him to enter debugger and run ps there
<avg> and get backtraces of the hanging threads
<dwhite-> it sounds like a leaked lock in the error case

If not, just leaving this here for the record ;)


-- 
Eitan Adler
Comment 3 Lutz Donnerhacke freebsd_committer freebsd_triage 2017-03-07 23:42:04 UTC
Situation does not occur any more.
Time changed.