>Synopsis: no termination on buffer >Category: library >Environment: System : OpenBSD 7.3 Details : OpenBSD 7.3 (GENERIC.MP) #2080: Sat Mar 25 14:20:25 MDT 2023 dera...@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP
Architecture: OpenBSD.arm64 Machine : arm64 >Description: This is all just theory as I'm code reading. Let's start in setup_query() in /usr/src/lib/libc/asr/res_send_async.c ,... fqdn and dname are size MAXDNAME, pretend MAXDNAME is 50 for simplicity this means that the maximum fqdn name can be 49 characters long, and [1] this is checked in _asr_make_fqdn(), the 50th character is \0. the next function is _asr_dname_from_fqdn() and it does not check for anything but -1, though perhaps it should check for more? Let's check this function out, in /usr/src/lib/libc/asr/asr_utils.c ssize_t _asr_dname_from_fqdn(const char *str, char *dst, size_t max) { XXX str is the fqdn so 49 characters long, dst is dname 50 characters sized. max is also at 50. res = 0; /* special case: the root domain */ if (str[0] == '.') { XXX we're not a root domain so we skip this check, now the room gets hot for (; *str; str = d + 1) { d = strchr(str, '.'); if (d == NULL || d == str) return (-1); XXX the 49th character in str is '.' coincidentally. l = (d - str); XXX here l == 49 if (dname_check_label(str, l) == -1) return (-1); XXX this just checks if we're beyond 63 so it doesn't apply. res += l + 1; XXX res is now 49 + 1 == 50 if (dst) { *dst++ = l; XXX dst is incremented by 1 byte max -= 1; XXX max is now 49 n = (l > max) ? max : l; XXX l is not larger than max so false, n equals 49 now memmove(dst, str, n); XXX dst is now filled with 49 bytes from str max -= n; XXX max is reduced by 49 so it is 0 if (max == 0) dst = NULL; XXX dst is now NULL else XXX else does not apply here, we go through the loop again *str is at 49(.) for (; *str; str = d + 1) { XXX at this point the loop ends becuase d is at 49th byte + 1 is the 50th XXX byte and that is \0, see [1] if (dst) XXX dst is NULL so this does not enter the if condition, which is too bad *dst++ = '\0'; XXX because that would have terminated the dst, even if it was an off by XXX one. return (res + 1); XXX we return res + 1, which is irrelevant because it only gets checked for -1 So what do we have here? dname is not terminated! dname was from the stack and not guaranteed to be zero'ed or is it? Going / returning to: static int setup_query(struct asr_query *as, const char *name, const char *dom, we eventually do strdup(dname), which surely does a strlen() of dname the dname buffer is overwalked, into somewhere until the \0. we could have a crash or it could be exploited further down perhaps. >How-To-Repeat: Code reading for something, for which I may put up a mail soon. >Fix: one thing that can be done is guaranteeing that the buffer of dname is zero filled with a memset(&dname, 0, sizeof(dname)) at beginning of setup_query() This would avert a lot of pain. Or you could fix _asr_dname_from_fqdn(), which I won't do. dmesg: OpenBSD 7.3 (GENERIC.MP) #2080: Sat Mar 25 14:20:25 MDT 2023 dera...@arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP real mem = 8432840704 (8042MB) avail mem = 8139239424 (7762MB) random: good seed from bootblocks mainbus0 at root: ACPI psci0 at mainbus0: PSCI 1.1, SMCCC 1.2 cpu0 at mainbus0 mpidr 0: ARM Cortex-A72 r0p3 cpu0: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache cpu0: 1024KB 64b/line 16-way L2 cache cpu0: CRC32,ASID16 cpu1 at mainbus0 mpidr 1: ARM Cortex-A72 r0p3 cpu1: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache cpu1: 1024KB 64b/line 16-way L2 cache cpu1: CRC32,ASID16 cpu2 at mainbus0 mpidr 2: ARM Cortex-A72 r0p3 cpu2: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache cpu2: 1024KB 64b/line 16-way L2 cache cpu2: CRC32,ASID16 cpu3 at mainbus0 mpidr 3: ARM Cortex-A72 r0p3 cpu3: 48KB 64b/line 3-way L1 PIPT I-cache, 32KB 64b/line 2-way L1 D-cache cpu3: 1024KB 64b/line 16-way L2 cache cpu3: CRC32,ASID16 efi0 at mainbus0: UEFI 2.7 efi0: https://github.com/pftf/RPi4 rev 0x10000 smbios0 at efi0: SMBIOS 3.3.0 smbios0: vendor https://github.com/pftf/RPi4 version "UEFI Firmware v1.21" date 11/13/2020 smbios0: Raspberry Pi Foundation Raspberry Pi 4 Model B apm0 at mainbus0 ampintc0 at mainbus0 nirq 256, ncpu 4 ipi: 0, 1, 2: "interrupt-controller" agtimer0 at mainbus0: 54000 kHz acpi0 at mainbus0: ACPI 6.3 acpi0: sleep states acpi0: tables DSDT FACP CSRT DBG2 GTDT IORT APIC PPTT BGRT acpi0: wakeup devices acpiiort0 at acpi0 "BCM2849" at acpi0 not configured "BCM2835" at acpi0 not configured "BCM2854" at acpi0 not configured "ACPI0004" at acpi0 not configured xhci0 at acpi0 XHC0 addr 0x600000000/0x1000 irq 175, xHCI 1.0 usb0 at xhci0: USB revision 3.0 uhub0 at usb0 configuration 1 interface 0 "Generic xHCI root hub" rev 3.00/1.00 addr 1 "ACPI0007" at acpi0 not configured "ACPI0007" at acpi0 not configured "ACPI0007" at acpi0 not configured "ACPI0007" at acpi0 not configured "ACPI0004" at acpi0 not configured "BCM2848" at acpi0 not configured "BCM2850" at acpi0 not configured "BCM2856" at acpi0 not configured "BCM2845" at acpi0 not configured "BCM2841" at acpi0 not configured "BCM2841" at acpi0 not configured "BCM2838" at acpi0 not configured "BCM2839" at acpi0 not configured "BCM2844" at acpi0 not configured pluart0 at acpi0 URT0 addr 0xfe201000/0x1000 irq 153 "BCM2836" at acpi0 not configured "BCM2EA6" at acpi0 not configured "MSFT8000" at acpi0 not configured sdhc0 at acpi0 SDC1 addr 0xfe300000/0x100 irq 158 sdhc0: base clock frequency unknown "BCM2855" at acpi0 not configured bse0 at acpi0 ETH0 addr 0xfd580000/0x10000 irq 189: address dc:a6:32:cc:db:a7 brgphy0 at bse0 phy 1: BCM54210E 10/100/1000baseT PHY, rev. 2 "PNP0C06" at acpi0 not configured acpitz0 at acpi0: critical temperature is 90 degC simplefb0 at mainbus0: 640x480, 32bpp wsdisplay0 at simplefb0 mux 1: console (std, vt100 emulation) wsdisplay0: screen 1-5 added (std, vt100 emulation) uhub1 at uhub0 port 1 configuration 1 interface 0 "VIA Labs USB2.0 Hub" rev 2.10/4.21 addr 2 uhidev0 at uhub1 port 4 configuration 1 interface 0 "APC Back-UPS ES 700G FW:871.O4 .I USB FW:O4" rev 1.10/1.06 addr 3 uhidev0: iclass 3/0, 146 report ids upd0 at uhidev0 uhid0 at uhidev0 reportid 1: input=0, output=0, feature=1 uhid1 at uhidev0 reportid 2: input=0, output=0, feature=1 uhid2 at uhidev0 reportid 3: input=0, output=0, feature=1 uhid3 at uhidev0 reportid 4: input=0, output=0, feature=1 uhid4 at uhidev0 reportid 5: input=0, output=0, feature=1 uhid5 at uhidev0 reportid 6: input=1, output=0, feature=1 uhid6 at uhidev0 reportid 7: input=0, output=0, feature=2 uhid7 at uhidev0 reportid 8: input=0, output=0, feature=2 uhid8 at uhidev0 reportid 9: input=0, output=0, feature=2 uhid9 at uhidev0 reportid 10: input=0, output=0, feature=1 uhid10 at uhidev0 reportid 11: input=0, output=0, feature=1 uhid11 at uhidev0 reportid 12: input=3, output=0, feature=3 uhid12 at uhidev0 reportid 13: input=0, output=0, feature=1 uhid13 at uhidev0 reportid 14: input=0, output=0, feature=1 uhid14 at uhidev0 reportid 15: input=0, output=0, feature=1 uhid15 at uhidev0 reportid 16: input=0, output=0, feature=1 uhid16 at uhidev0 reportid 17: input=0, output=0, feature=1 uhid17 at uhidev0 reportid 18: input=0, output=0, feature=1 uhid18 at uhidev0 reportid 23: input=0, output=0, feature=2 uhid19 at uhidev0 reportid 24: input=0, output=0, feature=1 uhid20 at uhidev0 reportid 28: input=0, output=0, feature=3 uhid21 at uhidev0 reportid 32: input=0, output=0, feature=2 uhid22 at uhidev0 reportid 34: input=0, output=0, feature=1 uhid23 at uhidev0 reportid 35: input=0, output=0, feature=2 uhid24 at uhidev0 reportid 36: input=0, output=0, feature=2 uhid25 at uhidev0 reportid 37: input=0, output=0, feature=2 uhid26 at uhidev0 reportid 38: input=0, output=0, feature=2 uhid27 at uhidev0 reportid 39: input=0, output=0, feature=1 uhid28 at uhidev0 reportid 40: input=0, output=0, feature=4 uhid29 at uhidev0 reportid 48: input=0, output=0, feature=2 uhid30 at uhidev0 reportid 49: input=0, output=0, feature=2 uhid31 at uhidev0 reportid 50: input=0, output=0, feature=2 uhid32 at uhidev0 reportid 51: input=0, output=0, feature=2 uhid33 at uhidev0 reportid 52: input=0, output=0, feature=1 uhid34 at uhidev0 reportid 53: input=0, output=0, feature=1 uhid35 at uhidev0 reportid 54: input=0, output=0, feature=1 uhid36 at uhidev0 reportid 64: input=0, output=0, feature=1 uhid37 at uhidev0 reportid 65: input=0, output=0, feature=2 uhid38 at uhidev0 reportid 80: input=0, output=0, feature=1 uhid39 at uhidev0 reportid 81: input=0, output=0, feature=1 uhid40 at uhidev0 reportid 96: input=0, output=0, feature=2 uhid41 at uhidev0 reportid 97: input=0, output=0, feature=1 uhid42 at uhidev0 reportid 98: input=0, output=0, feature=4 uhid43 at uhidev0 reportid 120: input=0, output=0, feature=1 uhid44 at uhidev0 reportid 121: input=0, output=0, feature=1 uhid45 at uhidev0 reportid 122: input=0, output=0, feature=4 uhid46 at uhidev0 reportid 123: input=0, output=0, feature=2 uhid47 at uhidev0 reportid 124: input=0, output=0, feature=1 uhid48 at uhidev0 reportid 125: input=0, output=0, feature=1 uhid49 at uhidev0 reportid 126: input=0, output=0, feature=1 uhid50 at uhidev0 reportid 127: input=0, output=0, feature=1 uhid51 at uhidev0 reportid 140: input=0, output=0, feature=1 uhid52 at uhidev0 reportid 141: input=0, output=0, feature=1 uhid53 at uhidev0 reportid 142: input=0, output=0, feature=1 uhid54 at uhidev0 reportid 143: input=0, output=0, feature=1 uhid55 at uhidev0 reportid 144: input=0, output=0, feature=1 uhid56 at uhidev0 reportid 145: input=0, output=0, feature=2 uhid57 at uhidev0 reportid 146: input=0, output=0, feature=2 umass0 at uhub0 port 3 configuration 1 interface 0 "Samsung Flash Drive FIT" rev 3.10/11.00 addr 4 umass0: using SCSI over Bulk-Only scsibus0 at umass0: 2 targets, initiator 0 sd0 at scsibus0 targ 1 lun 0: <Samsung, Flash Drive FIT, 1100> removable serial.090c1000521110001360 sd0: 244752MB, 512 bytes/sector, 501253132 sectors vscsi0 at root scsibus1 at vscsi0: 256 targets softraid0 at root scsibus2 at softraid0: 256 targets root on sd0a (081866428dff49a4.a) swap on sd0b dump on sd0b WARNING: bad clock chip time WARNING: CHECK AND RESET THE DATE! usbdevs: Controller /dev/usb0: addr 01: 0000:0000 Generic, xHCI root hub super speed, self powered, config 1, rev 1.00 driver: uhub0 addr 02: 2109:3431 VIA Labs, USB2.0 Hub high speed, self powered, config 1, rev 4.21 driver: uhub1 addr 03: 051d:0002 APC, Back-UPS ES 700G FW:871.O4 .I USB FW:O4 low speed, power 2 mA, config 1, rev 1.06, iSerial 5B1936T42959 driver: uhidev0 addr 04: 090c:1000 Samsung, Flash Drive FIT super speed, power 76 mA, config 1, rev 11.00, iSerial 0319521110001360 driver: umass0