Re: amd64: do CPU identification before TSC sync test

2022-05-10 Thread Yuichiro NAITO

Hi, Scott.

After applying your patch, cpu1 is not identified on my current kernel.
Dmesg shows as follows. I'll see it further more.

OpenBSD 7.1-current (GENERIC.MP) #3: Wed May 11 12:27:53 JST 2022
yuich...@yuichiro-obsd.soum.co.jp:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 2129526784 (2030MB)
avail mem = 2047676416 (1952MB)
random: good seed from bootblocks
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xe0010 (242 entries)
bios0: vendor Phoenix Technologies LTD version "6.00" date 12/12/2018
bios0: VMware, Inc. VMware Virtual Platform
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S0 S1 S4 S5
acpi0: tables DSDT FACP BOOT APIC MCFG SRAT HPET WAET
acpi0: wakeup devices PCI0(S3) USB_(S1) P2P0(S3) S1F0(S3) S2F0(S3) S8F0(S3) 
S16F(S3) S17F(S3) S18F(S3) S22F(S3) S23F(S3) S24F(S3) S25F(S3) PE40(S3) 
S1F0(S3) PE50(S3) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD Ryzen 7 5700G with Radeon Graphics, 3792.28 MHz, 19-50-00
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,PCLMUL,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,HV,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,PKU,IBPB,XSAVEOPT,XSAVEC,XSAVES

cpu0: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 
8-way L2 cache
cpu0: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 65MHz
cpu1 at mainbus0: apid 2 (application processor)
cpu1: failed to identify


On 5/11/22 11:04, Scott Cheloha wrote:

On Tue, Mar 29, 2022 at 10:24:03AM -0500, Scott Cheloha wrote:

On Tue, Mar 29, 2022 at 03:26:49PM +1100, Jonathan Gray wrote:

On Mon, Mar 28, 2022 at 10:52:09PM -0500, Scott Cheloha wrote:

I want to use the IA32_TSC_ADJUST MSR where available when testing TSC
synchronization.  We note if it's available during CPU identification.

Can we do CPU identification earlier in cpu_hatch() and
cpu_start_secondary(), before we do the TSC sync testing?

This can wait until after release.  I'm just trying to suss out
whether there is an order dependency I'm not seeing.  My laptop
appears to boot and resume no differently with this patch.

Thoughts?


The rest aside, moving the cpu_ucode_apply() call to after the
identifycpu() call is wrong as microcode can add cpuid bits.
I would keep cpu_tsx_disable() before it as well.


Okay, moved them up.


I'm sure I've had problems trying to change the sequencing
of lapic, tsc freq and identify in the past.  It caused problems
only on certain machines.


[...]


6 week bump + rebase.

Once again, I want to do CPU identification before the TSC sync test
so we can check for and use the IA32_TSC_ADJUST MSR during the sync
test.

Does anyone understand amd64 CPU startup well enough to say whether
this rearrangement is going to break something?

Is this ok?

Index: cpu.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v
retrieving revision 1.156
diff -u -p -r1.156 cpu.c
--- cpu.c   26 Apr 2022 08:35:30 -  1.156
+++ cpu.c   11 May 2022 02:00:37 -
@@ -852,20 +852,7 @@ cpu_start_secondary(struct cpu_info *ci)
printf("dropping into debugger; continue from here to resume 
boot\n");
db_enter();
  #endif
-   } else {
-   /*
-* Synchronize time stamp counters. Invalidate cache and
-* synchronize twice (in tsc_sync_bp) to minimize possible
-* cache effects. Disable interrupts to try and rule out any
-* external interference.
-*/
-   s = intr_disable();
-   wbinvd();
-   tsc_sync_bp(ci);
-   intr_restore(s);
-#ifdef TSC_DEBUG
-   printf("TSC skew=%lld\n", (long long)ci->ci_tsc_skew);
-#endif
+   goto cleanup;
}
  
  	if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) {

@@ -875,11 +862,28 @@ cpu_start_secondary(struct cpu_info *ci)
for (i = 200; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--)
delay(10);
  
-		if (ci->ci_flags & CPUF_IDENTIFY)

+   if (ci->ci_flags & CPUF_IDENTIFY) {
printf("%s: failed to identify\n",
ci->ci_dev->dv_xname);
+   goto cleanup;
+   }
}
  
+	/*

+* Synchronize time stamp counters. Invalidate cache and
+* synchronize twice (in tsc_sync_bp) to minimize possible
+* 

Re: Mark pw_error __dead in util.h

2022-05-10 Thread Matthew Martin
On Tue, May 03, 2022 at 10:37:36PM -0500, Matthew Martin wrote:
> The function is already marked __dead in passwd.c, so appears to just be
> an oversight.

ping

diff --git util.h util.h
index dd64f478e23..752f8bb9fc5 100644
--- util.h
+++ util.h
@@ -97,7 +97,7 @@ void  pw_edit(int, const char *);
 void   pw_prompt(void);
 void   pw_copy(int, int, const struct passwd *, const struct passwd *);
 intpw_scan(char *, struct passwd *, int *);
-void   pw_error(const char *, int, int);
+__dead voidpw_error(const char *, int, int);
 intgetptmfd(void);
 intopenpty(int *, int *, char *, const struct termios *,
const struct winsize *);



Re: [v2] amd64: simplify TSC sync testing

2022-05-10 Thread Scott Cheloha
On Wed, May 11, 2022 at 10:52:55AM +0900, Yuichiro NAITO wrote:
> Hi, Scott.
> 
> Recently I started running OpenBSD on ESXi.
> I'm facing monotonic time going back problem as same as Yasuoka-san's report.
> 
> https://marc.info/?l=openbsd-tech=161657532610882=2
> 
> I've tried your v2 patch. It seems the problem has been solved in my 
> enviroment.
> But I'm a little bit confused about the patch. May I ask you goal of the 
> patch?

The primary goal of the patch is to eliminate false positives when
testing for TSC skew.

NUMA lag seems to sometimes fool the current test.  It would be nice
to be able to use the TSC in userland on multisocket machines.

> Is it indented to fix the problem or is it for collecting test cases and the 
> results?

The intention of the patch was not to fix the problem Yasuoka is
describing.

If it fixes that problem it is unintentional.

> Here is the dmesg shown in my patched environment.
> 
> [...]



Re: amd64: do CPU identification before TSC sync test

2022-05-10 Thread Scott Cheloha
On Tue, Mar 29, 2022 at 10:24:03AM -0500, Scott Cheloha wrote:
> On Tue, Mar 29, 2022 at 03:26:49PM +1100, Jonathan Gray wrote:
> > On Mon, Mar 28, 2022 at 10:52:09PM -0500, Scott Cheloha wrote:
> > > I want to use the IA32_TSC_ADJUST MSR where available when testing TSC
> > > synchronization.  We note if it's available during CPU identification.
> > > 
> > > Can we do CPU identification earlier in cpu_hatch() and
> > > cpu_start_secondary(), before we do the TSC sync testing?
> > > 
> > > This can wait until after release.  I'm just trying to suss out
> > > whether there is an order dependency I'm not seeing.  My laptop
> > > appears to boot and resume no differently with this patch.
> > > 
> > > Thoughts?
> > 
> > The rest aside, moving the cpu_ucode_apply() call to after the
> > identifycpu() call is wrong as microcode can add cpuid bits.
> > I would keep cpu_tsx_disable() before it as well.
> 
> Okay, moved them up.
> 
> > I'm sure I've had problems trying to change the sequencing
> > of lapic, tsc freq and identify in the past.  It caused problems
> > only on certain machines.
> 
> [...]

6 week bump + rebase.

Once again, I want to do CPU identification before the TSC sync test
so we can check for and use the IA32_TSC_ADJUST MSR during the sync
test.

Does anyone understand amd64 CPU startup well enough to say whether
this rearrangement is going to break something?

Is this ok?

Index: cpu.c
===
RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v
retrieving revision 1.156
diff -u -p -r1.156 cpu.c
--- cpu.c   26 Apr 2022 08:35:30 -  1.156
+++ cpu.c   11 May 2022 02:00:37 -
@@ -852,20 +852,7 @@ cpu_start_secondary(struct cpu_info *ci)
printf("dropping into debugger; continue from here to resume 
boot\n");
db_enter();
 #endif
-   } else {
-   /*
-* Synchronize time stamp counters. Invalidate cache and
-* synchronize twice (in tsc_sync_bp) to minimize possible
-* cache effects. Disable interrupts to try and rule out any
-* external interference.
-*/
-   s = intr_disable();
-   wbinvd();
-   tsc_sync_bp(ci);
-   intr_restore(s);
-#ifdef TSC_DEBUG
-   printf("TSC skew=%lld\n", (long long)ci->ci_tsc_skew);
-#endif
+   goto cleanup;
}
 
if ((ci->ci_flags & CPUF_IDENTIFIED) == 0) {
@@ -875,11 +862,28 @@ cpu_start_secondary(struct cpu_info *ci)
for (i = 200; (ci->ci_flags & CPUF_IDENTIFY) && i > 0; i--)
delay(10);
 
-   if (ci->ci_flags & CPUF_IDENTIFY)
+   if (ci->ci_flags & CPUF_IDENTIFY) {
printf("%s: failed to identify\n",
ci->ci_dev->dv_xname);
+   goto cleanup;
+   }
}
 
+   /*
+* Synchronize time stamp counters. Invalidate cache and
+* synchronize twice (in tsc_sync_bp) to minimize possible
+* cache effects. Disable interrupts to try and rule out any
+* external interference.
+*/
+   s = intr_disable();
+   wbinvd();
+   tsc_sync_bp(ci);
+   intr_restore(s);
+#ifdef TSC_DEBUG
+   printf("TSC skew=%lld\n", (long long)ci->ci_tsc_skew);
+#endif
+
+cleanup:
CPU_START_CLEANUP(ci);
 
pmap_kremove(MP_TRAMPOLINE, PAGE_SIZE);
@@ -940,18 +944,8 @@ cpu_hatch(void *v)
if (ci->ci_flags & CPUF_PRESENT)
panic("%s: already running!?", ci->ci_dev->dv_xname);
 #endif
-
-   /*
-* Synchronize the TSC for the first time. Note that interrupts are
-* off at this point.
-*/
-   wbinvd();
ci->ci_flags |= CPUF_PRESENT;
-   ci->ci_tsc_skew = 0;/* reset on resume */
-   tsc_sync_ap(ci);
 
-   lapic_enable();
-   lapic_startclock();
cpu_ucode_apply(ci);
cpu_tsx_disable(ci);
 
@@ -970,6 +964,17 @@ cpu_hatch(void *v)
/* Prevent identifycpu() from running again */
atomic_setbits_int(>ci_flags, CPUF_IDENTIFIED);
}
+
+   /*
+* Synchronize the TSC for the first time. Note that interrupts are
+* off at this point.
+*/
+   wbinvd();
+   ci->ci_tsc_skew = 0;/* reset on resume */
+   tsc_sync_ap(ci);
+
+   lapic_enable();
+   lapic_startclock();
 
while ((ci->ci_flags & CPUF_GO) == 0)
delay(10);



Re: [v2] amd64: simplify TSC sync testing

2022-05-10 Thread Yuichiro NAITO

Hi, Scott.

Recently I started running OpenBSD on ESXi.
I'm facing monotonic time going back problem as same as Yasuoka-san's report.

https://marc.info/?l=openbsd-tech=161657532610882=2

I've tried your v2 patch. It seems the problem has been solved in my enviroment.
But I'm a little bit confused about the patch. May I ask you goal of the patch?
Is it indented to fix the problem or is it for collecting test cases and the 
results?

Here is the dmesg shown in my patched environment.

OpenBSD 7.1-current (GENERIC.MP) #2: Mon May  2 12:03:22 JST 2022
yuich...@yuichiro-obsd.soum.co.jp:/usr/src/sys/arch/amd64/compile/GENERIC.MP
real mem = 2129526784 (2030MB)
avail mem = 2047713280 (1952MB)
random: good seed from bootblocks
mpath0 at root
scsibus0 at mpath0: 256 targets
mainbus0 at root
bios0 at mainbus0: SMBIOS rev. 2.7 @ 0xe0010 (242 entries)
bios0: vendor Phoenix Technologies LTD version "6.00" date 12/12/2018
bios0: VMware, Inc. VMware Virtual Platform
acpi0 at bios0: ACPI 4.0
acpi0: sleep states S0 S1 S4 S5
acpi0: tables DSDT FACP BOOT APIC MCFG SRAT HPET WAET
acpi0: wakeup devices PCI0(S3) USB_(S1) P2P0(S3) S1F0(S3) S2F0(S3) S8F0(S3) 
S16F(S3) S17F(S3) S18F(S3) S22F(S3) S23F(S3) S24F(S3) S25F(S3) PE40(S3) 
S1F0(S3) PE50(S3) [...]
acpitimer0 at acpi0: 3579545 Hz, 24 bits
acpimadt0 at acpi0 addr 0xfee0: PC-AT compat
cpu0 at mainbus0: apid 0 (boot processor)
cpu0: AMD Ryzen 7 5700G with Radeon Graphics, 3792.27 MHz, 19-50-00
cpu0: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,PCLMUL,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,HV,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,PKU,IBPB,XSAVEOPT,XSAVEC,XSAVES

