Kernel ignores RTAX_IFP if an exact RTAX_IFA match is found

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Kernel ignores RTAX_IFP if an exact RTAX_IFA match is found

Demi M. Obenour
>Synopsis: Kernel ignores RTAX_IFP if an exact RTAX_IFA match is found
>Category: kernel
>Environment:
        System      : OpenBSD 6.8
        Details     : OpenBSD 6.8-beta (GENERIC.MP) #64: Sun Sep  6 18:19:41 MDT 2020
                         [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP

        Architecture: OpenBSD.amd64
        Machine     : amd64
>Description:
        If an RTM_ADD command on a routing socket includes an RTA_IFA sockaddr,
        and that sockaddr is an exact match for one of the interfaces in the
        relevant routing domain, the RTA_IFP sockaddr is ignored.  If there are
        multiple interfaces with the same IP address, this can cause packets to
        be sent out the wrong interface.

        I expected that an RTA_IFP sockaddr will always be honored.  That is,
        the route will always use the interface supplied, regardless of what the
        other sockaddrs in the message are.  If the kernel is not able to ensure
        this, it should return an error.
>How-To-Repeat:
        Run these commands as root on a machine where vether0 and vether1 do not
        exist, and on which the subnet 192.0.2.0/24 (reserved for documentation)
        is not in use:

        # ifconfig vether0 destroy 2>/dev/null
        # ifconfig vether1 destroy 2>/dev/null
        # dummy_mac=fe:ff:ff:ff:ff:ff dummy_ip=192.0.2.5
        # ifconfig vether0 create lladdr "$dummy_mac"
        # ifconfig vether1 create lladdr "$dummy_mac"
        # ifconfig vether0 inet "$dummy_ip" prefixlen 32
        # route -n delete "$dummy_ip/32" "$dummy_ip"
        # ifconfig vether1 inet "$dummy_ip" prefixlen 32
        # route -n delete "$dummy_ip/32" "$dummy_ip"
        # route -n add -inet 192.0.2.6 -static -iface -llinfo -link vether1 -ifp vether1 -inet -ifa "$dummy_ip"
        # route -n show -inet

        The last route command will show that the route to 192.0.2.6 goes
        through vether0, even though vether1 was specifically requested.
>Fix:
        Apply the following patch to the kernel, rebuild and install a new
        kernel, and reboot the system.

From 5bad996c7301378405b141a8e4c72dab9f8601b8 Mon Sep 17 00:00:00 2001
From: "Demi M. Obenour" <[hidden email]>
Date: Thu, 10 Sep 2020 16:01:33 -0400
Subject: [PATCH] rtm_getifa: check requested interface exists

If userspace passes an RTAX_IFP sockaddr, but the interface
requested by that sockaddr did not exist, it would be silently ignored.
This would result in packets being incorrectly routed.  This change makes
write() fail with ENXIO instead.  Furthermore, panic if the kernel chooses a
route that leads to an interface that differs from what the user requested.
---
 sys/net/rtsock.c | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index fa84ddc25e5..dc8446bd78f 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -1235,7 +1235,8 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
  struct sockaddr_dl *sdl;
 
  sdl = satosdl(info->rti_info[RTAX_IFP]);
- ifp = if_get(sdl->sdl_index);
+ if ((ifp = if_get(sdl->sdl_index)) == NULL)
+ return (ENXIO);
  }
 
 #ifdef IPSEC
@@ -1246,11 +1247,19 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
  * enc0.
  */
  if (info->rti_info[RTAX_DST] &&
-    info->rti_info[RTAX_DST]->sa_family == PF_KEY)
+    info->rti_info[RTAX_DST]->sa_family == PF_KEY) {
  info->rti_ifa = enc_getifa(rtid, 0);
+
+ if (info->rti_ifa != NULL && ifp != NULL &&
+    ifp != info->rti_ifa->ifa_ifp) {
+ if_put(ifp);
+ return (EINVAL);
+ }
+ }
 #endif
 
