Re: 12.0-BETA1 vnet with pf firewall

From: Kristof Provost <kp_at_FreeBSD.org>
Date: Sun, 28 Oct 2018 20:41:42 -0700
On 28 Oct 2018, at 14:39, Rodney W. Grimes wrote:
>> Bjoern A. Zeeb wrote:
>>> On 28 Oct 2018, at 15:31, Ernie Luzar wrote:
>>>
>>>> Tested with host running ipfilter and vnet running pf. Tried 
>>>> loading
>>>> pf from host console or from vnet console using kldload pf.ko 
>>>> command
>>>> and get this error message;
>>>>
>>>> linker_load_file: /boot/kernel/pf.ko-unsupported file type.
>>>>
>>>> Looks like the 12.0 version of pf which is suppose to work in vnet
>>>> independent of what firewall is running on the host is not working.
>>>
>>> You cannot load pf from inside a jail (with or without vnet).  
>>> Kernel
>>> modules are global objects loaded from the base system or you 
>>> compile
>>> the devices into the kernel;  it is their state which is 
>>> virtualised.
>>>
>>> If you load multiple firewalls they will all be available to the 
>>> base
>>> system and all jails+vnet.  Whichever you configure in which one is 
>>> up
>>> to you.  Just be careful as an unconfigured firewall might have a
>>> default action affecting the outcome of the overall decision.
>>>
>>> For example you could have:
>>>
>>> a base system using ipfilter and setting pf to default accept 
>>> everything
>>> and a jail+vnet using pf and setting ipfilter there to accept 
>>> everything.
>>>
>>>
>>> Hope that clarifies some things.
>>>
>>> /bz
>>>
>>
>> Hello Bjoern.
>>
>> What you said is correct for 10.x & 11.x. But I an talking about
>> 12.0-beta1.  I have the ipfilter options enabled in rc.conf of the 
>> host
>> and on boot ipfilter starts just like it all ways does. Now to prep 
>> the
>> host for pf in a vnet jail, I issue from the host console the
>> "kldload pf.ko" command and get this error message;
>>
>> linker_load_file: /boot/kernel/pf.ko-unsupported file type.
>>
>> Something is wrong here. This is not suppose to happen according to 
>> your
>> post above.
>>
>> Remember that in 12.0 vimage is included in the base system kernel.
>
> Confirmed, if I boot a clean install and issue:
> 	kldload ipfilter.ko
> 	kldload pf.ko
> my dmesg has:
> IP Filter: v5.1.2 initialized.  Default = pass all, Logging = enabled
> linker_load_file: /boot/kernel/pf.ko - unsupported file type
>
Yeah, something’s very, very broken somewhere.

On head loading both pf and ipfilter panics:

	Fatal trap 12: page fault while in kernel mode
	cpuid = 5; apic id = 05
	fault virtual address   = 0x0
	fault code              = supervisor read data, page not present
	instruction pointer     = 0x20:0xffffffff80c8a1d0
	stack pointer           = 0x28:0xfffffe0088955340
	frame pointer           = 0x28:0xfffffe0088955340
	code segment            = base 0x0, limit 0xfffff, type 0x1b
	                        = DPL 0, pres 1, long 1, def32 0, gran 1
	processor eflags        = interrupt enabled, resume, IOPL = 0
	current process         = 940 (kldload)
	[ thread pid 940 tid 100473 ]
	Stopped at      strncmp+0x10:   movzbl  (%rdi,%rcx,1),%r8d
	db> bt
	Tracing pid 940 tid 100473 td 0xfffff80007599000
	strncmp() at strncmp+0x10/frame 0xfffffe0088955340
	link_elf_lookup_set() at link_elf_lookup_set+0x64/frame 
0xfffffe0088955390
	sdt_kld_unload_try() at sdt_kld_unload_try+0x39/frame 
0xfffffe00889553d0
	linker_file_unload() at linker_file_unload+0xeb/frame 
0xfffffe0088955430
	link_elf_load_file() at link_elf_load_file+0x152/frame 
0xfffffe00889554f0
	linker_load_module() at linker_load_module+0x97a/frame 