cpu0: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 
8-way L2 cache
cpu0: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu0: smt 0, core 0, package 0
mtrr: Pentium Pro MTRR support, 8 var ranges, 88 fixed ranges
cpu0: apic clock running at 65MHz
cpu1 at mainbus0: apid 2 (application processor)
cpu1: AMD Ryzen 7 5700G with Radeon Graphics, 3792.01 MHz, 19-50-00
cpu1: 
FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,CFLUSH,MMX,FXSR,SSE,SSE2,SSE3,PCLMUL,SSSE3,FMA3,CX16,SSE4.1,SSE4.2,x2APIC,MOVBE,POPCNT,AES,XSAVE,AVX,F16C,RDRAND,HV,NXE,MMXX,FFXSR,PAGE1GB,RDTSCP,LONG,LAHF,EAPICSP,AMCR8,ABM,SSE4A,MASSE,3DNOWP,OSVW,ITSC,FSGSBASE,BMI1,AVX2,SMEP,BMI2,ERMS,INVPCID,RDSEED,ADX,SMAP,CLFLUSHOPT,CLWB,SHA,PKU,IBPB,XSAVEOPT,XSAVEC,XSAVES

cpu1: 32KB 64b/line 8-way I-cache, 32KB 64b/line 8-way D-cache, 512KB 64b/line 
8-way L2 cache
cpu1: ITLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu1: DTLB 64 4KB entries fully associative, 64 4MB entries fully associative
cpu1: smt 0, core 0, package 2
ioapic0 at mainbus0: apid 1 pa 0xfec0, version 20, 24 pins
acpimcfg0 at acpi0
acpimcfg0: addr 0xf000, bus 0-127
acpihpet0 at acpi0: 14318179 Hz
acpiprt0 at acpi0: bus 0 (PCI0)
acpipci0 at acpi0 PCI0: 0x 0x0011 0x0001
acpicmos0 at acpi0
"PNP0A05" at acpi0 not configured
acpiac0 at acpi0: AC unit online
acpicpu0 at acpi0: C1(@1 halt!)
acpicpu1 at acpi0: C1(@1 halt!)
pvbus0 at mainbus0: VMware
vmt0 at pvbus0
pci0 at mainbus0 bus 0
pchb0 at pci0 dev 0 function 0 "Intel 82443BX AGP" rev 0x01
ppb0 at pci0 dev 1 function 0 "Intel 82443BX AGP" rev 0x01
pci1 at ppb0 bus 1
pcib0 at pci0 dev 7 function 0 "Intel 82371AB PIIX4 ISA" rev 0x08
pciide0 at pci0 dev 7 function 1 "Intel 82371AB IDE" rev 0x01: DMA, channel 0 
configured to compatibility, channel 1 configured to compatibility
pciide0: channel 0 disabled (no drives)
pciide0: channel 1 disabled (no drives)
piixpm0 at pci0 dev 7 function 3 "Intel 82371AB Power" rev 0x08: SMBus disabled
"VMware VMCI" rev 0x10 at pci0 dev 7 function 7 not configured
vga1 at pci0 dev 15 function 0 "VMware SVGA II" rev 0x00
wsdisplay0 at vga1 mux 1: console (80x25, vt100 emulation)
wsdisplay0: screen 1-5 added (80x25, vt100 emulation)
mpi0 at pci0 dev 16 function 0 "Symbios Logic 53c1030" rev 0x01: apic 1 int 17
mpi0: 0, firmware 1.3.41.32
scsibus1 at mpi0: 16 targets, initiator 7
sd0 at scsibus1 targ 0 lun 0: 
sd0: 40960MB, 512 bytes/sector, 83886080 sectors
mpi0: target 0 Sync at 160MHz width 16bit offset 127 QAS 1 DT 1 IU 1
ppb1 at pci0 dev 17 function 0 "VMware PCI" rev 0x02
pci2 at ppb1 bus 2
uhci0 at pci2 dev 0 function 0 "VMware UHCI" rev 0x00: apic 1 int 18
ehci0 at pci2 dev 1 function 0 "VMware EHCI" rev 0x00: apic 1 int 19
usb0 at ehci0: USB revision 2.0
uhub0 at usb0 configuration 1 interface 0 "VMware EHCI root hub" rev 2.00/1.00 
addr 1
ahci0 at pci2 dev 3 function 0 "VMware AHCI" rev 0x00: msi, AHCI 1.3
ahci0: port 0: 6.0Gb/s
scsibus2 at ahci0: 32 targets
cd0 at scsibus2 targ 0 lun 0:  

ssh: double fclose() in sshkey_save_public()

2022-05-10 Thread Tobias Heider
Hey,

it looks like in sshkey_save_public() the same fd will be closed twice
if the first fclose() returns something other than 0.

The patch below should make sure everything only gets closed once.
I moved the close() call and refactored a bit to improve readability.

Index: authfile.c
===
RCS file: /cvs/src/usr.bin/ssh/authfile.c,v
retrieving revision 1.142
diff -u -p -r1.142 authfile.c
--- authfile.c  1 Jan 2022 01:55:30 -   1.142
+++ authfile.c  10 May 2022 21:38:29 -
@@ -496,20 +496,25 @@ sshkey_save_public(const struct sshkey *
return SSH_ERR_SYSTEM_ERROR;
if ((f = fdopen(fd, "w")) == NULL) {
r = SSH_ERR_SYSTEM_ERROR;
+   close(fd);
goto fail;
}
if ((r = sshkey_write(key, f)) != 0)
goto fail;
fprintf(f, " %s\n", comment);
-   if (ferror(f) || fclose(f) != 0) {
+   if (ferror(f)) {
r = SSH_ERR_SYSTEM_ERROR;
+   goto fail;
+   }
+   if (fclose(f) != 0) {
+   r = SSH_ERR_SYSTEM_ERROR;
+   f = NULL;
  fail:
-   oerrno = errno;
-   if (f != NULL)
+   if (f != NULL) {
+   oerrno = errno;
fclose(f);
-   else
-   close(fd);
-   errno = oerrno;
+   errno = oerrno;
+   }
return r;
}
return 0;



Add support for Advantech multi-port serial device to puc(4)

2022-05-10 Thread Greg Winterstein
This patch adds support for the Advantech PCIE-1612B multi-port serial device
to puc(4). The device has an Exar XR17V354 UART and the changes use the
existing code that supports XR17V35x devices.

This patch was minimally tested. All four ports were tested with several
different serial devices. I only tested RS-232 and do not have the ability
to test RS-422 or RS-485.

dmesg snippet:
...
puc0 at pci4 dev 0 function 0 "Advantech PCIE-1612B-AE 4-port RS232/422/485" 
rev 0x03: ports: 16 com
com4 at puc0 port 0 apic 2 int 17: xr17v35x, 256 byte fifo
com5 at puc0 port 1 apic 2 int 17: xr17v35x, 256 byte fifo
com6 at puc0 port 2 apic 2 int 17: xr17v35x, 256 byte fifo
com7 at puc0 port 3 apic 2 int 17: xr17v35x, 256 byte fifo
...


Index: pcidevs
===
RCS file: /cvs/src/sys/dev/pci/pcidevs,v
retrieving revision 1.1988
diff -u -p -u -p -r1.1988 pcidevs
--- pcidevs 11 Mar 2022 08:28:40 -  1.1988
+++ pcidevs 10 May 2022 15:38:10 -
@@ -244,6 +244,7 @@ vendor  TECHSAN 0x13d0  Techsan Electroni
 vendor ABOCOM  0x13d1  Abocom
 vendor SUNDANCE0x13f0  Sundance
 vendor CMI 0x13f6  C-Media Electronics
+vendor ADVANTECH   0x13fe  Advantech
 vendor LAVA0x1407  Lava
 vendor SUNIX   0x1409  Sunix
 vendor ICENSEMBLE  0x1412  IC Ensemble
@@ -512,6 +513,9 @@ product ACCTON EN1217   0x1217  EN1217
 
 /* Acer products */
 product ACER M1435 0x1435  M1435 VL-PCI
+
+/* Advantech products */
+product ADVANTECH 1612B0x000b  PCIE-1612B-AE 4-port 
RS232/422/485
 
 /* Analog Devices */
 product AD SP21535 0x1535  ADSP 21535 DSP
Index: pucdata.c
===
RCS file: /cvs/src/sys/dev/pci/pucdata.c,v
retrieving revision 1.116
diff -u -p -u -p -r1.116 pucdata.c
--- pucdata.c   9 Jan 2022 05:42:58 -   1.116
+++ pucdata.c   10 May 2022 15:38:10 -
@@ -2139,6 +2139,20 @@ const struct puc_device_description puc_
},
},
 
