diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-06 15:18:05 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2020-07-06 15:18:05 +0000 |
commit | d8aa63df5fc8a037352f116c52139532d3af096d (patch) | |
tree | 8a932ff46a07abcd5523ece3945823a4273074c6 /sys/arch/arm64 | |
parent | 5f3d71c2afe1c553b1c388aac3b59523d83e41c7 (diff) |
IEEE1275 (Open Firmware) defines that parameter name strings can have a
length of up to 31 characters. This limit is also present in the
flattened device tree specification/ Unfortunately this limit isn't enforced
by the tooling and there are systems in the wild that use longer strings.
This includes the device trees used on POWER9 systems and has been seen
on some ARM systems as well.
So bump the buffer size from 32 bytes (31 + terminating NUL) to 64 bytes.
Centrally define OFMAXPARAM to this value (in <dev/ofw/openfirm.h>)
replacing the various OPROMMAXPARAM definition scattered around the tree
to make sure the FDT implementation of OF_nextprop() uses the same
buffer size as its consumers.
Eliminate the static buffer in various openprom(4) implementations on
FDT systems.
Makes it possible to dump the full device tree on POWER9 systems using
eeprom -p.
ok deraadt@, visa@
Diffstat (limited to 'sys/arch/arm64')
-rw-r--r-- | sys/arch/arm64/arm64/openprom.c | 64 |
1 files changed, 11 insertions, 53 deletions
diff --git a/sys/arch/arm64/arm64/openprom.c b/sys/arch/arm64/arm64/openprom.c index 4d399058440..e18f42ca6c3 100644 --- a/sys/arch/arm64/arm64/openprom.c +++ b/sys/arch/arm64/arm64/openprom.c @@ -1,4 +1,4 @@ -/* $OpenBSD: openprom.c,v 1.1 2017/01/23 12:34:06 kettenis Exp $ */ +/* $OpenBSD: openprom.c,v 1.2 2020/07/06 15:18:03 kettenis Exp $ */ /* $NetBSD: openprom.c,v 1.4 2002/01/10 06:21:53 briggs Exp $ */ /* @@ -55,13 +55,11 @@ #include <dev/ofw/openfirm.h> -#define OPROMMAXPARAM 32 +static int lastnode; /* speed hack */ +static int optionsnode; /* node ID of ROM's options */ -static int lastnode; /* speed hack */ -static int optionsnode; /* node ID of ROM's options */ - -static int openpromcheckid(int, int); -static int openpromgetstr(int, char *, char **); +int openpromcheckid(int, int); +int openpromgetstr(int, char *, char **); void openpromattach(int); void @@ -115,15 +113,11 @@ int openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) { struct opiocdesc *op; - int node, len, ok, error, s; + int node, len, ok, error; char *name, *value, *nextprop; - static char buf[32]; /* XXX */ - if (optionsnode == 0) { - s = splhigh(); + if (optionsnode == 0) optionsnode = OF_getnodebyname(0, "options"); - splx(s); - } /* All too easy... */ if (cmd == OPIOCGETOPTNODE) { @@ -136,9 +130,7 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) node = op->op_nodeid; if (node != 0 && node != lastnode && node != optionsnode) { /* Not an easy one, must search for it */ - s = splhigh(); ok = openpromcheckid(OF_peer(0), node); - splx(s); if (!ok) return (EINVAL); lastnode = node; @@ -156,10 +148,7 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) error = openpromgetstr(op->op_namelen, op->op_name, &name); if (error) break; - s = splhigh(); - strlcpy(buf, name, 32); /* XXX */ - len = OF_getproplen(node, buf); - splx(s); + len = OF_getproplen(node, name); if (len > op->op_buflen) { error = ENOMEM; break; @@ -169,34 +158,10 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) if (len <= 0) break; value = malloc(len, M_TEMP, M_WAITOK); - s = splhigh(); - strlcpy(buf, name, 32); /* XXX */ - OF_getprop(node, buf, value, len); - splx(s); + OF_getprop(node, name, value, len); error = copyout(value, op->op_buf, len); break; -#if 0 - case OPIOCSET: - if ((flags & FWRITE) == 0) - return (EBADF); - if (node == 0) - return (EINVAL); - error = openpromgetstr(op->op_namelen, op->op_name, &name); - if (error) - break; - error = openpromgetstr(op->op_buflen, op->op_buf, &value); - if (error) - break; - s = splhigh(); - strlcpy(buf, name, 32); /* XXX */ - len = OF_setprop(node, buf, value, op->op_buflen + 1); - splx(s); - if (len != op->op_buflen) - error = EINVAL; - break; -#endif - case OPIOCNEXTPROP: if ((flags & FREAD) == 0) return (EBADF); @@ -209,16 +174,13 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) error = ENAMETOOLONG; break; } - value = nextprop = malloc(OPROMMAXPARAM, M_TEMP, + value = nextprop = malloc(OFMAXPARAM, M_TEMP, M_WAITOK | M_CANFAIL); if (nextprop == NULL) { error = ENOMEM; break; } - s = splhigh(); - strlcpy(buf, name, 32); /* XXX */ - error = OF_nextprop(node, buf, nextprop); - splx(s); + error = OF_nextprop(node, name, nextprop); if (error == -1) { error = EINVAL; break; @@ -241,9 +203,7 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) case OPIOCGETNEXT: if ((flags & FREAD) == 0) return (EBADF); - s = splhigh(); node = OF_peer(node); - splx(s); *(int *)data = lastnode = node; break; @@ -252,9 +212,7 @@ openpromioctl(dev_t dev, u_long cmd, caddr_t data, int flags, struct proc *p) return (EBADF); if (node == 0) return (EINVAL); - s = splhigh(); node = OF_child(node); - splx(s); *(int *)data = lastnode = node; break; |