0xfffffe0088955800
	kern_kldload() at kern_kldload+0xf1/frame 0xfffffe0088955850
	sys_kldload() at sys_kldload+0x5b/frame 0xfffffe0088955880
	amd64_syscall() at amd64_syscall+0x278/frame 0xfffffe00889559b0
	fast_syscall_common() at fast_syscall_common+0x101/frame 
0xfffffe00889559b0
	--- syscall (304, FreeBSD ELF64, sys_kldload), rip = 0x8002d2f7a, rsp = 
0x7fffffffe588, rbp = 0x7fffffffeb00 ---

While I’d recommend very strongly against trying to mix firewalls we 
obviously shouldn’t panic.

This doesn’t appear to be specifically either firewalls fault though, 
as the panic happens during the linking of the module, not 
initialisation of the firewall. Also, it happens regardless of load 
order (so ipfilter first or pf first).

	(kgdb) bt
	#0  __curthread () at ./machine/pcpu.h:230
	#1  doadump (textdump=0) at /usr/src/sys/kern/kern_shutdown.c:366
	#2  0xffffffff8046576b in db_dump (dummy=<optimized out>, 
dummy2=<unavailable>, dummy3=<unavailable>, dummy4=<unavailable>) at 
/usr/src/sys/ddb/db_command.c:574
	#3  0xffffffff80465539 in db_command (last_cmdp=<optimized out>, 
cmd_table=<optimized out>, dopager=<optimized out>) at 
/usr/src/sys/ddb/db_command.c:481
	#4  0xffffffff804652b4 in db_command_loop () at 
/usr/src/sys/ddb/db_command.c:534
	#5  0xffffffff804684cf in db_trap (type=<optimized out>, 
code=<optimized out>) at /usr/src/sys/ddb/db_main.c:252
	#6  0xffffffff80be71c7 in kdb_trap (type=12, code=0, 
tf=0xfffffe0088955280) at /usr/src/sys/kern/subr_kdb.c:693
	#7  0xffffffff81073f51 in trap_fatal (frame=0xfffffe0088955280, eva=0) 
at /usr/src/sys/amd64/amd64/trap.c:921
	#8  0xffffffff81074072 in trap_pfault (frame=0xfffffe0088955280, 
usermode=<optimized out>) at /usr/src/sys/amd64/amd64/trap.c:765
	#9  0xffffffff8107369a in trap (frame=0xfffffe0088955280) at 
/usr/src/sys/amd64/amd64/trap.c:441
	#10 <signal handler called>
	#11 strncmp (s1=0x0, s2=0xffffffff812b970d "set_", n=4) at 
/usr/src/sys/libkern/strncmp.c:44
	#12 0xffffffff811ade34 in link_elf_lookup_set (lf=0xfffff8000dc43a00, 
name=0xffffffff82fcaca2 "sdt_providers_set", startp=0xfffffe00889553a0, 
stopp=0xfffffe00889553a8,
	    countp=0x0) at /usr/src/sys/kern/link_elf_obj.c:1285
	#13 0xffffffff82fca5f9 in sdt_kld_unload_try (arg=<optimized out>, 
lf=0xfffff8000dc43800, error=0xfffffe0088955404) at 
/usr/src/sys/cddl/dev/sdt/sdt.c:321
	#14 0xffffffff80b6f3bb in linker_file_unload (file=0xfffff8000dc43a00, 
flags=1) at /usr/src/sys/kern/kern_linker.c:656
	#15 0xffffffff811ac382 in link_elf_load_file (cls=<optimized out>, 
filename=<optimized out>, result=<optimized out>) at 
/usr/src/sys/kern/link_elf_obj.c:1016
	#16 0xffffffff80b6ecca in LINKER_LOAD_FILE (cls=0xffffffff81b817c0 
<link_elf_class>, result=0x0, filename=<optimized out>) at 
./linker_if.h:180
	#17 linker_load_file (filename=<optimized out>, result=<optimized out>) 
at /usr/src/sys/kern/kern_linker.c:447
	#18 linker_load_module (kldname=<optimized out>, 
modname=0xfffff8000d141c00 "ipfilter", parent=0x0, verinfo=<optimized 
out>, lfpp=0xfffffe0088955818)
	    at /usr/src/sys/kern/kern_linker.c:2110
	#19 0xffffffff80b70661 in kern_kldload (td=<optimized out>, 