+   {   /*
+* Advantech PCIE-1612B-AE 4-port RS232/422/485
+* Has a 4-channel Exar XR17V354 UART
+*/
+   {   PCI_VENDOR_ADVANTECH, PCI_PRODUCT_ADVANTECH_1612B,  0, 0 },
+   {   0x, 0x, 0, 0 },
+   {
+   { PUC_PORT_COM_XR17V35X, 0x10, 0x },
+   { PUC_PORT_COM_XR17V35X, 0x10, 0x0400 },
+   { PUC_PORT_COM_XR17V35X, 0x10, 0x0800 },
+   { PUC_PORT_COM_XR17V35X, 0x10, 0x0C00 },
+   },
+   },
+
{   /* Dell DRAC 3 Virtual UART */
{   PCI_VENDOR_DELL, PCI_PRODUCT_DELL_DRAC_3_VUART, 0, 0 },
{   0x, 0x, 0, 0 },



rpki-client: remove verify_cb()

2022-05-10 Thread Theo Buehler
With RSC and recent cert.c changes, rpki-client now has a hard
dependency on RFC 3779 support in libcrypto, so this code is no
longer useful.

Index: validate.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
retrieving revision 1.32
diff -u -p -r1.32 validate.c
--- validate.c  10 May 2022 07:41:37 -  1.32
+++ validate.c  10 May 2022 20:28:52 -
@@ -347,67 +347,6 @@ valid_origin(const char *uri, const char
 }
 
 /*
- * Callback for X509_verify_cert() to handle critical extensions in old
- * LibreSSL libraries or OpenSSL libs without RFC3779 support.
- */
-static int
-verify_cb(int ok, X509_STORE_CTX *store_ctx)
-{
-   X509*cert;
-   const STACK_OF(X509_EXTENSION)  *exts;
-   X509_EXTENSION  *ext;
-   ASN1_OBJECT *obj;
-   char*file;
-   int  depth, error, i, nid;
-
-   error = X509_STORE_CTX_get_error(store_ctx);
-   depth = X509_STORE_CTX_get_error_depth(store_ctx);
-
-   if (error != X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION)
-   return ok;
-
-   if ((file = X509_STORE_CTX_get_app_data(store_ctx)) == NULL)
-   cryptoerrx("X509_STORE_CTX_get_app_data");
-
-   if ((cert = X509_STORE_CTX_get_current_cert(store_ctx)) == NULL) {
-   warnx("%s: got no current cert", file);
-   return 0;
-   }
-   if ((exts = X509_get0_extensions(cert)) == NULL) {
-   warnx("%s: got no cert extensions", file);
-   return 0;
-   }
-
-   for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
-   ext = sk_X509_EXTENSION_value(exts, i);
-
-   /* skip over non-critical and known extensions */
-   if (!X509_EXTENSION_get_critical(ext))
-   continue;
-   if (X509_supported_extension(ext))
-   continue;
-
-   if ((obj = X509_EXTENSION_get_object(ext)) == NULL) {
-   warnx("%s: got no extension object", file);
-   return 0;
-   }
-
-   nid = OBJ_obj2nid(obj);
-   switch (nid) {
-   case NID_sbgp_ipAddrBlock:
-   case NID_sbgp_autonomousSysNum:
-   continue;
-   default:
-   warnx("%s: depth %d: unknown extension: nid %d",
-   file, depth, nid);
-   return 0;
-   }
-   }
-
-   return 1;
-}
-
-/*
  * Walk the certificate tree to the root and build a certificate
  * chain from cert->x509. All certs in the tree are validated and
  * can be loaded as trusted stack into the validator.
@@ -476,9 +415,6 @@ valid_x509(char *file, X509_STORE_CTX *s
if (!X509_VERIFY_PARAM_add0_policy(params, cp_oid))
cryptoerrx("X509_VERIFY_PARAM_add0_policy");
 
-   X509_STORE_CTX_set_verify_cb(store_ctx, verify_cb);
-   if (!X509_STORE_CTX_set_app_data(store_ctx, file))
-   cryptoerrx("X509_STORE_CTX_set_app_data");
flags = X509_V_FLAG_CRL_CHECK;
flags |= X509_V_FLAG_EXPLICIT_POLICY;
flags |= X509_V_FLAG_INHIBIT_MAP;



Re: move vmm(4) spinout paranoia behind MP_LOCKDEBUG

2022-05-10 Thread Dave Voutila


ping

Dave Voutila  writes:

> This tucks all the spinout paranoia behind `#ifdef MP_LOCKDEBUG` and
> uses the same approach used in amd64's pmap's TLB shootdown code.
>
> Part of me wants to remove this altogether, but I'm not sure it's
> outlived its usefulness quite yet.
>
> Three areas that busy wait on ipi's are modified:
>
> 1. vmm_start - performs ipi to enable vmm on all cpus
> 2. vmm_stop - performs ipi to disable vmm on all cpus
> 3. vmx_remote_vmclear - performs ipi to vmclear a cpu (only pertinent to
>Intel hosts)
>
> (3) is the most likely to spin out and prior to bumping the spinout to
> the current value (based on __mp_lock_spinout) we had reports from users
> of hitting it on slower/older MP hardware.
>
> For vmm_{start, stop}, I moved the current cpu start/stop routine to
> before performing the ipi broadcast because if we're going to fail to
> (dis)enable vmm we should fail fast. If we fail, there's no need to
> broadcast the ipi. This simplifies the code paths and removes a local
> variable.
>
> All three migrate to infinite busy waits and only have a spinout if
> built with MP_LOCKDEBUG. On a spinout, we enter ddb.
>
> Compiled on amd64 GENERIC, GENERIC.MP, and GENERIC.MP with
> MP_LOCKDEBUG. (This time I won't break GENERIC :)
>
> OK?
>
> -dv
>
> Index: sys/arch/amd64/amd64/vmm.c
> ===
> RCS file: /opt/cvs/src/sys/arch/amd64/amd64/vmm.c,v
> retrieving revision 1.305
> diff -u -p -r1.305 vmm.c
> --- sys/arch/amd64/amd64/vmm.c28 Mar 2022 06:28:47 -  1.305
> +++ sys/arch/amd64/amd64/vmm.c16 Apr 2022 18:49:01 -
> @@ -43,6 +43,11 @@
>  #include 
>  #include 
>
> +#ifdef MP_LOCKDEBUG
> +#include 
> +extern int __mp_lock_spinout;
> +#endif /* MP_LOCKDEBUG */
> +
>  /* #define VMM_DEBUG */
>
>  void *l1tf_flush_region;
> @@ -1328,17 +1333,26 @@ int
>  vmm_start(void)
>  {
>   struct cpu_info *self = curcpu();
> - int ret = 0;
>  #ifdef MULTIPROCESSOR
>   struct cpu_info *ci;
>   CPU_INFO_ITERATOR cii;
> - int i;
> -#endif
> +#ifdef MP_LOCKDEBUG
> + int nticks;
> +#endif /* MP_LOCKDEBUG */
> +#endif /* MULTIPROCESSOR */
>
>   /* VMM is already running */
>   if (self->ci_flags & CPUF_VMM)
>   return (0);
>
> + /* Start VMM on this CPU */
> + start_vmm_on_cpu(self);
> + if (!(self->ci_flags & CPUF_VMM)) {
> + printf("%s: failed to enter VMM mode\n",
> + self->ci_dev->dv_xname);
> + return (EIO);
> + }
> +
>  #ifdef MULTIPROCESSOR
>   /* Broadcast start VMM IPI */
>   x86_broadcast_ipi(X86_IPI_START_VMM);
> @@ -1346,25 +1360,23 @@ vmm_start(void)
>   CPU_INFO_FOREACH(cii, ci) {
>   if (ci == self)
>   continue;
> - for (i = 10; (!(ci->ci_flags & CPUF_VMM)) && i>0;i--)
> - delay(10);
> - if (!(ci->ci_flags & CPUF_VMM)) {
> - printf("%s: failed to enter VMM mode\n",
> - ci->ci_dev->dv_xname);
> - ret = EIO;
> +#ifdef MP_LOCKDEBUG
> + nticks = __mp_lock_spinout;
> +#endif /* MP_LOCKDEBUG */
> + while (!(ci->ci_flags & CPUF_VMM)) {
> + CPU_BUSY_CYCLE();
> +#ifdef MP_LOCKDEBUG
> + if (--nticks <= 0) {
> + db_printf("%s: spun out", __func__);
> + db_enter();
> + nticks = __mp_lock_spinout;
> + }
> +#endif /* MP_LOCKDEBUG */
>   }
>   }
>  #endif /* MULTIPROCESSOR */
>
> - /* Start VMM on this CPU */
> - start_vmm_on_cpu(self);
> - if (!(self->ci_flags & CPUF_VMM)) {
> - printf("%s: failed to enter VMM mode\n",
> - self->ci_dev->dv_xname);
> - ret = EIO;
> - }
> -
> - return (ret);
> + return (0);
>  }
>
>  /*
> @@ -1376,17 +1388,26 @@ int
>  vmm_stop(void)
>  {
>   struct cpu_info *self = curcpu();
> - int ret = 0;
>  #ifdef MULTIPROCESSOR
>   struct cpu_info *ci;
>   CPU_INFO_ITERATOR cii;
> - int i;
> -#endif
> +#ifdef MP_LOCKDEBUG
> + int nticks;
> +#endif /* MP_LOCKDEBUG */
> +#endif /* MULTIPROCESSOR */
>
>   /* VMM is not running */
>   if (!(self->ci_flags & CPUF_VMM))
>   return (0);
>
> + /* Stop VMM on this CPU */
> + stop_vmm_on_cpu(self);
> + if (self->ci_flags & CPUF_VMM) {
> + printf("%s: failed to exit VMM mode\n",
> + self->ci_dev->dv_xname);
> + return (EIO);
> + }
> +
>  #ifdef MULTIPROCESSOR
>   /* Stop VMM on other CPUs */
>   x86_broadcast_ipi(X86_IPI_STOP_VMM);
> @@ -1394,25 +1415,23 @@ vmm_stop(void)
>   CPU_INFO_FOREACH(cii, ci) {
>   if (ci == self)
>   continue;
> - for (i = 10; (ci->ci_flags & CPUF_VMM) && i>0 

rpki-client: deserialize ASIdentifiers in libcrypto

2022-05-10 Thread Theo Buehler
The ASIdentifiers code is a bit strangely factored presumably due to
constraints of the low-level shoveling. I kept the coarse structure
of the code and left some house keeping for later. The changes in
sbgp_asrange() and sbgp_asid() should be easy.

The in-tree sbgp_assysnum() is tricky to follow. The main thing to
note is that the for loop at the end really only inspects asnum (and
ignores rdi). Since RDI is forbidden in RFC 6487, I added a check
and error. All the complicated gymnastics can be dropped and what
remains is a bit stricter and what it does should be rather obvious.

With this diff, ASN1_TYPE and ASN1_frame() uses are gone from cert.c.

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.74
diff -u -p -r1.74 cert.c
--- cert.c  10 May 2022 16:43:53 -  1.74
+++ cert.c  10 May 2022 18:13:02 -
@@ -34,13 +34,6 @@
 #include "extern.h"
 
 /*
- * Type of ASIdentifier (RFC 3779, 3.2.3).
- */
-#defineASID_TYPE_ASNUM 0x00
-#define ASID_TYPE_RDI  0x01
-#define ASID_TYPE_MAX  ASID_TYPE_RDI
-
-/*
  * A parsing sequence of a file (which may just be ).
  */
 struct parse {
@@ -128,70 +121,36 @@ sbgp_addr(struct parse *p, struct cert_i
  * Returns zero on failure, non-zero on success.
  */
 static int
-sbgp_asrange(struct parse *p, const unsigned char *d, size_t dsz)
+sbgp_asrange(struct parse *p, const ASRange *range)
 {
struct cert_as   as;
-   ASN1_SEQUENCE_ANY   *seq;
-   const ASN1_TYPE *t;
-   int  rc = 0;
-
-   if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, , dsz)) == NULL) {
-   cryptowarnx("%s: RFC 3779 section 3.2.3.8: ASRange: "
-   "failed ASN.1 sequence parse", p->fn);
-   goto out;
-   }
-   if (sk_ASN1_TYPE_num(seq) != 2) {
-   warnx("%s: RFC 3779 section 3.2.3.8: ASRange: "
-   "want 2 elements, have %d", p->fn,
-   sk_ASN1_TYPE_num(seq));
-   goto out;
-   }
 
memset(, 0, sizeof(struct cert_as));
as.type = CERT_AS_RANGE;
 
-   t = sk_ASN1_TYPE_value(seq, 0);
-   if (t->type != V_ASN1_INTEGER) {
-   warnx("%s: RFC 3779 section 3.2.3.8: ASRange: "
-   "want ASN.1 integer, have %s (NID %d)",
-   p->fn, ASN1_tag2str(t->type), t->type);
-   goto out;
-   }
-   if (!as_id_parse(t->value.integer, )) {
+   if (!as_id_parse(range->min, )) {
warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
"malformed AS identifier", p->fn);
-   goto out;
+   return 0;
}
 
-   t = sk_ASN1_TYPE_value(seq, 1);
-   if (t->type != V_ASN1_INTEGER) {
-   warnx("%s: RFC 3779 section 3.2.3.8: ASRange: "
-   "want ASN.1 integer, have %s (NID %d)",
-   p->fn, ASN1_tag2str(t->type), t->type);
-   goto out;
-   }
-   if (!as_id_parse(t->value.integer, )) {
+   if (!as_id_parse(range->max, )) {
warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
"malformed AS identifier", p->fn);
-   goto out;
+   return 0;
}
 
if (as.range.max == as.range.min) {
warnx("%s: RFC 3379 section 3.2.3.8: ASRange: "
"range is singular", p->fn);
-   goto out;
+   return 0;
} else if (as.range.max < as.range.min) {
warnx("%s: RFC 3379 section 3.2.3.8: ASRange: "
"range is out of order", p->fn);
-   goto out;
+   return 0;
}
 
-   if (!append_as(p, ))
-   goto out;
-   rc = 1;
-out:
-   sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free);
-   return rc;
+   return append_as(p, );
 }
 
 /*
@@ -224,80 +183,46 @@ sbgp_asid(struct parse *p, const ASN1_IN
  * Returns zero on failure, non-zero on success.
  */
 static int
-sbgp_asnum(struct parse *p, const unsigned char *d, size_t dsz)
+sbgp_asnum(struct parse *p, const ASIdentifierChoice *aic)
 {
struct cert_as   as;
-   ASN1_TYPE   *t, *tt;
-   ASN1_SEQUENCE_ANY   *seq = NULL;
-   int  i, rc = 0;
-   const unsigned char *sv = d;
-
-   /* We can either be a null (inherit) or sequence. */
-
-   if ((t = d2i_ASN1_TYPE(NULL, , dsz)) == NULL) {
-   cryptowarnx("%s: RFC 3779 section 3.2.3.2: ASIdentifierChoice: "
-   "failed ASN.1 type parse", p->fn);
-   goto out;
-   }
-
-   /*
-* Section 3779 3.2.3.3 is to inherit with an ASN.1 NULL type,
-* which is the easy case.
-*/
+   const ASIdOrRanges  *aors = NULL;
+   const ASIdOrRange   *aor;
+   int  i;
 
-   switch 

Re: uvm_pagedequeue()

2022-05-10 Thread Mark Kettenis
> Date: Tue, 10 May 2022 18:45:21 +0200
> From: Martin Pieuchot 
> 
> On 05/05/22(Thu) 14:54, Martin Pieuchot wrote:
> > Diff below introduces a new wrapper to manipulate active/inactive page
> > queues. 
> > 
> > ok?
> 
> Anyone?

Sorry I started looking at this and got distracted.

I'm not sure about the changes to uvm_pageactivate().  It doesn't
quite match what NetBSD does, but I guess NetBSD assumes that
uvm_pageactiave() isn't called for a page that is already active?  And
that's something we can't guarantee?

The diff is correct though in the sense that it is equivalent to the
code we already have.  So if this definitely is the direction you want
to go:

ok kettenis@

> > Index: uvm/uvm_page.c
> > ===
> > RCS file: /cvs/src/sys/uvm/uvm_page.c,v
> > retrieving revision 1.165
> > diff -u -p -r1.165 uvm_page.c
> > --- uvm/uvm_page.c  4 May 2022 14:58:26 -   1.165
> > +++ uvm/uvm_page.c  5 May 2022 12:49:13 -
> > @@ -987,16 +987,7 @@ uvm_pageclean(struct vm_page *pg)
> > /*
> >  * now remove the page from the queues
> >  */
> > -   if (pg->pg_flags & PQ_ACTIVE) {
> > -   TAILQ_REMOVE(_active, pg, pageq);
> > -   flags_to_clear |= PQ_ACTIVE;
> > -   uvmexp.active--;
> > -   }
> > -   if (pg->pg_flags & PQ_INACTIVE) {
> > -   TAILQ_REMOVE(_inactive, pg, pageq);
> > -   flags_to_clear |= PQ_INACTIVE;
> > -   uvmexp.inactive--;
> > -   }
> > +   uvm_pagedequeue(pg);
> >  
> > /*
> >  * if the page was wired, unwire it now.
> > @@ -1243,16 +1234,7 @@ uvm_pagewire(struct vm_page *pg)
> > MUTEX_ASSERT_LOCKED();
> >  
> > if (pg->wire_count == 0) {
> > -   if (pg->pg_flags & PQ_ACTIVE) {
> > -   TAILQ_REMOVE(_active, pg, pageq);
> > -   atomic_clearbits_int(>pg_flags, PQ_ACTIVE);
> > -   uvmexp.active--;
> > -   }
> > -   if (pg->pg_flags & PQ_INACTIVE) {
> > -   TAILQ_REMOVE(_inactive, pg, pageq);
> > -   atomic_clearbits_int(>pg_flags, PQ_INACTIVE);
> > -   uvmexp.inactive--;
> > -   }
> > +   uvm_pagedequeue(pg);
> > uvmexp.wired++;
> > }
> > pg->wire_count++;
> > @@ -1324,28 +1306,32 @@ uvm_pageactivate(struct vm_page *pg)
> > KASSERT(uvm_page_owner_locked_p(pg));
> > MUTEX_ASSERT_LOCKED();
> >  
> > +   uvm_pagedequeue(pg);
> > +   if (pg->wire_count == 0) {
> > +   TAILQ_INSERT_TAIL(_active, pg, pageq);
> > +   atomic_setbits_int(>pg_flags, PQ_ACTIVE);
> > +   uvmexp.active++;
> > +
> > +   }
> > +}
> > +
> > +/*
> > + * uvm_pagedequeue: remove a page from any paging queue
> > + */
> > +void
> > +uvm_pagedequeue(struct vm_page *pg)
> > +{
> > +   if (pg->pg_flags & PQ_ACTIVE) {
> > +   TAILQ_REMOVE(_active, pg, pageq);
> > +   atomic_clearbits_int(>pg_flags, PQ_ACTIVE);
> > +   uvmexp.active--;
> > +   }
> > if (pg->pg_flags & PQ_INACTIVE) {
> > TAILQ_REMOVE(_inactive, pg, pageq);
> > atomic_clearbits_int(>pg_flags, PQ_INACTIVE);
> > uvmexp.inactive--;
> > }
> > -   if (pg->wire_count == 0) {
> > -   /*
> > -* if page is already active, remove it from list so we
> > -* can put it at tail.  if it wasn't active, then mark
> > -* it active and bump active count
> > -*/
> > -   if (pg->pg_flags & PQ_ACTIVE)
> > -   TAILQ_REMOVE(_active, pg, pageq);
> > -   else {
> > -   atomic_setbits_int(>pg_flags, PQ_ACTIVE);
> > -   uvmexp.active++;
> > -   }
> > -
> > -   TAILQ_INSERT_TAIL(_active, pg, pageq);
> > -   }
> >  }
> > -
> >  /*
> >   * uvm_pagezero: zero fill a page
> >   */
> > Index: uvm/uvm_page.h
> > ===
> > RCS file: /cvs/src/sys/uvm/uvm_page.h,v
> > retrieving revision 1.67
> > diff -u -p -r1.67 uvm_page.h
> > --- uvm/uvm_page.h  29 Jan 2022 06:25:33 -  1.67
> > +++ uvm/uvm_page.h  5 May 2022 12:49:13 -
> > @@ -224,6 +224,7 @@ boolean_t   uvm_page_physget(paddr_t *);
> >  #endif
> >  
> >  void   uvm_pageactivate(struct vm_page *);
> > +void   uvm_pagedequeue(struct vm_page *);
> >  vaddr_tuvm_pageboot_alloc(vsize_t);
> >  void   uvm_pagecopy(struct vm_page *, struct vm_page *);
> >  void   uvm_pagedeactivate(struct vm_page *);
> > 
> 
> 



rpki-client: shuffle two IP address functions down a bit

2022-05-10 Thread Theo Buehler
This moves two helper functions down so that the file starts with the
code parsing ASIdentifiers, then the code dealing with IPAddrBlocks.

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.74
diff -u -p -r1.74 cert.c
--- cert.c  10 May 2022 16:43:53 -  1.74
+++ cert.c  10 May 2022 16:44:44 -
@@ -54,34 +54,6 @@ extern ASN1_OBJECT   *manifest_oid;  /* 1.3
 extern ASN1_OBJECT *notify_oid;/* 1.3.6.1.5.5.7.48.13 (rpkiNotify) */
 
 /*
- * Append an IP address structure to our list of results.
- * This will also constrain us to having at most one inheritance
- * statement per AFI and also not have overlapping ranges (as prohibited
- * in section 2.2.3.6).
- * It does not make sure that ranges can't coalesce, that is, that any
- * two ranges abut each other.
- * This is warned against in section 2.2.3.6, but doesn't change the
- * semantics of the system.
- * Returns zero on failure (IP overlap) non-zero on success.
- */
-static int
-append_ip(struct parse *p, const struct cert_ip *ip)
-{
-   struct cert *res = p->res;
-
-   if (!ip_addr_check_overlap(ip, p->fn, p->res->ips, p->res->ipsz))
-   return 0;
-   if (res->ipsz >= MAX_IP_SIZE)
-   return 0;
-   res->ips = reallocarray(res->ips, res->ipsz + 1,
-   sizeof(struct cert_ip));
-   if (res->ips == NULL)
-   err(1, NULL);
-   res->ips[res->ipsz++] = *ip;
-   return 1;
-}
-
-/*
  * Append an AS identifier structure to our list of results.
  * Makes sure that the identifiers do not overlap or improperly inherit
  * as defined by RFC 3779 section 3.3.
@@ -102,28 +74,6 @@ append_as(struct parse *p, const struct 
 }
 
 /*
- * Construct a RFC 3779 2.2.3.8 range from its bit string.
- * Returns zero on failure, non-zero on success.
- */
-static int
-sbgp_addr(struct parse *p, struct cert_ip *ip, const ASN1_BIT_STRING *bs)
-{
-   if (!ip_addr_parse(bs, ip->afi, p->fn, >ip)) {
-   warnx("%s: RFC 3779 section 2.2.3.8: IPAddress: "
-   "invalid IP address", p->fn);
-   return 0;
-   }
-
-   if (!ip_cert_compose_ranges(ip)) {
-   warnx("%s: RFC 3779 section 2.2.3.8: IPAddress: "
-   "IP address range reversed", p->fn);
-   return 0;
-   }
-
-   return append_ip(p, ip);
-}
-
-/*
  * Parse a range of addresses as in 3.2.3.8.
  * Returns zero on failure, non-zero on success.
  */
@@ -414,6 +364,56 @@ out:
sk_ASN1_TYPE_pop_free(sseq, ASN1_TYPE_free);
free(sv);
return rc;
+}
+
+/*
+ * Append an IP address structure to our list of results.
+ * This will also constrain us to having at most one inheritance
+ * statement per AFI and also not have overlapping ranges (as prohibited
+ * in section 2.2.3.6).
+ * It does not make sure that ranges can't coalesce, that is, that any
+ * two ranges abut each other.
+ * This is warned against in section 2.2.3.6, but doesn't change the
+ * semantics of the system.
+ * Returns zero on failure (IP overlap) non-zero on success.
+ */
+static int
+append_ip(struct parse *p, const struct cert_ip *ip)
+{
+   struct cert *res = p->res;
+
+   if (!ip_addr_check_overlap(ip, p->fn, p->res->ips, p->res->ipsz))
+   return 0;
+   if (res->ipsz >= MAX_IP_SIZE)
+   return 0;
+   res->ips = reallocarray(res->ips, res->ipsz + 1,
+   sizeof(struct cert_ip));
+   if (res->ips == NULL)
+   err(1, NULL);
+   res->ips[res->ipsz++] = *ip;
+   return 1;
+}
+
+/*
+ * Construct a RFC 3779 2.2.3.8 range from its bit string.
+ * Returns zero on failure, non-zero on success.
+ */
+static int
+sbgp_addr(struct parse *p, struct cert_ip *ip, const ASN1_BIT_STRING *bs)
+{
+   if (!ip_addr_parse(bs, ip->afi, p->fn, >ip)) {
+   warnx("%s: RFC 3779 section 2.2.3.8: IPAddress: "
+   "invalid IP address", p->fn);
+   return 0;
+   }
+
+   if (!ip_cert_compose_ranges(ip)) {
+   warnx("%s: RFC 3779 section 2.2.3.8: IPAddress: "
+   "IP address range reversed", p->fn);
+   return 0;
+   }
+
+   return append_ip(p, ip);
 }
 
 /*



Re: uvm_pagedequeue()

2022-05-10 Thread Martin Pieuchot
On 05/05/22(Thu) 14:54, Martin Pieuchot wrote:
> Diff below introduces a new wrapper to manipulate active/inactive page
> queues. 
> 
> ok?

Anyone?

> Index: uvm/uvm_page.c
> ===
> RCS file: /cvs/src/sys/uvm/uvm_page.c,v
> retrieving revision 1.165
> diff -u -p -r1.165 uvm_page.c
> --- uvm/uvm_page.c4 May 2022 14:58:26 -   1.165
> +++ uvm/uvm_page.c5 May 2022 12:49:13 -
> @@ -987,16 +987,7 @@ uvm_pageclean(struct vm_page *pg)
>   /*
>* now remove the page from the queues
>*/
> - if (pg->pg_flags & PQ_ACTIVE) {
> - TAILQ_REMOVE(_active, pg, pageq);
> - flags_to_clear |= PQ_ACTIVE;
> - uvmexp.active--;
> - }
> - if (pg->pg_flags & PQ_INACTIVE) {
> - TAILQ_REMOVE(_inactive, pg, pageq);
> - flags_to_clear |= PQ_INACTIVE;
> - uvmexp.inactive--;
> - }
> + uvm_pagedequeue(pg);
>  
>   /*
>* if the page was wired, unwire it now.
> @@ -1243,16 +1234,7 @@ uvm_pagewire(struct vm_page *pg)
>   MUTEX_ASSERT_LOCKED();
>  
>   if (pg->wire_count == 0) {
> - if (pg->pg_flags & PQ_ACTIVE) {
> - TAILQ_REMOVE(_active, pg, pageq);
> - atomic_clearbits_int(>pg_flags, PQ_ACTIVE);
> - uvmexp.active--;
> - }
> - if (pg->pg_flags & PQ_INACTIVE) {
> - TAILQ_REMOVE(_inactive, pg, pageq);
> - atomic_clearbits_int(>pg_flags, PQ_INACTIVE);
> - uvmexp.inactive--;
> - }
> + uvm_pagedequeue(pg);
>   uvmexp.wired++;
>   }
>   pg->wire_count++;
> @@ -1324,28 +1306,32 @@ uvm_pageactivate(struct vm_page *pg)
>   KASSERT(uvm_page_owner_locked_p(pg));
>   MUTEX_ASSERT_LOCKED();
>  
> + uvm_pagedequeue(pg);
> + if (pg->wire_count == 0) {
> + TAILQ_INSERT_TAIL(_active, pg, pageq);
> + atomic_setbits_int(>pg_flags, PQ_ACTIVE);
> + uvmexp.active++;
> +
> + }
> +}
> +
> +/*
> + * uvm_pagedequeue: remove a page from any paging queue
> + */
> +void
> +uvm_pagedequeue(struct vm_page *pg)
> +{
> + if (pg->pg_flags & PQ_ACTIVE) {
> + TAILQ_REMOVE(_active, pg, pageq);
> + atomic_clearbits_int(>pg_flags, PQ_ACTIVE);
> + uvmexp.active--;
> + }
>   if (pg->pg_flags & PQ_INACTIVE) {
>   TAILQ_REMOVE(_inactive, pg, pageq);
>   atomic_clearbits_int(>pg_flags, PQ_INACTIVE);
>   uvmexp.inactive--;
>   }
> - if (pg->wire_count == 0) {
> - /*
> -  * if page is already active, remove it from list so we
> -  * can put it at tail.  if it wasn't active, then mark
> -  * it active and bump active count
> -  */
> - if (pg->pg_flags & PQ_ACTIVE)
> - TAILQ_REMOVE(_active, pg, pageq);
> - else {
> - atomic_setbits_int(>pg_flags, PQ_ACTIVE);
> - uvmexp.active++;
> - }
> -
> - TAILQ_INSERT_TAIL(_active, pg, pageq);
> - }
>  }
> -
>  /*
>   * uvm_pagezero: zero fill a page
>   */
> Index: uvm/uvm_page.h
> ===
> RCS file: /cvs/src/sys/uvm/uvm_page.h,v
> retrieving revision 1.67
> diff -u -p -r1.67 uvm_page.h
> --- uvm/uvm_page.h29 Jan 2022 06:25:33 -  1.67
> +++ uvm/uvm_page.h5 May 2022 12:49:13 -
> @@ -224,6 +224,7 @@ boolean_t uvm_page_physget(paddr_t *);
>  #endif
>  
>  void uvm_pageactivate(struct vm_page *);
> +void uvm_pagedequeue(struct vm_page *);
>  vaddr_t  uvm_pageboot_alloc(vsize_t);
>  void uvm_pagecopy(struct vm_page *, struct vm_page *);
>  void uvm_pagedeactivate(struct vm_page *);
> 



Re: rpki-client: deserialize IPAddrBlocks in libcrypto

2022-05-10 Thread Claudio Jeker
On Tue, May 10, 2022 at 01:27:17PM +0200, Theo Buehler wrote:
> This is a straightforward conversion to letting libcrypto's RFC 3779
> code parse a cert's IPAddrBlocks. The magic happens in X509V3_EXT_d2i()
> in sbgp_ipaddrblk(). After that, we simply have to walk the returned
> structure. The fact that it parsed only means that it is well-formed as
> far as the templating goes. Notably, at this point we will not yet have
> called X509v3_addr_is_canonical(), so no additional validation of the
> extension has happened beforehand.
> 
> This does not use any of the X509v3_addr_* API apart from the types.
> 
> There's more cleanup that can be done, e.g. the reaching through and
> copying of struct ip is a bit weird. This also fixes at least one leak
> in sbgp_addr_range().

Lovley. The new code is so much shorter. Also the necessary sacrifice to
understand the code went from a rhino to a chicken. Big improvement.

OK claudio@
 
> Index: cert.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 cert.c
> --- cert.c21 Apr 2022 12:59:03 -  1.71
> +++ cert.c10 May 2022 10:29:57 -
> @@ -423,49 +423,18 @@ out:
>   */
>  static int
>  sbgp_addr_range(struct parse *p, struct cert_ip *ip,
> - const unsigned char *d, size_t dsz)
> +const IPAddressRange *range)
>  {
> - ASN1_SEQUENCE_ANY   *seq;
> - const ASN1_TYPE *t;
> - int  rc = 0;
> -
> - if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, , dsz)) == NULL) {
> - cryptowarnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
> - "failed ASN.1 sequence parse", p->fn);
> - goto out;
> - }
> - if (sk_ASN1_TYPE_num(seq) != 2) {
> - warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
> - "want 2 elements, have %d", p->fn, sk_ASN1_TYPE_num(seq));
> - goto out;
> - }
> -
> - t = sk_ASN1_TYPE_value(seq, 0);
> - if (t->type != V_ASN1_BIT_STRING) {
> - warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
> - "want ASN.1 bit string, have %s (NID %d)",
> - p->fn, ASN1_tag2str(t->type), t->type);
> - goto out;
> - }
> - if (!ip_addr_parse(t->value.bit_string,
> - ip->afi, p->fn, >range.min)) {
> + if (!ip_addr_parse(range->min, ip->afi, p->fn, >range.min)) {
>   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
>   "invalid IP address", p->fn);
> - goto out;
> + return 0;
>   }
>  
> - t = sk_ASN1_TYPE_value(seq, 1);
> - if (t->type != V_ASN1_BIT_STRING) {
> - warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
> - "want ASN.1 bit string, have %s (NID %d)",
> - p->fn, ASN1_tag2str(t->type), t->type);
> - goto out;
> - }
> - if (!ip_addr_parse(t->value.bit_string,
> - ip->afi, p->fn, >range.max)) {
> + if (!ip_addr_parse(range->max, ip->afi, p->fn, >range.max)) {
>   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
>   "invalid IP address", p->fn);
> - goto out;
> + return 0;
>   }
>  
>   if (!ip_cert_compose_ranges(ip)) {
> @@ -474,10 +443,7 @@ sbgp_addr_range(struct parse *p, struct 
>   return 0;
>   }
>  
> - rc = append_ip(p, ip);
> -out:
> - sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free);
> - return rc;
> + return append_ip(p, ip);
>  }
>  
>  /*
> @@ -488,48 +454,35 @@ out:
>   */
>  static int
>  sbgp_addr_or_range(struct parse *p, struct cert_ip *ip,
> - const unsigned char *d, size_t dsz)
> +const IPAddressOrRanges *aors)
>  {
>   struct cert_ip   nip;
> - ASN1_SEQUENCE_ANY   *seq;
> - const ASN1_TYPE *t;
> + const IPAddressOrRange  *aor;
>   int  i, rc = 0;
>  
> - if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, , dsz)) == NULL) {
> - cryptowarnx("%s: RFC 3779 section 2.2.3.7: IPAddressOrRange: "
> - "failed ASN.1 sequence parse", p->fn);
> - goto out;
> - }
> -
> - /* Either RFC 3779 2.2.3.8 or 2.2.3.9. */
> -
> - for (i = 0; i < sk_ASN1_TYPE_num(seq); i++) {
> + for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
>   nip = *ip;
> - t = sk_ASN1_TYPE_value(seq, i);
> - switch (t->type) {
> - case V_ASN1_BIT_STRING:
> + aor = sk_IPAddressOrRange_value(aors, i);
> + switch (aor->type) {
> + case IPAddressOrRange_addressPrefix:
>   nip.type = CERT_IP_ADDR;
> - if (!sbgp_addr(p, , t->value.bit_string))
> + if (!sbgp_addr(p, , aor->u.addressPrefix))
>   goto out;
>   break;
> - 

Re: rpki-client: three leaks in cert.c

2022-05-10 Thread Claudio Jeker
On Tue, May 10, 2022 at 01:47:44PM +0200, Theo Buehler wrote:
> In sbgp_asrange() and sbgp_addr_range(), the ASN1_SEQUENCE_ANY *seq is
> potentially leaked due to early return 0 instead of goto out. The last
> hunk collides with my IPAddrBlocks diff. Sending this out so I don't
> forget.
> 
> Index: cert.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
> retrieving revision 1.71
> diff -u -p -r1.71 cert.c
> --- cert.c21 Apr 2022 12:59:03 -  1.71
> +++ cert.c10 May 2022 11:35:57 -
> @@ -161,7 +161,7 @@ sbgp_asrange(struct parse *p, const unsi
>   if (!as_id_parse(t->value.integer, )) {
>   warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
>   "malformed AS identifier", p->fn);
> - return 0;
> + goto out;
>   }
>  
>   t = sk_ASN1_TYPE_value(seq, 1);
> @@ -174,7 +174,7 @@ sbgp_asrange(struct parse *p, const unsi
>   if (!as_id_parse(t->value.integer, )) {
>   warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
>   "malformed AS identifier", p->fn);
> - return 0;
> + goto out;
>   }
>  
>   if (as.range.max == as.range.min) {
> @@ -471,7 +471,7 @@ sbgp_addr_range(struct parse *p, struct 
>   if (!ip_cert_compose_ranges(ip)) {
>   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
>   "IP address range reversed", p->fn);
> - return 0;
> + goto out;
>   }
>  
>   rc = append_ip(p, ip);
> 

OK claudio@
-- 
:wq Claudio



Re: [External] : Re: move memory allocation in pfr_add_tables() outside of NET_LOCK()/PF_LOCK()

2022-05-10 Thread Alexander Bluhm
On Tue, May 10, 2022 at 12:40:39AM +0200, Alexandr Nedvedicky wrote:
> updated diff is below.

Although this makes the code more complex, I see no simple solution.
We must get the sleeps out of the pf lock.  As seen from the mail
on bugs@, sleeping in pf is not a good thing.  Also mbuhl@ is hunting
some sleeping bugs with copyin and copyout from syzkaller.  So this
is the right direction.

OK bluhm@

> 8<---8<---8<--8<
> diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
> index 8315b115474..1f036e1368f 100644
> --- a/sys/net/pf_ioctl.c
> +++ b/sys/net/pf_ioctl.c
> @@ -2217,12 +2217,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int 
> flags, struct proc *p)
>   error = ENODEV;
>   goto fail;
>   }
> - NET_LOCK();
> - PF_LOCK();
>   error = pfr_add_tables(io->pfrio_buffer, io->pfrio_size,
>   >pfrio_nadd, io->pfrio_flags | PFR_FLAG_USERIOCTL);
> - PF_UNLOCK();
> - NET_UNLOCK();
>   break;
>   }
>  
> diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
> index fb23bcabe04..d0e42ca62ba 100644
> --- a/sys/net/pf_table.c
> +++ b/sys/net/pf_table.c
> @@ -189,6 +189,7 @@ void   pfr_clstats_ktable(struct 
> pfr_ktable *, time_t, int);
>  struct pfr_ktable*pfr_create_ktable(struct pfr_table *, time_t, int,
>   int);
>  void  pfr_destroy_ktables(struct pfr_ktableworkq *, int);
> +void  pfr_destroy_ktables_aux(struct pfr_ktableworkq *);
>  void  pfr_destroy_ktable(struct pfr_ktable *, int);
>  int   pfr_ktable_compare(struct pfr_ktable *,
>   struct pfr_ktable *);
> @@ -1493,14 +1494,16 @@ pfr_clr_tables(struct pfr_table *filter, int *ndel, 
> int flags)
>  int
>  pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
>  {
> - struct pfr_ktableworkq   addq, changeq;
> - struct pfr_ktable   *p, *q, *r, key;
> + struct pfr_ktableworkq   addq, changeq, auxq;
> + struct pfr_ktable   *p, *q, *r, *n, *w, key;
>   int  i, rv, xadd = 0;
>   time_t   tzero = gettime();
>  
>   ACCEPT_FLAGS(flags, PFR_FLAG_DUMMY);
>   SLIST_INIT();
>   SLIST_INIT();
> + SLIST_INIT();
> + /* pre-allocate all memory outside of locks */
>   for (i = 0; i < size; i++) {
>   YIELD(flags & PFR_FLAG_USERIOCTL);
>   if (COPYIN(tbl+i, _t, sizeof(key.pfrkt_t), flags))
> @@ -1509,65 +1512,149 @@ pfr_add_tables(struct pfr_table *tbl, int size, int 
> *nadd, int flags)
>   flags & PFR_FLAG_USERIOCTL))
>   senderr(EINVAL);
>   key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
> - p = RB_FIND(pfr_ktablehead, _ktables, );
> + p = pfr_create_ktable(_t, tzero, 0,
> + !(flags & PFR_FLAG_USERIOCTL));
> + if (p == NULL)
> + senderr(ENOMEM);
> +
> + /*
> +  * Note: we also pre-allocate a root table here. We keep it
> +  * at ->pfrkt_root, which we must not forget about.
> +  */
> + key.pfrkt_flags = 0;
> + memset(key.pfrkt_anchor, 0, sizeof(key.pfrkt_anchor));
> + p->pfrkt_root = pfr_create_ktable(_t, 0, 0,
> + !(flags & PFR_FLAG_USERIOCTL));
> + if (p->pfrkt_root == NULL) {
> + pfr_destroy_ktable(p, 0);
> + senderr(ENOMEM);
> + }
> +
> + SLIST_FOREACH(q, , pfrkt_workq) {
> + if (!pfr_ktable_compare(p, q)) {
> + /*
> +  * We need no lock here, because `p` is empty,
> +  * there are no rules or shadow tables
> +  * attached.
> +  */
> + pfr_destroy_ktable(p->pfrkt_root, 0);
> + p->pfrkt_root = NULL;
> + pfr_destroy_ktable(p, 0);
> + p = NULL;
> + break;
> + }
> + }
> + if (q != NULL)
> + continue;
> +
> + SLIST_INSERT_HEAD(, p, pfrkt_workq);
> + }
> +
> + /*
> +  * auxq contains freshly allocated tables with no dups.
> +  * also note there are no rulesets attached, because
> +  * the attach operation requires PF_LOCK().
> +  */
> + NET_LOCK();
> + PF_LOCK();
> + SLIST_FOREACH_SAFE(n, , pfrkt_workq, w) {
> + p = RB_FIND(pfr_ktablehead, _ktables, n);
>   if (p == NULL) {
> - p = pfr_create_ktable(_t, tzero, 1,
> - !(flags & PFR_FLAG_USERIOCTL));
> -  

rpki-client: three leaks in cert.c

2022-05-10 Thread Theo Buehler
In sbgp_asrange() and sbgp_addr_range(), the ASN1_SEQUENCE_ANY *seq is
potentially leaked due to early return 0 instead of goto out. The last
hunk collides with my IPAddrBlocks diff. Sending this out so I don't
forget.

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.71
diff -u -p -r1.71 cert.c
--- cert.c  21 Apr 2022 12:59:03 -  1.71
+++ cert.c  10 May 2022 11:35:57 -
@@ -161,7 +161,7 @@ sbgp_asrange(struct parse *p, const unsi
if (!as_id_parse(t->value.integer, )) {
warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
"malformed AS identifier", p->fn);
-   return 0;
+   goto out;
}
 
t = sk_ASN1_TYPE_value(seq, 1);
@@ -174,7 +174,7 @@ sbgp_asrange(struct parse *p, const unsi
if (!as_id_parse(t->value.integer, )) {
warnx("%s: RFC 3779 section 3.2.3.8 (via RFC 1930): "
"malformed AS identifier", p->fn);
-   return 0;
+   goto out;
}
 
if (as.range.max == as.range.min) {
@@ -471,7 +471,7 @@ sbgp_addr_range(struct parse *p, struct 
if (!ip_cert_compose_ranges(ip)) {
warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
"IP address range reversed", p->fn);
-   return 0;
+   goto out;
}
 
rc = append_ip(p, ip);



rpki-client: deserialize IPAddrBlocks in libcrypto

2022-05-10 Thread Theo Buehler
This is a straightforward conversion to letting libcrypto's RFC 3779
code parse a cert's IPAddrBlocks. The magic happens in X509V3_EXT_d2i()
in sbgp_ipaddrblk(). After that, we simply have to walk the returned
structure. The fact that it parsed only means that it is well-formed as
far as the templating goes. Notably, at this point we will not yet have
called X509v3_addr_is_canonical(), so no additional validation of the
extension has happened beforehand.

This does not use any of the X509v3_addr_* API apart from the types.

There's more cleanup that can be done, e.g. the reaching through and
copying of struct ip is a bit weird. This also fixes at least one leak
in sbgp_addr_range().

Index: cert.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/cert.c,v
retrieving revision 1.71
diff -u -p -r1.71 cert.c
--- cert.c  21 Apr 2022 12:59:03 -  1.71
+++ cert.c  10 May 2022 10:29:57 -
@@ -423,49 +423,18 @@ out:
  */
 static int
 sbgp_addr_range(struct parse *p, struct cert_ip *ip,
-   const unsigned char *d, size_t dsz)
+const IPAddressRange *range)
 {
-   ASN1_SEQUENCE_ANY   *seq;
-   const ASN1_TYPE *t;
-   int  rc = 0;
-
-   if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, , dsz)) == NULL) {
-   cryptowarnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
-   "failed ASN.1 sequence parse", p->fn);
-   goto out;
-   }
-   if (sk_ASN1_TYPE_num(seq) != 2) {
-   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
-   "want 2 elements, have %d", p->fn, sk_ASN1_TYPE_num(seq));
-   goto out;
-   }
-
-   t = sk_ASN1_TYPE_value(seq, 0);
-   if (t->type != V_ASN1_BIT_STRING) {
-   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
-   "want ASN.1 bit string, have %s (NID %d)",
-   p->fn, ASN1_tag2str(t->type), t->type);
-   goto out;
-   }
-   if (!ip_addr_parse(t->value.bit_string,
-   ip->afi, p->fn, >range.min)) {
+   if (!ip_addr_parse(range->min, ip->afi, p->fn, >range.min)) {
warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
"invalid IP address", p->fn);
-   goto out;
+   return 0;
}
 