- if (info->rti_ifa == NULL && info->rti_info[RTAX_IFA] != NULL)
+ if (info->rti_ifa == NULL && ifp == NULL &&
+    info->rti_info[RTAX_IFA] != NULL)
  info->rti_ifa = ifa_ifwithaddr(info->rti_info[RTAX_IFA], rtid);
 
  if (info->rti_ifa == NULL) {
@@ -1273,10 +1282,15 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid)
     sa, sa, rtid);
  }
 
- if_put(ifp);
-
- if (info->rti_ifa == NULL)
+ if (info->rti_ifa == NULL) {
+ if_put(ifp);
  return (ENETUNREACH);
+ }
+
+ if (ifp != NULL && ifp != info->rti_ifa->ifa_ifp)
+ panic("rtm_getifa: returned route to wrong interface");
+
+ if_put(ifp);
 
  return (0);
 }
--
2.26.2

dmesg:
OpenBSD 6.8-beta (GENERIC.MP) #64: Sun Sep  6 18:19:41 MDT 2020
    [hidden email]:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 385871872 (367MB)
avail mem = 359223296 (342MB)
random: good seed from bootblocks
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.4 @ 0xfc001000 (12 entries)
bios0: vendor Xen version "4.8.5-22.fc25" date 08/15/2020
bios0: Xen HVM domU
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S3 S4 S5
acpi0: tables DSDT FACP APIC HPET WAET SSDT SSDT
acpi0: wakeup devices
acpitimer0 at acpi0: 3579545 Hz, 32 bits
acpimadt0 at acpi0 addr 0xfee00000: PC-AT compat
ioapic0 at mainbus0: apid 1 pa 0xfec00000, version 11, 48 pins, remapped
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz, 2808.43 MHz, 06-9e-09
cpu0: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,ACPI,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,SSSE3,FMA3,CX16,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,HV,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,CLFLUSHOPT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu0: 256KB 64b/line 8-way L2 cache
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 100MHz
cpu1 at mainbus0: apid 2 (application processor)
cpu1: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz, 2808.10 MHz, 06-9e-09
cpu1: FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,ACPI,MMX,FXSR,SSE,SSE2,HTT,SSE3,PCLMUL,SSSE3,FMA3,CX16,PCID,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,DEADLINE,AES,XSAVE,AVX,F16C,RDRAND,HV,NXE,PAGE1GB,RDTSCP,LONG,LAHF,ABM,3DNOWP,FSGSBASE,TSC_ADJUST,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,MPX,RDSEED,ADX,CLFLUSHOPT,MD_CLEAR,IBRS,IBPB,STIBP,L1DF,SSBD,XSAVEOPT,XSAVEC,XGETBV1,XSAVES,MELTDOWN
cpu1: 256KB 64b/line 8-way L2 cache
cpu1: smt 0, core 1, package 0
acpihpet0 at acpi0: 62500000 Hz
acpiprt0 at acpi0: bus 0 (PCI0)
acpipci0 at acpi0 PCI0
extent `acpipci0 pcibus' (0x0 - 0xff), flags=0
extent `pciio' (0x0 - 0xffffffff), flags=0
     0x10000 - 0xffffffff