file=<optimized out>, fileid=0xfffffe0088955864) at 
/usr/src/sys/kern/kern_linker.c:1089
	#20 0xffffffff80b7078b in sys_kldload (td=0xfffff80007599000, 
uap=<optimized out>) at /usr/src/sys/kern/kern_linker.c:1115
	#21 0xffffffff81074b28 in syscallenter (td=0xfffff80007599000) at 
/usr/src/sys/amd64/amd64/../../kern/subr_syscall.c:135
	#22 amd64_syscall (td=0xfffff80007599000, traced=0) at 
/usr/src/sys/amd64/amd64/trap.c:1154
	#23 <signal handler called>
	#24 0x00000008002d2f7a in ?? ()
	Backtrace stopped: Cannot access memory at address 0x7fffffffe588
	(kgdb) fr 12
	#12 0xffffffff811ade34 in link_elf_lookup_set (lf=0xfffff8000dc43a00, 
name=0xffffffff82fcaca2 "sdt_providers_set", startp=0xfffffe00889553a0, 
stopp=0xfffffe00889553a8,
	    countp=0x0) at /usr/src/sys/kern/link_elf_obj.c:1285
	1285                    if ((strncmp(ef->progtab[i].name, "set_", 4) == 
0) &&
	(kgdb) p *ef
	$1 = {lf = {ops = 0xfffff800040fb000, refs = 1, userrefs = 0, flags = 
0, link = {tqe_next = 0x0, tqe_prev = 0xfffff8004b37e418}, filename = 
0xfffff8000df9d120 "ipl.ko",
	    pathname = 0xfffff8000df9f2a0 "/boot/kernel/ipl.ko", id = 17,
	    address = 0xffffffff83646000 <sysctl_ipf_int> 
"UH\211\345AWAVSPH\211\313I\211\366I\211\377H\211U\340H\213C(M\205\366t\r\272\004", 
size = 445056, ctors_addr = 0x0,
	    ctors_size = 0, ndeps = 0, deps = 0x0, common = {stqh_first = 0x0, 
stqh_last = 0xfffff8000dc43a70}, modules = {tqh_first = 0x0, tqh_last = 
0xfffff8000dc43a80}, loaded = {
	      tqe_next = 0x0, tqe_prev = 0x0}, loadcnt = 17, nenabled = 0, 
fbt_nentries = 0}, preloaded = 0,
	  address = 0xffffffff83646000 <sysctl_ipf_int> 
"UH\211\345AWAVSPH\211\313I\211\366I\211\377H\211U\340H\213C(M\205\366t\r\272\004", 
object = 0xfffff800399ec500,
	  e_shdr = 0xfffff8004b45d800, progtab = 0xfffff8000dc43800, nprogtab = 
13, relatab = 0xfffff80015413b00, nrelatab = 9, reltab = 0x0, nreltab = 
0,
	  ddbsymtab = 0xfffffe0090374000, ddbsymcnt = 3446, ddbstrtab = 
0xfffffe00903c9000 "", ddbstrcnt = 161248, shstrtab = 0xfffff8000dc43600 
"", shstrcnt = 297, ctftab = 0x0,
	  ctfcnt = 0, ctfoff = 0x0, typoff = 0x0, typlen = 0}
	(kgdb) p i
	$2 = 12
	(kgdb) p *ef->progtab
	$3 = {addr = 0xffffffff83646000 <sysctl_ipf_int>, size = 300898, flags 
= 0, sec = 1, name = 0xfffff8000dc43620 ".text"}
	(kgdb) p ef->progtab[12]
	$4 = {addr = 0x0, size = 0, flags = 0, sec = 0, name = 0x0}
	(kgdb)

So we panic because we dereference a NULL pointer in strncmp(), which 
happens because nprogtab = 13 but ef->progtab[12] has NULL pointers.

It’s not clear to me why that happens, but it’s something to go on. 
I do wonder if this isn’t a bit of a red herring too. It might be an 
error in the error path (because we pass through linker_file_unload()). 
link_elf_load_file() increments ef->nprogtab for SHT_X86_64_UNWIND, so 
perhaps the error handling doesn’t cope with that.

(I likely won’t be able to look at this further in the next day or 
two. I’m flying home from MeetBSD.)

Best regards,
Kristof
Received on Mon Oct 29 2018 - 02:41:49 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:41:19 UTC