-   t = sk_ASN1_TYPE_value(seq, 1);
-   if (t->type != V_ASN1_BIT_STRING) {
-   warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
-   "want ASN.1 bit string, have %s (NID %d)",
-   p->fn, ASN1_tag2str(t->type), t->type);
-   goto out;
-   }
-   if (!ip_addr_parse(t->value.bit_string,
-   ip->afi, p->fn, >range.max)) {
+   if (!ip_addr_parse(range->max, ip->afi, p->fn, >range.max)) {
warnx("%s: RFC 3779 section 2.2.3.9: IPAddressRange: "
"invalid IP address", p->fn);
-   goto out;
+   return 0;
}
 
if (!ip_cert_compose_ranges(ip)) {
@@ -474,10 +443,7 @@ sbgp_addr_range(struct parse *p, struct 
return 0;
}
 
-   rc = append_ip(p, ip);
-out:
-   sk_ASN1_TYPE_pop_free(seq, ASN1_TYPE_free);
-   return rc;
+   return append_ip(p, ip);
 }
 
 /*
@@ -488,48 +454,35 @@ out:
  */
 static int
 sbgp_addr_or_range(struct parse *p, struct cert_ip *ip,
-   const unsigned char *d, size_t dsz)
+const IPAddressOrRanges *aors)
 {
struct cert_ip   nip;
-   ASN1_SEQUENCE_ANY   *seq;
-   const ASN1_TYPE *t;
+   const IPAddressOrRange  *aor;
int  i, rc = 0;
 
-   if ((seq = d2i_ASN1_SEQUENCE_ANY(NULL, , dsz)) == NULL) {
-   cryptowarnx("%s: RFC 3779 section 2.2.3.7: IPAddressOrRange: "
-   "failed ASN.1 sequence parse", p->fn);
-   goto out;
-   }
-
-   /* Either RFC 3779 2.2.3.8 or 2.2.3.9. */
-
-   for (i = 0; i < sk_ASN1_TYPE_num(seq); i++) {
+   for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) {
nip = *ip;
-   t = sk_ASN1_TYPE_value(seq, i);
-   switch (t->type) {
-   case V_ASN1_BIT_STRING:
+   aor = sk_IPAddressOrRange_value(aors, i);
+   switch (aor->type) {
+   case IPAddressOrRange_addressPrefix:
nip.type = CERT_IP_ADDR;
-   if (!sbgp_addr(p, , t->value.bit_string))
+   if (!sbgp_addr(p, , aor->u.addressPrefix))
goto out;
break;
-   case V_ASN1_SEQUENCE:
+   case IPAddressOrRange_addressRange:
nip.type = CERT_IP_RANGE;
-   d = t->value.asn1_string->data;
-   dsz = t->value.asn1_string->length;
-   if (!sbgp_addr_range(p, , d, 

Re: rpki-client: consider CA:FALSE certs to be invalid

2022-05-10 Thread Theo Buehler
On Tue, May 10, 2022 at 08:32:15AM +, Job Snijders wrote:
> Hi,
> 
> Following this errata report https://www.rfc-editor.org/errata/eid6854
> 
> If the Basic Constraints extension is present, and the certificate is
> *not* a CA - as determined by X509_check_ca(3), leave the purpose as
> CERT_PURPOSE_INVALID.

LibreSSL's X509_check_ca() has a bug that will make it return 1 if
x509v3_cache_extensions() fails... That shouldn't affect us here since
x should already have its extensions cached.

I think for your purposes it is better to check the extension flags
instead of parsing the basic constraints extension another time:

if (X509_get_extension_flags(x) & EXFLAG_BCONS) {
warnx("%s: Basic Constraints in non-CA cert", fn);
goto out;
}

and we should probably consider rewriting this function to inspect
extension flags also for the CA case.

> 
> While there, use the value name rather than 0.
> 
> OK?
> 
> Kind regards,
> 
> Job
> 
> Index: x509.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
> retrieving revision 1.42
> diff -u -p -r1.42 x509.c
> --- x509.c9 May 2022 17:13:06 -   1.42
> +++ x509.c10 May 2022 08:31:03 -
> @@ -182,15 +182,22 @@ out:
>  enum cert_purpose
>  x509_get_purpose(X509 *x, const char *fn)
>  {
> + BASIC_CONSTRAINTS   *bc = NULL;
>   EXTENDED_KEY_USAGE  *eku = NULL;
>   int  crit;
> - enum cert_purposepurpose = 0;
> + enum cert_purposepurpose = CERT_PURPOSE_INVALID;
>  
>   if (X509_check_ca(x) == 1) {
>   purpose = CERT_PURPOSE_CA;
>   goto out;
>   }
>  
> + bc = X509_get_ext_d2i(x, NID_basic_constraints, , NULL);
> + if (bc != NULL) {
> + warnx("%s: Basic Constraints ext in CA:FALSE cert", fn);
> + goto out;
> + }
> +
>   eku = X509_get_ext_d2i(x, NID_ext_key_usage, , NULL);
>   if (eku == NULL) {
>   warnx("%s: EKU: extension missing", fn);
> @@ -212,6 +219,7 @@ x509_get_purpose(X509 *x, const char *fn
>   }
>  
>   out:
> + BASIC_CONSTRAINTS_free(bc);
>   EXTENDED_KEY_USAGE_free(eku);
>   return purpose;
>  }
> 



rpki-client: consider CA:FALSE certs to be invalid

2022-05-10 Thread Job Snijders
Hi,

Following this errata report https://www.rfc-editor.org/errata/eid6854

If the Basic Constraints extension is present, and the certificate is
*not* a CA - as determined by X509_check_ca(3), leave the purpose as
CERT_PURPOSE_INVALID.

While there, use the value name rather than 0.

OK?

Kind regards,

Job

Index: x509.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/x509.c,v
retrieving revision 1.42
diff -u -p -r1.42 x509.c
--- x509.c  9 May 2022 17:13:06 -   1.42
+++ x509.c  10 May 2022 08:31:03 -
@@ -182,15 +182,22 @@ out:
 enum cert_purpose
 x509_get_purpose(X509 *x, const char *fn)
 {
+   BASIC_CONSTRAINTS   *bc = NULL;
EXTENDED_KEY_USAGE  *eku = NULL;
int  crit;
-   enum cert_purposepurpose = 0;
+   enum cert_purposepurpose = CERT_PURPOSE_INVALID;
 
if (X509_check_ca(x) == 1) {
purpose = CERT_PURPOSE_CA;
goto out;
}
 
+   bc = X509_get_ext_d2i(x, NID_basic_constraints, , NULL);
+   if (bc != NULL) {
+   warnx("%s: Basic Constraints ext in CA:FALSE cert", fn);
+   goto out;
+   }
+
eku = X509_get_ext_d2i(x, NID_ext_key_usage, , NULL);
if (eku == NULL) {
warnx("%s: EKU: extension missing", fn);
@@ -212,6 +219,7 @@ x509_get_purpose(X509 *x, const char *fn
}
 
  out:
+   BASIC_CONSTRAINTS_free(bc);
EXTENDED_KEY_USAGE_free(eku);
return purpose;
 }



Re: I got the RALINK RT5372 usb wifi adapter working

2022-05-10 Thread Stefan Sperling
On Mon, May 09, 2022 at 08:17:35PM +, molotov31337 wrote:
> I recently picked up a Panda Wireless PAU06 and got it working, can this be 
> committed?
> Here is the cvs diff

Committed, thanks!

> Index: usbdevs
> ===
> RCS file: /cvs/src/sys/dev/usb/usbdevs,v
> retrieving revision 1.745
> diff -u -p -u -r1.745 usbdevs
> --- usbdevs 24 Dec 2021 06:18:11 - 1.745
> +++ usbdevs 9 May 2022 20:12:42 -
> @@ -3731,6 +3731,7 @@ product RALINK RT3370 0x3370 RT3370
> product RALINK RT3572 0x3572 RT3572
> product RALINK RT3573 0x3573 RT3573
> product RALINK RT5370 0x5370 RT5370
> +product RALINK RT5372 0x5372 RT5372
> product RALINK RT5572 0x5572 RT5572
> product RALINK MT7601 0x7601 MT7601
> product RALINK MT7601_2 0x760a MT7601
> Index: if_run.c
> ===
> RCS file: /cvs/src/sys/dev/usb/if_run.c,v
> retrieving revision 1.135
> diff -u -p -u -r1.135 if_run.c
> --- if_run.c 22 Nov 2021 10:17:14 - 1.135
> +++ if_run.c 9 May 2022 20:12:43 -
> @@ -259,6 +259,7 @@ static const struct usb_devno run_devs[]
> USB_ID(RALINK, RT3572),
> USB_ID(RALINK, RT3573),
> USB_ID(RALINK, RT5370),
> + USB_ID(RALINK, RT5372),
> USB_ID(RALINK, RT5572),
> USB_ID(RALINK, RT8070), USB_ID(SAMSUNG, WIS09ABGN),
> 
> And the device shows up in dmesg as
> run0 at uhub0 port 4 configuration 1 interface 0 "Ralink 802.11 n WLAN" rev 
> 2.00/1.01 addr 2
> run0: MAC/BBP RT5392 (rev 0x0223), RF RT5372 (MIMO 2T2R), address 
> 9c:ef:d5:fa:4b:15
> 
> Sent with [ProtonMail](https://protonmail.com/) secure email.



fix mac address on iwx(4) AX210

2022-05-10 Thread Stefan Sperling
As noticed by jsg@ and kevlo@ we use a bad MAC address on AX210 devices.
Patch below fixes the issue on AX210, and still works on AX200.

The old way of reading the MAC no longer works on AX210; apparently this
new way of reading the MAC was introduced in the 9k hw generation but the
old way was still working until now.

ok?

diff 04382ee86a01509dce834178b7ab1460d3539207 
37ed6bbfb5c966e24cc7dbbe8dd40222aac69407
blob - b3ea3675ae9dc65b56a1c90ab7f92c1c0a4f3a8f
blob + 9e94f17a9fc41ca7c3ce1096497ccc478f958197
--- sys/dev/pci/if_iwx.c
+++ sys/dev/pci/if_iwx.c
@@ -341,8 +341,9 @@ voidiwx_sta_tx_agg_start(struct iwx_softc *, struct 
i
uint8_t);
 void   iwx_ba_task(void *);
 
-intiwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
+void   iwx_set_mac_addr_from_csr(struct iwx_softc *, struct iwx_nvm_data *);
 intiwx_is_valid_mac_addr(const uint8_t *);
+void   iwx_flip_hw_address(uint32_t, uint32_t, uint8_t *);
 intiwx_nvm_get(struct iwx_softc *);
 intiwx_load_firmware(struct iwx_softc *);
 intiwx_start_fw(struct iwx_softc *);
@@ -3688,31 +3689,33 @@ iwx_ampdu_tx_start(struct ieee80211com *ic, struct iee
return EBUSY;
 }
 
-/* Read the mac address from WFMP registers. */
-int
+void
 iwx_set_mac_addr_from_csr(struct iwx_softc *sc, struct iwx_nvm_data *data)
 {
-   const uint8_t *hw_addr;
uint32_t mac_addr0, mac_addr1;
 
+   memset(data->hw_addr, 0, sizeof(data->hw_addr));
+
if (!iwx_nic_lock(sc))
-   return EBUSY;
+   return;
 
-   mac_addr0 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_0));
-   mac_addr1 = htole32(iwx_read_prph(sc, IWX_WFMP_MAC_ADDR_1));
+   mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_STRAP(sc)));
+   mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_STRAP(sc)));
 
-   hw_addr = (const uint8_t *)_addr0;
-   data->hw_addr[0] = hw_addr[3];
-   data->hw_addr[1] = hw_addr[2];
-   data->hw_addr[2] = hw_addr[1];
-   data->hw_addr[3] = hw_addr[0];
+   iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 
-   hw_addr = (const uint8_t *)_addr1;
-   data->hw_addr[4] = hw_addr[1];
-   data->hw_addr[5] = hw_addr[0];
+   /* If OEM fused a valid address, use it instead of the one in OTP. */
+   if (iwx_is_valid_mac_addr(data->hw_addr)) {
+   iwx_nic_unlock(sc);
+   return;
+   }
 
+   mac_addr0 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR0_OTP(sc)));
+   mac_addr1 = htole32(IWX_READ(sc, IWX_CSR_MAC_ADDR1_OTP(sc)));
+
+   iwx_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
+
iwx_nic_unlock(sc);
-   return 0;
 }
 
 int
@@ -3728,6 +3731,22 @@ iwx_is_valid_mac_addr(const uint8_t *addr)
!ETHER_IS_MULTICAST(addr));
 }
 
