Re: buffer overprint in riscv64/cpu.c

2023-08-04 Thread Jonathan Gray
On Fri, Aug 04, 2023 at 01:26:08PM +0200, Peter J. Philipp wrote:
> On Tue, Aug 01, 2023 at 01:43:36PM +0200, p...@delphinusdns.org wrote:
> > >Synopsis:  non-terminated strings buffer in riscv64/cpu.c
> > >Category:  kernel
> > >Environment:
> > System  : OpenBSD 7.3
> > Details : OpenBSD 7.3-current (GENERIC.MP) #376: Thu Jul 13 
> > 03:59:40 MDT 2023
> >  
> > dera...@riscv64.openbsd.org:/usr/src/sys/arch/riscv64/compile/GENERIC.MP
> > 
> > Architecture: OpenBSD.riscv64
> > Machine : riscv64
> > >Description:
> > The cpu detect output is not NUL terminated, this causes *puke* to be
> > displayed on serial terminals.
> > >How-To-Repeat:
> > Using Qemu for riscv64 arch.
> > 
> > from a eeprom -p | grep isa output:
> > 
> > riscv,isa: 
> > 'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'
> > riscv,isa: 
> > 'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'
> > 
> > I counted this as 60 bytes long.
> > >Fix:
> > 
> > There is two approaches.  One is to explicitly NUL terminate the 32 byte
> > buffer or make it bigger.  I give an untested patch of the latter.

riscv,isa is going away:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=aeb71e42caae2031ec849a858080d81462cacca9

I see no point in trying to parse it.