extent `pcimem' (0x0 - 0xffffffffffffffff), flags=0
     0x0 - 0x17ffffff
     0xfc000000 - 0xffffffff
     0x40000000000 - 0xffffffffffffffff
acpicmos0 at acpi0
acpicpu0 at acpi0: C1(@1 halt!)
acpicpu1 at acpi0: C1(@1 halt!)
cpu0: using VERW MDS workaround (except on vmm entry)
pvbus0 at mainbus0: Xen 4.8
xen0 at pvbus0: features 0x2705, 32 grant table frames, event channel 1
xbf0 at xen0 backend 0 channel 6: disk
scsibus1 at xbf0: 1 targets
sd0 at scsibus1 targ 0 lun 0: <Xen, phy xvda 51712, 0000>
sd0: 10240MB, 512 bytes/sector, 20971520 sectors
xbf1 at xen0 backend 0 channel 7: disk
scsibus2 at xbf1: 1 targets
sd1 at scsibus2 targ 0 lun 0: <Xen, phy xvdb 51728, 0000>
sd1: 10240MB, 512 bytes/sector, 20971520 sectors
xbf2 at xen0 backend 0 channel 8: disk
scsibus3 at xbf2: 1 targets
sd2 at scsibus3 targ 0 lun 0: <Xen, phy xvdc 51744, 0000>
sd2: 10240MB, 512 bytes/sector, 20971520 sectors
xnf0 at xen0 backend 30 channel 9: address 00:16:3e:5e:6c:00
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82441FX" rev 0x02
pcib0 at pci0 dev 1 function 0 "Intel 82371SB ISA" rev 0x00
pciide0 at pci0 dev 1 function 1 "Intel 82371SB IDE" rev 0x00: DMA, channel 0 wired to compatibility, channel 1 wired to compatibility
pciide0: channel 0 disabled (no drives)
pciide0: channel 1 disabled (no drives)
piixpm0 at pci0 dev 1 function 3 "Intel 82371AB Power" rev 0x03: SMBus disabled
xspd0 at pci0 dev 2 function 0 "XenSource Platform Device" rev 0x01
vga1 at pci0 dev 3 function 0 "Bochs VGA" rev 0x02
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
ehci0 at pci0 dev 4 function 0 "Intel 82801DB USB" rev 0x10: apic 1 int 35
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 configuration 1 interface 0 "Intel EHCI root hub" rev 2.00/1.00 addr 1
isa0 at pcib0
isadma0 at isa0
fdc0 at isa0 port 0x3f0/6 irq 6 drq 2
pckbc0 at isa0 port 0x60/5 irq 1 irq 12
pckbd0 at pckbc0 (kbd slot)
wskbd0 at pckbd0: console keyboard, using wsdisplay0
pms0 at pckbc0 (aux slot)
wsmouse0 at pms0 mux 0
pcppi0 at isa0 port 0x61
spkr0 at pcppi0
uhidev0 at uhub0 port 1 configuration 1 interface 0 "QEMU QEMU USB Tablet" rev 2.00/0.00 addr 2
uhidev0: iclass 3/0
ums0 at uhidev0: 3 buttons, Z dir
wsmouse1 at ums0 mux 0
vscsi0 at root
scsibus4 at vscsi0: 256 targets
softraid0 at root
scsibus5 at softraid0: 256 targets
root on sd0a (70df444b6f9122b4.a) swap on sd0b dump on sd0b
fd0 at fdc0 drive 1: density unknown

usbdevs:
Controller /dev/usb0:
addr 01: 8086:0000 Intel, EHCI root hub
         high speed, self powered, config 1, rev 1.00
         driver: uhub0
addr 02: 0627:0001 QEMU, QEMU USB Tablet
         high speed, power 100 mA, config 1, rev 0.00, iSerial 42
         driver: uhidev0

pcidump:
Domain /dev/pci0:
 0:0:0: Intel 82441FX
        0x0000: Vendor ID: 8086, Product ID: 1237
        0x0004: Command: 0004, Status: 0000
        0x0008: Class: 06 Bridge, Subclass: 00 Host,
                Interface: 00, Revision: 02
        0x000c: BIST: 00, Header Type: 00, Latency Timer: 00,
                Cache Line Size: 00
        0x0010: BAR empty (00000000)
        0x0014: BAR empty (00000000)
        0x0018: BAR empty (00000000)
        0x001c: BAR empty (00000000)
        0x0020: BAR empty (00000000)
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 1af4 Product ID: 1100
        0x0030: Expansion ROM Base Address: 00000000
        0x0038: 00000000
        0x003c: Interrupt Pin: 00 Line: 00 Min Gnt: 00 Max Lat: 00
        0x0000: 12378086 00000004 06000002 00000000
        0x0010: 00000000 00000000 00000000 00000000
        0x0020: 00000000 00000000 00000000 11001af4
        0x0030: 00000000 00000000 00000000 00000000
        0x0040: 00000000 00000000 00000000 00000000
        0x0050: 00000000 30000000 00000000 00000000
        0x0060: 00000000 00000000 00000000 00000000
        0x0070: 00020000 00000000 00000000 00000000
        0x0080: 00000000 00000000 00000000 00000000
        0x0090: 00000000 00000000 00000000 00000000
        0x00a0: 00000000 00000000 00000000 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: 00000000 00000000 00000000 00000000
        0x00d0: 00000000 00000000 00000000 00000000
        0x00e0: 00000000 00000000 00000000 00000000
        0x00f0: 00000000 00000000 00000000 00000000
 0:1:0: Intel 82371SB ISA
        0x0000: Vendor ID: 8086, Product ID: 7000
        0x0004: Command: 0004, Status: 0200
        0x0008: Class: 06 Bridge, Subclass: 01 ISA,
                Interface: 00, Revision: 00
        0x000c: BIST: 00, Header Type: 80, Latency Timer: 00,
                Cache Line Size: 00
        0x0010: BAR empty (00000000)
        0x0014: BAR empty (00000000)
        0x0018: BAR empty (00000000)
        0x001c: BAR empty (00000000)
        0x0020: BAR empty (00000000)
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 1af4 Product ID: 1100
        0x0030: Expansion ROM Base Address: 00000000
        0x0038: 00000000
        0x003c: Interrupt Pin: 00 Line: 00 Min Gnt: 00 Max Lat: 00
        0x0000: 70008086 02000004 06010000 00800000
        0x0010: 00000000 00000000 00000000 00000000
        0x0020: 00000000 00000000 00000000 11001af4
        0x0030: 00000000 00000000 00000000 00000000
        0x0040: 00000000 00000000 00000000 0003004d
        0x0050: 00000000 00000000 00000000 00000000
        0x0060: 050b0a05 00000000 00000200 00000000
        0x0070: 00000080 0c0c0000 00000002 00000000
        0x0080: 00000000 00000000 00000000 00000000
        0x0090: 00000000 00000000 00000000 00000000
        0x00a0: 00000008 00000000 0000000f 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: 00000000 00000000 00000000 00000000
        0x00d0: 00000000 00000000 00000000 00000000
        0x00e0: 00000000 00000000 00000000 00000000
        0x00f0: 00000000 00000000 00000000 00000000
 0:1:1: Intel 82371SB IDE
        0x0000: Vendor ID: 8086, Product ID: 7010
        0x0004: Command: 0005, Status: 0280
        0x0008: Class: 01 Mass Storage, Subclass: 01 IDE,
                Interface: 80, Revision: 00
        0x000c: BIST: 00, Header Type: 00, Latency Timer: 00,
                Cache Line Size: 00
        0x0010: BAR empty (00000000)
        0x0014: BAR empty (00000000)
        0x0018: BAR empty (00000000)
        0x001c: BAR empty (00000000)
        0x0020: BAR io addr: 0x0000c300/0x0010
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 1af4 Product ID: 1100
        0x0030: Expansion ROM Base Address: 00000000
        0x0038: 00000000
        0x003c: Interrupt Pin: 00 Line: 00 Min Gnt: 00 Max Lat: 00
        0x0000: 70108086 02800005 01018000 00000000
        0x0010: 00000000 00000000 00000000 00000000
        0x0020: 0000c301 00000000 00000000 11001af4
        0x0030: 00000000 00000000 00000000 00000000
        0x0040: 00000000 00000000 00000000 00000000
        0x0050: 00000000 00000000 00000000 00000000
        0x0060: 00000000 00000000 00000000 00000000
        0x0070: 00000000 00000000 00000000 00000000
        0x0080: 00000000 00000000 00000000 00000000
        0x0090: 00000000 00000000 00000000 00000000
        0x00a0: 00000000 00000000 00000000 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: 00000000 00000000 00000000 00000000
        0x00d0: 00000000 00000000 00000000 00000000
        0x00e0: 00000000 00000000 00000000 00000000
        0x00f0: 00000000 00000000 00000000 00000000
 0:1:3: Intel 82371AB Power
        0x0000: Vendor ID: 8086, Product ID: 7113
        0x0004: Command: 0004, Status: 0280
        0x0008: Class: 06 Bridge, Subclass: 80 Miscellaneous,
                Interface: 00, Revision: 03
        0x000c: BIST: 00, Header Type: 00, Latency Timer: 00,
                Cache Line Size: 00
        0x0010: BAR empty (00000000)
        0x0014: BAR empty (00000000)
        0x0018: BAR empty (00000000)
        0x001c: BAR empty (00000000)
        0x0020: BAR empty (00000000)
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 1af4 Product ID: 1100
        0x0030: Expansion ROM Base Address: 00000000
        0x0038: 00000000
        0x003c: Interrupt Pin: 01 Line: 0a Min Gnt: 00 Max Lat: 00
        0x0000: 71138086 02800004 06800003 00000000
        0x0010: 00000000 00000000 00000000 00000000
        0x0020: 00000000 00000000 00000000 11001af4
        0x0030: 00000000 00000000 00000000 0000010a
        0x0040: 0000b001 00000000 00000000 00000000
        0x0050: 00000000 00000000 02000000 10000000
        0x0060: 60000000 00000000 00000000 00000000
        0x0070: 00000000 00000000 00000000 00000000
        0x0080: 00000001 00000000 00000000 00000000
        0x0090: 0000b101 00000000 00000000 00000000
        0x00a0: 00000000 00000000 00000000 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: 00000000 00000000 00000000 00000000
        0x00d0: 00000000 00000000 00000000 00000000
        0x00e0: 00000000 00000000 00000000 00000000
        0x00f0: 00000000 00000000 00000000 00000000
 0:2:0: XenSource Platform Device
        0x0000: Vendor ID: 5853, Product ID: 0001
        0x0004: Command: 0007, Status: 0000
        0x0008: Class: ff (unknown), Subclass: 80 (unknown),
                Interface: 00, Revision: 01
        0x000c: BIST: 00, Header Type: 00, Latency Timer: 00,
                Cache Line Size: 00
        0x0010: BAR io addr: 0x0000c000/0x0100
        0x0014: BAR mem prefetchable 32bit addr: 0xf0000000/0x01000000
        0x0018: BAR empty (00000000)
        0x001c: BAR empty (00000000)
        0x0020: BAR empty (00000000)
        0x0024: BAR empty (00000000)
        0x0028: Cardbus CIS: 00000000
        0x002c: Subsystem Vendor ID: 5853 Product ID: 0001
        0x0030: Expansion ROM Base Address: 00000000
        0x0038: 00000000
        0x003c: Interrupt Pin: 01 Line: 0b Min Gnt: 00 Max Lat: 00
        0x0000: 00015853 00000007 ff800001 00000000
        0x0010: 0000c001 f0000008 00000000 00000000
        0x0020: 00000000 00000000 00000000 00015853
        0x0030: 00000000 00000000 00000000 0000010b
        0x0040: 00000000 00000000 00000000 00000000
        0x0050: 00000000 00000000 00000000 00000000
        0x0060: 00000000 00000000 00000000 00000000
        0x0070: 00000000 00000000 00000000 00000000
        0x0080: 00000000 00000000 00000000 00000000
        0x0090: 00000000 00000000 00000000 00000000
        0x00a0: 00000000 00000000 00000000 00000000
        0x00b0: 00000000 00000000 00000000 00000000
        0x00c0: 00000000 00000000 00000000 00000000
        0x00d0: 00000000 00000000 00000000 00000000
        0x00e0: 00000000 00000000 00000000 00000000
        0x00f0: 00000000 00000000 00000000 00000000
 0:3:0: Bochs VGA
        0x0000: Vendor ID: 1234, Product ID: 1111
        0x0004: Command: 0007, Status: 0000
        0x0008: Class: 03 Display,