+void
+iwx_flip_hw_address(uint32_t mac_addr0, uint32_t mac_addr1, uint8_t *dest)
+{
+   const uint8_t *hw_addr;
+
+   hw_addr = (const uint8_t *)_addr0;
+   dest[0] = hw_addr[3];
+   dest[1] = hw_addr[2];
+   dest[2] = hw_addr[1];
+   dest[3] = hw_addr[0];
+
+   hw_addr = (const uint8_t *)_addr1;
+   dest[4] = hw_addr[1];
+   dest[5] = hw_addr[0];
+}
+
 int
 iwx_nvm_get(struct iwx_softc *sc)
 {
@@ -10654,6 +10673,8 @@ iwx_attach(struct device *parent, struct device *self,
}
}
 
+   sc->mac_addr_from_csr = 0x380; /* differs on BZ hw generation */
+
if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) {
sc->sc_umac_prph_offset = 0x30;
sc->max_tfd_queue_size = IWX_TFD_QUEUE_SIZE_MAX_GEN3;
blob - 6ddfb14e5eb9240cc82ea07d12a6e5c846167586
blob + 0f1948913a39bee6956603e3e322b9961615f038
--- sys/dev/pci/if_iwxreg.h
+++ sys/dev/pci/if_iwxreg.h
@@ -1160,6 +1160,12 @@ enum msix_ivar_for_cause {
 #define IWX_MSIX_AUTO_CLEAR_CAUSE  (0 << 7)
 #define IWX_MSIX_NON_AUTO_CLEAR_CAUSE  (1 << 7)
 
+#define IWX_CSR_ADDR_BASE(sc)  ((sc)->mac_addr_from_csr)
+#define IWX_CSR_MAC_ADDR0_OTP(sc)  (IWX_CSR_ADDR_BASE(sc) + 0x00)
+#define IWX_CSR_MAC_ADDR1_OTP(sc)  (IWX_CSR_ADDR_BASE(sc) + 0x04)
+#define IWX_CSR_MAC_ADDR0_STRAP(sc)(IWX_CSR_ADDR_BASE(sc) + 0x08)
+#define IWX_CSR_MAC_ADDR1_STRAP(sc)(IWX_CSR_ADDR_BASE(sc) + 0x0c)
+
 /**
  * uCode API flags
  * @IWX_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously
blob - bec0758d890fb5939a291ed794a610f9e5ac37df
blob + 19f9a333d1a1e479845512439daaef8adc164ca4
--- sys/dev/pci/if_iwxvar.h
+++ sys/dev/pci/if_iwxvar.h
@@ -681,6 +681,7 @@ struct iwx_softc {
 #define IWX_DEVICE_FAMILY_220001
 #define IWX_DEVICE_FAMILY_AX2102
uint32_t sc_sku_id[3];
+   uint32_t mac_addr_from_csr;
 
struct iwx_dma_info ctxt_info_dma;
struct iwx_self_init_dram init_dram;



Re: rpki-client: enforce RSC compliant filenames

2022-05-10 Thread Claudio Jeker
On Tue, May 10, 2022 at 08:38:32AM +0200, Theo Buehler wrote:
> On Tue, May 10, 2022 at 08:28:10AM +0200, Claudio Jeker wrote:
> > On Tue, May 10, 2022 at 08:05:00AM +0200, Theo Buehler wrote:
> > > This moves valid_filename() to validate.c and splits out a helper
> > > portable_filename() which can be used from the RSC code. While moving
> > > valid_filename() is not necessary, I thought it makes sense to keep the 
> > > two functions next to each other.
> > > 
> > > I could not find a short name with valid_ prefix for portable_filename()
> > > that I liked. valid_posix_filename()? valid_checklist_file()?
> > > 
> > > Also, valid_filename() could be stricter and enforce that the unique '.'
> > > is followed by a 3-letter suffix.
> > 
> > I would use valid_filename() for what you call portable_filename() and
> > then introduce a mft_filename() in mft.c that does the extra check.
> > Or maybe rename valid_filename() to valid_mft_filename().
> 
> I like both suggestion. Went with the latter since it is clearer at the
> call site what it does. Thanks
> 
> > I don't think we need to enforce the location of the dot. That is enforced
> > by rtype_from_file_extension() and rtype_from_mftfile().
> 
> Right.

OK claudio@
 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.134
> diff -u -p -r1.134 extern.h
> --- extern.h  9 May 2022 17:19:32 -   1.134
> +++ extern.h  10 May 2022 06:32:03 -
> @@ -502,6 +502,7 @@ intvalid_cert(const char *, struct au
>  int   valid_roa(const char *, struct auth *, struct roa *);
>  int   valid_filehash(int, const char *, size_t);
>  int   valid_hash(unsigned char *, size_t, const char *, size_t);
> +int   valid_filename(const char *, size_t);
>  int   valid_uri(const char *, size_t, const char *);
>  int   valid_origin(const char *, const char *);
>  int   valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
> Index: mft.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 mft.c
> --- mft.c 9 May 2022 17:02:34 -   1.61
> +++ mft.c 10 May 2022 06:36:32 -
> @@ -129,16 +129,15 @@ rtype_from_file_extension(const char *fn
>  /*
>   * Validate that a filename listed on a Manifest only contains characters
>   * permitted in draft-ietf-sidrops-6486bis section 4.2.2
> + * Also ensure that there is exactly one '.'.
>   */
>  static int
> -valid_filename(const char *fn, size_t len)
> +valid_mft_filename(const char *fn, size_t len)
>  {
>   const unsigned char *c;
> - size_t i;
>  
> - for (c = fn, i = 0; i < len; i++, c++)
> - if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
> - return 0;
> + if (!valid_filename(fn, len))
> + return 0;
>  
>   c = memchr(fn, '.', len);
>   if (c == NULL || c != memrchr(fn, '.', len))
> @@ -205,7 +204,7 @@ mft_parse_filehash(struct parse *p, cons
>   p->fn, ASN1_tag2str(file->type), file->type);
>   goto out;
>   }
> - if (!valid_filename(file->value.ia5string->data,
> + if (!valid_mft_filename(file->value.ia5string->data,
>   file->value.ia5string->length)) {
>   warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
>   goto out;
> @@ -482,7 +481,7 @@ mft_parse(X509 **x509, const char *fn, c
>   goto out;
>   }
>   if ((crlfile = strrchr(crldp, '/')) == NULL ||
> - !valid_filename(crlfile + 1, strlen(crlfile + 1)) ||
> + !valid_mft_filename(crlfile + 1, strlen(crlfile + 1)) ||
>   rtype_from_file_extension(crlfile + 1) != RTYPE_CRL) {
>   warnx("%s: RFC 6487 section 4.8.6: CRL: "
>   "bad CRL distribution point extension", fn);
> Index: rsc.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/rsc.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 rsc.c
> --- rsc.c 9 May 2022 17:02:34 -   1.1
> +++ rsc.c 10 May 2022 06:32:09 -
> @@ -147,6 +147,8 @@ rsc_parse_filenamehash(struct parse *p, 
>   }
>  
>   if (elemsz == 2) {
> + ASN1_IA5STRING *filename;
> +
>   file = sk_ASN1_TYPE_value(seq, i++);
>   if (file->type != V_ASN1_IA5STRING) {
>   warnx("%s: RSC FileNameAndHash: want ASN.1 IA5 string,"
> @@ -154,25 +156,17 @@ rsc_parse_filenamehash(struct parse *p, 
>   ASN1_tag2str(file->type), file->type);
>   goto out;
>   }
> - fn = strndup((const char *)file->value.ia5string->data,
> - file->value.ia5string->length);
> - if (fn == NULL)
> - err(1, NULL);
> 

Re: rpki-client: enforce RSC compliant filenames

2022-05-10 Thread Theo Buehler
On Tue, May 10, 2022 at 08:28:10AM +0200, Claudio Jeker wrote:
> On Tue, May 10, 2022 at 08:05:00AM +0200, Theo Buehler wrote:
> > This moves valid_filename() to validate.c and splits out a helper
> > portable_filename() which can be used from the RSC code. While moving
> > valid_filename() is not necessary, I thought it makes sense to keep the 
> > two functions next to each other.
> > 
> > I could not find a short name with valid_ prefix for portable_filename()
> > that I liked. valid_posix_filename()? valid_checklist_file()?
> > 
> > Also, valid_filename() could be stricter and enforce that the unique '.'
> > is followed by a 3-letter suffix.
> 
> I would use valid_filename() for what you call portable_filename() and
> then introduce a mft_filename() in mft.c that does the extra check.
> Or maybe rename valid_filename() to valid_mft_filename().

I like both suggestion. Went with the latter since it is clearer at the
call site what it does. Thanks

> I don't think we need to enforce the location of the dot. That is enforced
> by rtype_from_file_extension() and rtype_from_mftfile().

Right.

Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.134
diff -u -p -r1.134 extern.h
--- extern.h9 May 2022 17:19:32 -   1.134
+++ extern.h10 May 2022 06:32:03 -
@@ -502,6 +502,7 @@ int  valid_cert(const char *, struct au
 int valid_roa(const char *, struct auth *, struct roa *);
 int valid_filehash(int, const char *, size_t);
 int valid_hash(unsigned char *, size_t, const char *, size_t);
+int valid_filename(const char *, size_t);
 int valid_uri(const char *, size_t, const char *);
 int valid_origin(const char *, const char *);
 int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
Index: mft.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.61
diff -u -p -r1.61 mft.c
--- mft.c   9 May 2022 17:02:34 -   1.61
+++ mft.c   10 May 2022 06:36:32 -
@@ -129,16 +129,15 @@ rtype_from_file_extension(const char *fn
 /*
  * Validate that a filename listed on a Manifest only contains characters
  * permitted in draft-ietf-sidrops-6486bis section 4.2.2
+ * Also ensure that there is exactly one '.'.
  */
 static int
-valid_filename(const char *fn, size_t len)
+valid_mft_filename(const char *fn, size_t len)
 {
const unsigned char *c;
-   size_t i;
 
-   for (c = fn, i = 0; i < len; i++, c++)
-   if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
-   return 0;
+   if (!valid_filename(fn, len))
+   return 0;
 
c = memchr(fn, '.', len);
if (c == NULL || c != memrchr(fn, '.', len))
@@ -205,7 +204,7 @@ mft_parse_filehash(struct parse *p, cons
p->fn, ASN1_tag2str(file->type), file->type);
goto out;
}
-   if (!valid_filename(file->value.ia5string->data,
+   if (!valid_mft_filename(file->value.ia5string->data,
file->value.ia5string->length)) {
warnx("%s: RFC 6486 section 4.2.2: bad filename", p->fn);
goto out;
@@ -482,7 +481,7 @@ mft_parse(X509 **x509, const char *fn, c
goto out;
}
if ((crlfile = strrchr(crldp, '/')) == NULL ||
-   !valid_filename(crlfile + 1, strlen(crlfile + 1)) ||
+   !valid_mft_filename(crlfile + 1, strlen(crlfile + 1)) ||
rtype_from_file_extension(crlfile + 1) != RTYPE_CRL) {
warnx("%s: RFC 6487 section 4.8.6: CRL: "
"bad CRL distribution point extension", fn);
Index: rsc.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/rsc.c,v
retrieving revision 1.1
diff -u -p -r1.1 rsc.c
--- rsc.c   9 May 2022 17:02:34 -   1.1
+++ rsc.c   10 May 2022 06:32:09 -
@@ -147,6 +147,8 @@ rsc_parse_filenamehash(struct parse *p, 
}
 
if (elemsz == 2) {
+   ASN1_IA5STRING *filename;
+
file = sk_ASN1_TYPE_value(seq, i++);
if (file->type != V_ASN1_IA5STRING) {
warnx("%s: RSC FileNameAndHash: want ASN.1 IA5 string,"
@@ -154,25 +156,17 @@ rsc_parse_filenamehash(struct parse *p, 
ASN1_tag2str(file->type), file->type);
goto out;
}
-   fn = strndup((const char *)file->value.ia5string->data,
-   file->value.ia5string->length);
-   if (fn == NULL)
-   err(1, NULL);
 
-   /*
-* filename must confirm to portable file name character set
-* XXX: use valid_filename() instead
-*/
-   if 

Re: rpki-client: enforce RSC compliant filenames

2022-05-10 Thread Claudio Jeker
On Tue, May 10, 2022 at 08:05:00AM +0200, Theo Buehler wrote:
> This moves valid_filename() to validate.c and splits out a helper
> portable_filename() which can be used from the RSC code. While moving
> valid_filename() is not necessary, I thought it makes sense to keep the 
> two functions next to each other.
> 
> I could not find a short name with valid_ prefix for portable_filename()
> that I liked. valid_posix_filename()? valid_checklist_file()?
> 
> Also, valid_filename() could be stricter and enforce that the unique '.'
> is followed by a 3-letter suffix.

I would use valid_filename() for what you call portable_filename() and
then introduce a mft_filename() in mft.c that does the extra check.
Or maybe rename valid_filename() to valid_mft_filename().
I don't think we need to enforce the location of the dot. That is enforced
by rtype_from_file_extension() and rtype_from_mftfile().

 
> Index: extern.h
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.134
> diff -u -p -r1.134 extern.h
> --- extern.h  9 May 2022 17:19:32 -   1.134
> +++ extern.h  10 May 2022 06:03:19 -
> @@ -502,6 +502,8 @@ intvalid_cert(const char *, struct au
>  int   valid_roa(const char *, struct auth *, struct roa *);
>  int   valid_filehash(int, const char *, size_t);
>  int   valid_hash(unsigned char *, size_t, const char *, size_t);
> +int   portable_filename(const char *, size_t);
> +int   valid_filename(const char *, size_t);
>  int   valid_uri(const char *, size_t, const char *);
>  int   valid_origin(const char *, const char *);
>  int   valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
> Index: mft.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
> retrieving revision 1.61
> diff -u -p -r1.61 mft.c
> --- mft.c 9 May 2022 17:02:34 -   1.61
> +++ mft.c 10 May 2022 06:03:19 -
> @@ -127,27 +127,6 @@ rtype_from_file_extension(const char *fn
>  }
>  
>  /*
> - * Validate that a filename listed on a Manifest only contains characters
> - * permitted in draft-ietf-sidrops-6486bis section 4.2.2
> - */
> -static int
> -valid_filename(const char *fn, size_t len)
> -{
> - const unsigned char *c;
> - size_t i;
> -
> - for (c = fn, i = 0; i < len; i++, c++)
> - if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
> - return 0;
> -
> - c = memchr(fn, '.', len);
> - if (c == NULL || c != memrchr(fn, '.', len))
> - return 0;
> -
> - return 1;
> -}
> -
> -/*
>   * Check that the file is an ASPA, CER, CRL, GBR or a ROA.
>   * Returns corresponding rtype or RTYPE_INVALID on error.
>   */
> Index: rsc.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/rsc.c,v
> retrieving revision 1.1
> diff -u -p -r1.1 rsc.c
> --- rsc.c 9 May 2022 17:02:34 -   1.1
> +++ rsc.c 10 May 2022 06:03:46 -
> @@ -147,6 +147,8 @@ rsc_parse_filenamehash(struct parse *p, 
>   }
>  
>   if (elemsz == 2) {
> + ASN1_IA5STRING *filename;
> +
>   file = sk_ASN1_TYPE_value(seq, i++);
>   if (file->type != V_ASN1_IA5STRING) {
>   warnx("%s: RSC FileNameAndHash: want ASN.1 IA5 string,"
> @@ -154,25 +156,17 @@ rsc_parse_filenamehash(struct parse *p, 
>   ASN1_tag2str(file->type), file->type);
>   goto out;
>   }
> - fn = strndup((const char *)file->value.ia5string->data,
> - file->value.ia5string->length);
> - if (fn == NULL)
> - err(1, NULL);
>  
> - /*
> -  * filename must confirm to portable file name character set
> -  * XXX: use valid_filename() instead
> -  */
> - if (strchr(fn, '/') != NULL) {
> - warnx("%s: path components disallowed in filename: %s",
> - p->fn, fn);
> - goto out;
> - }
> - if (strchr(fn, '\n') != NULL) {
> - warnx("%s: newline disallowed in filename: %s",
> - p->fn, fn);
> + filename = file->value.ia5string;
> +
> + if (!portable_filename(filename->data, filename->length)) {
> + warnx("%s: RSC FileNameAndHash: bad filename", p->fn);
>   goto out;
>   }
> +
> + fn = strndup(filename->data, filename->length);
> + if (fn == NULL)
> + err(1, NULL);
>   }
>  
>   /* Now hash value. */
> Index: validate.c
> ===
> RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
> 

rpki-client: enforce RSC compliant filenames

2022-05-10 Thread Theo Buehler
This moves valid_filename() to validate.c and splits out a helper
portable_filename() which can be used from the RSC code. While moving
valid_filename() is not necessary, I thought it makes sense to keep the 
two functions next to each other.

I could not find a short name with valid_ prefix for portable_filename()
that I liked. valid_posix_filename()? valid_checklist_file()?

Also, valid_filename() could be stricter and enforce that the unique '.'
is followed by a 3-letter suffix.

Index: extern.h
===
RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
retrieving revision 1.134
diff -u -p -r1.134 extern.h
--- extern.h9 May 2022 17:19:32 -   1.134
+++ extern.h10 May 2022 06:03:19 -
@@ -502,6 +502,8 @@ int  valid_cert(const char *, struct au
 int valid_roa(const char *, struct auth *, struct roa *);
 int valid_filehash(int, const char *, size_t);
 int valid_hash(unsigned char *, size_t, const char *, size_t);
+int portable_filename(const char *, size_t);
+int valid_filename(const char *, size_t);
 int valid_uri(const char *, size_t, const char *);
 int valid_origin(const char *, const char *);
 int valid_x509(char *, X509_STORE_CTX *, X509 *, struct auth *,
Index: mft.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/mft.c,v
retrieving revision 1.61
diff -u -p -r1.61 mft.c
--- mft.c   9 May 2022 17:02:34 -   1.61
+++ mft.c   10 May 2022 06:03:19 -
@@ -127,27 +127,6 @@ rtype_from_file_extension(const char *fn
 }
 
 /*
- * Validate that a filename listed on a Manifest only contains characters
- * permitted in draft-ietf-sidrops-6486bis section 4.2.2
- */
-static int
-valid_filename(const char *fn, size_t len)
-{
-   const unsigned char *c;
-   size_t i;
-
-   for (c = fn, i = 0; i < len; i++, c++)
-   if (!isalnum(*c) && *c != '-' && *c != '_' && *c != '.')
-   return 0;
-
-   c = memchr(fn, '.', len);
-   if (c == NULL || c != memrchr(fn, '.', len))
-   return 0;
-
-   return 1;
-}
-
-/*
  * Check that the file is an ASPA, CER, CRL, GBR or a ROA.
  * Returns corresponding rtype or RTYPE_INVALID on error.
  */
Index: rsc.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/rsc.c,v
retrieving revision 1.1
diff -u -p -r1.1 rsc.c
--- rsc.c   9 May 2022 17:02:34 -   1.1
+++ rsc.c   10 May 2022 06:03:46 -
@@ -147,6 +147,8 @@ rsc_parse_filenamehash(struct parse *p, 
}
 
if (elemsz == 2) {
+   ASN1_IA5STRING *filename;
+
file = sk_ASN1_TYPE_value(seq, i++);
if (file->type != V_ASN1_IA5STRING) {
warnx("%s: RSC FileNameAndHash: want ASN.1 IA5 string,"
@@ -154,25 +156,17 @@ rsc_parse_filenamehash(struct parse *p, 
ASN1_tag2str(file->type), file->type);
goto out;
}
-   fn = strndup((const char *)file->value.ia5string->data,
-   file->value.ia5string->length);
-   if (fn == NULL)
-   err(1, NULL);
 
-   /*
-* filename must confirm to portable file name character set
-* XXX: use valid_filename() instead
-*/
-   if (strchr(fn, '/') != NULL) {
-   warnx("%s: path components disallowed in filename: %s",
-   p->fn, fn);
-   goto out;
-   }
-   if (strchr(fn, '\n') != NULL) {
-   warnx("%s: newline disallowed in filename: %s",
-   p->fn, fn);
+   filename = file->value.ia5string;
+
+   if (!portable_filename(filename->data, filename->length)) {
+   warnx("%s: RSC FileNameAndHash: bad filename", p->fn);
goto out;
}
+
+   fn = strndup(filename->data, filename->length);
+   if (fn == NULL)
+   err(1, NULL);
}
 
/* Now hash value. */
Index: validate.c
===
RCS file: /cvs/src/usr.sbin/rpki-client/validate.c,v
retrieving revision 1.31
diff -u -p -r1.31 validate.c
--- validate.c  21 Apr 2022 09:53:07 -  1.31
+++ validate.c  10 May 2022 06:03:19 -
@@ -275,6 +275,42 @@ valid_hash(unsigned char *buf, size_t le
 }
 
 /*
+ * Validate that a filename only contains characters from the POSIX portable
+ * filename character set [A-Za-z0-9._-], see IEEE Std 1003.1-2013, 3.278.
+ */
+int
+portable_filename(const char *fn, size_t len)
+{
+   const unsigned char *c;
+   size_t i;
+
+   for (c = fn, i = 0; i