> > 
> > Index: cpu.c
> > ===
> > RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
> > retrieving revision 1.14
> > diff -u -p -u -r1.14 cpu.c
> > --- cpu.c   15 Jun 2023 22:18:08 -  1.14
> > +++ cpu.c   1 Aug 2023 11:35:28 -
> > @@ -87,7 +87,7 @@ int cpu_errata_sifive_cip_1200;
> >  void
> >  cpu_identify(struct cpu_info *ci)
> >  {
> > -   char isa[32];
> > +   char isa[64];
> > uint64_t marchid, mimpid;
> > uint32_t mvendorid;
> > const char *vendor_name = NULL;
> > 
> > 
> 
> [tying in tech@]
> 
> This wasn't effective I just saw.  On another QEMU host the cpu ISA string is
> larger than 80 characters.  So I've made another patch.
> 
> With this patch it looks like so:
> 
> oceans$ dmesg|grep cpu
> cpu0 at mainbus0: vendor 0 arch 0 imp 0 rv64imafdch Zicbom Zicboz Zicsr 
> Zifencei Zihintpause Zawrs Zfa Zca Zcd Zba Zbb Zbc Zbs Sstc Svadu
> intc0 at cpu0
> cpu1 at mainbus0: vendor 0 arch 0 imp 0 rv64imafdch Zicbom Zicboz Zicsr 
> Zifencei Zihintpause Zawrs Zfa Zca Zcd Zba Zbb Zbc Zbs Sstc Svadu
> oceans# grep zicboz /root/eeprom-p.out
>  
> riscv,isa: 
> 'rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zca_zcd_zba_zbb_zbc_zbs_sstc_svadu'
> riscv,isa: 
> 'rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zca_zcd_zba_zbb_zbc_zbs_sstc_svadu'
> 
> This is in convention with the cpu.c found in qemu:
> 
> https://gitlab.com/qemu-project/qemu/-/blob/master/target/riscv/cpu.c
> 
> lines 64 through 84 is the description of it.
> 
> While I have no OpenBSD/riscv64 on true hardware it works on QEMU, and I
> googled for a dmesg online and the Hifive Unmatched should work as well.
> 
> patch follows:
> 
> Index: cpu.c
> ===
> RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
> retrieving revision 1.14
> diff -u -p -u -r1.14 cpu.c
> --- cpu.c 15 Jun 2023 22:18:08 -  1.14
> +++ cpu.c 4 Aug 2023 11:15:16 -
> @@ -84,15 +84,19 @@ struct cfdriver cpu_cd = {
>  
>  int cpu_errata_sifive_cip_1200;
>  
> +
>  void
>  cpu_identify(struct cpu_info *ci)
>  {
> - char isa[32];
> + char isa[255];
> + char szx_ext[255];  /* S, Z and X extension buffer */
> + char *extensions = "imafdqlcbkjtpvh";
>   uint64_t marchid, mimpid;
>   uint32_t mvendorid;
>   const char *vendor_name = NULL;
>   const char *arch_name = NULL;
>   struct arch *archlist = cpu_arch_none;
> + char *p, *pe, *end;
>   int i, len;
>  
>   mvendorid = sbi_get_mvendorid();
> @@ -126,8 +130,70 @@ cpu_identify(struct cpu_info *ci)
>  
>   len = OF_getprop(ci->ci_node, "riscv,isa", isa, sizeof(isa));
>   if (len != -1) {
> + /* terminate it, it could be non-terminated */
> + isa[sizeof(isa) - 1] = '\0';
> + 
> + /* PARSE the IMAFDQ... extensions */
> + pe = extensions;
> + if ((p = strchr(isa, 'i')) != NULL ||
> + (p = strchr(isa, 'I')) != NULL) {
> + for (; *pe != '\0'; pe++) {
> + if (((*p)|0x20) == *pe) {
> + if (p[1]) {
> + p++;
> + i++;
> + } else
> + break;
> + } 
> + /*
> + 

Re: buffer overprint in riscv64/cpu.c

2023-08-04 Thread Peter J. Philipp
On Tue, Aug 01, 2023 at 01:43:36PM +0200, p...@delphinusdns.org wrote:
> >Synopsis:non-terminated strings buffer in riscv64/cpu.c
> >Category:kernel
> >Environment:
>   System  : OpenBSD 7.3
>   Details : OpenBSD 7.3-current (GENERIC.MP) #376: Thu Jul 13 
> 03:59:40 MDT 2023
>
> dera...@riscv64.openbsd.org:/usr/src/sys/arch/riscv64/compile/GENERIC.MP
> 
>   Architecture: OpenBSD.riscv64
>   Machine : riscv64
> >Description:
>   The cpu detect output is not NUL terminated, this causes *puke* to be
> displayed on serial terminals.
> >How-To-Repeat:
>   Using Qemu for riscv64 arch.
> 
>   from a eeprom -p | grep isa output:
> 
> riscv,isa: 
> 'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'
> riscv,isa: 
> 'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'
> 
>   I counted this as 60 bytes long.
> >Fix:
> 
> There is two approaches.  One is to explicitly NUL terminate the 32 byte
> buffer or make it bigger.  I give an untested patch of the latter.
> 
> Index: cpu.c
> ===
> RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
> retrieving revision 1.14
> diff -u -p -u -r1.14 cpu.c
> --- cpu.c 15 Jun 2023 22:18:08 -  1.14
> +++ cpu.c 1 Aug 2023 11:35:28 -
> @@ -87,7 +87,7 @@ int cpu_errata_sifive_cip_1200;
>  void
>  cpu_identify(struct cpu_info *ci)
>  {
> - char isa[32];
> + char isa[64];
>   uint64_t marchid, mimpid;
>   uint32_t mvendorid;
>   const char *vendor_name = NULL;
> 
> 

[tying in tech@]

This wasn't effective I just saw.  On another QEMU host the cpu ISA string is
larger than 80 characters.  So I've made another patch.

With this patch it looks like so:

oceans$ dmesg|grep cpu
cpu0 at mainbus0: vendor 0 arch 0 imp 0 rv64imafdch Zicbom Zicboz Zicsr 
Zifencei Zihintpause Zawrs Zfa Zca Zcd Zba Zbb Zbc Zbs Sstc Svadu
intc0 at cpu0
cpu1 at mainbus0: vendor 0 arch 0 imp 0 rv64imafdch Zicbom Zicboz Zicsr 
Zifencei Zihintpause Zawrs Zfa Zca Zcd Zba Zbb Zbc Zbs Sstc Svadu
oceans# grep zicboz /root/eeprom-p.out 
riscv,isa: 
'rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zca_zcd_zba_zbb_zbc_zbs_sstc_svadu'
riscv,isa: 
'rv64imafdch_zicbom_zicboz_zicsr_zifencei_zihintpause_zawrs_zfa_zca_zcd_zba_zbb_zbc_zbs_sstc_svadu'

This is in convention with the cpu.c found in qemu:

https://gitlab.com/qemu-project/qemu/-/blob/master/target/riscv/cpu.c

lines 64 through 84 is the description of it.

While I have no OpenBSD/riscv64 on true hardware it works on QEMU, and I
googled for a dmesg online and the Hifive Unmatched should work as well.

patch follows:

Index: cpu.c
===
RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 cpu.c
--- cpu.c   15 Jun 2023 22:18:08 -  1.14
+++ cpu.c   4 Aug 2023 11:15:16 -
@@ -84,15 +84,19 @@ struct cfdriver cpu_cd = {
 
 int cpu_errata_sifive_cip_1200;
 
+
 void
 cpu_identify(struct cpu_info *ci)
 {
-   char isa[32];
+   char isa[255];
+   char szx_ext[255];  /* S, Z and X extension buffer */
+   char *extensions = "imafdqlcbkjtpvh";
uint64_t marchid, mimpid;
uint32_t mvendorid;
const char *vendor_name = NULL;
const char *arch_name = NULL;
struct arch *archlist = cpu_arch_none;
+   char *p, *pe, *end;
int i, len;
 
mvendorid = sbi_get_mvendorid();
@@ -126,8 +130,70 @@ cpu_identify(struct cpu_info *ci)
 
len = OF_getprop(ci->ci_node, "riscv,isa", isa, sizeof(isa));
if (len != -1) {
+   /* terminate it, it could be non-terminated */
+   isa[sizeof(isa) - 1] = '\0';
+   
+   /* PARSE the IMAFDQ... extensions */
+   pe = extensions;
+   if ((p = strchr(isa, 'i')) != NULL ||
+   (p = strchr(isa, 'I')) != NULL) {
+   for (; *pe != '\0'; pe++) {
+   if (((*p)|0x20) == *pe) {
+   if (p[1]) {
+   p++;
+   i++;
+   } else
+   break;
+   } 
+   /*
+* we've hit an underscore what follows 
+* may be an S or Z extension 
+*/
+   if (*p == '_')
+   break;
+   }
+
+   szx_ext[0] = '\0';
+   if (*p == '_') {
+   *p++ = '\0';
+  

buffer overprint in riscv64/cpu.c

2023-08-01 Thread pjp
>Synopsis:  non-terminated strings buffer in riscv64/cpu.c
>Category:  kernel
>Environment:
System  : OpenBSD 7.3
Details : OpenBSD 7.3-current (GENERIC.MP) #376: Thu Jul 13 
03:59:40 MDT 2023
 
dera...@riscv64.openbsd.org:/usr/src/sys/arch/riscv64/compile/GENERIC.MP

Architecture: OpenBSD.riscv64
Machine : riscv64
>Description:
The cpu detect output is not NUL terminated, this causes *puke* to be
displayed on serial terminals.
>How-To-Repeat:
Using Qemu for riscv64 arch.

from a eeprom -p | grep isa output:

riscv,isa: 
'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'
riscv,isa: 
'rv64imafdch_zicsr_zifencei_zihintpause_zba_zbb_zbc_zbs_sstc'

I counted this as 60 bytes long.
>Fix:

There is two approaches.  One is to explicitly NUL terminate the 32 byte
buffer or make it bigger.  I give an untested patch of the latter.

Index: cpu.c
===
RCS file: /cvs/src/sys/arch/riscv64/riscv64/cpu.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 cpu.c
--- cpu.c   15 Jun 2023 22:18:08 -  1.14
+++ cpu.c   1 Aug 2023 11:35:28 -
@@ -87,7 +87,7 @@ int cpu_errata_sifive_cip_1200;
 void
 cpu_identify(struct cpu_info *ci)
 {
-   char isa[32];
+   char isa[64];
uint64_t marchid, mimpid;
uint32_t mvendorid;
const char *vendor_name = NULL;


dmesg:
OpenBSD 7.3-current (GENERIC.MP) #376: Thu Jul 13 03:59:40 MDT 2023
dera...@riscv64.openbsd.org:/usr/src/sys/arch/riscv64/compile/GENERIC.MP
real mem  = 2147483648 (2048MB)
avail mem = 2027982848 (1934MB)
SBI: OpenSBI v1.2, SBI Specification Version 1.0
random: good seed from bootblocks
mainbus0 at root: riscv-virtio,qemu
cpu0 at mainbus0: vendor 0 arch 70200 imp 70200 
rv64imafdch_zicsr_zifencei_zihin\M-n\M-#7
intc0 at cpu0
cpu1 at mainbus0: vendor 0 arch 70200 imp 70200 
rv64imafdch_zicsr_zifencei_zihin\M-n\M-#7
syscon0 at mainbus0: "poweroff"
syscon1 at mainbus0: "reboot"
"fw-cfg" at mainbus0 not configured
"flash" at mainbus0 not configured
simplebus0 at mainbus0: "platform-bus"
simplebus1 at mainbus0: "soc"
syscon2 at simplebus1: "test"
plic0 at simplebus1
"pmu" at simplebus1 not configured
gfrtc0 at simplebus1
com0 at simplebus1: ns16550, no working fifo
com0: console
pciecam0 at simplebus1
pci0 at pciecam0
"Red Hat Host" rev 0x00 at pci0 dev 0 function 0 not configured
virtio0 at simplebus1: Virtio Network Device
vio0 at virtio0: address 52:54:00:12:34:56
virtio1 at simplebus1: Virtio Block Device
vioblk0 at virtio1
scsibus0 at vioblk0: 1 targets
sd0 at scsibus0 targ 0 lun 0: 
sd0: 40960MB, 512 bytes/sector, 83886080 sectors
virtio2 at simplebus1: Virtio Unknown (0) Device
virtio3 at simplebus1: Virtio Unknown (0) Device
virtio4 at simplebus1: Virtio Unknown (0) Device
virtio5 at simplebus1: Virtio Unknown (0) Device
virtio6 at simplebus1: Virtio Unknown (0) Device
virtio7 at simplebus1: Virtio Unknown (0) Device
"clint" at simplebus1 not configured
vscsi0 at root
scsibus1 at vscsi0: 256 targets
softraid0 at root
scsibus2 at softraid0: 256 targets
root on sd0a (a44107957d8bed73.a) swap on sd0b dump on sd0b

usbdevs:
usbdevs: no USB controllers found

pcidump:

everything past here is not provided.