diff options
author | marius <marius@FreeBSD.org> | 2004-05-22 16:43:42 +0000 |
---|---|---|
committer | marius <marius@FreeBSD.org> | 2004-05-22 16:43:42 +0000 |
commit | 630c60c775383107787c595cde447ba88cb494be (patch) | |
tree | f278fb8e30dee2cf60cd930fb8596885755725cc /sys/dev/ofw | |
parent | ef31e6c3b5eecc0138972fe13b84d260b34f2cbb (diff) | |
download | FreeBSD-src-630c60c775383107787c595cde447ba88cb494be.zip FreeBSD-src-630c60c775383107787c595cde447ba88cb494be.tar.gz |
- Move OFW_NAME_MAX, used as a limit for OFW property names and device
identifiers, to openfirmio.h as OFIOCMAXNAME, so programs can use it
for buffer sizes etc.
Note: Although this is only a rough upper limit to make the code more
robust and to prevent the allocation of ridiculous amounts of memory,
the current limit of one page (8191 + '\0' in openfirm_getstr()) still
appears a bit high. The maximum length of OFW property names is 31.
I didn't find a maximum length for the device identifiers in the OFW
documentation but it certainly is much smaller than 8191, too.
- Enable the OFIOCSET ioctl, i.e. move it out from under #if 0.
- Don't use openfirm_getstr() for the property value in OFIOCSET, there
are also properties whose values aren't strings and it makes sense to
use a different maximum length for property values than OFW_NAME_MAX/
OFIOCMAXNAME. The maximum accepted property value is defined in
openfirmio.h as OFIOCMAXVALUE (currently the maximum size of the value
of the nvramrc property).
- Make OFIOCSET not return EINVAL when OF_setprop() returns a different
length for the written value than it was told to write, this is normal
for the text string values of the properties in the OFW /options node.
Instead, only return EINVAL if OF_setprop() returned -1 (value could
not be written or property could not be created). Add a comment about
the specialty of the OFW /options node.
- Make OFIOCSET return the length of the written value returned by
OF_setprop(), just like OF_getprop() does. Quite useful, at least for
debugging.
Reviewed by: tmm
Diffstat (limited to 'sys/dev/ofw')
-rw-r--r-- | sys/dev/ofw/openfirmio.c | 28 | ||||
-rw-r--r-- | sys/dev/ofw/openfirmio.h | 9 |
2 files changed, 24 insertions, 13 deletions
diff --git a/sys/dev/ofw/openfirmio.c b/sys/dev/ofw/openfirmio.c index 358109e..adb3929 100644 --- a/sys/dev/ofw/openfirmio.c +++ b/sys/dev/ofw/openfirmio.c @@ -74,9 +74,6 @@ static phandle_t lastnode; /* speed hack */ static int openfirm_checkid(phandle_t, phandle_t); static int openfirm_getstr(int, const char *, char **); -/* Maximum accepted name length. */ -#define OFW_NAME_MAX 8191 - /* * Verify target ID is valid (exists in the OPENPROM tree), as * listed from node ID sid forward. @@ -99,7 +96,7 @@ openfirm_getstr(int len, const char *user, char **cpp) char *cp; /* Reject obvious bogus requests */ - if ((u_int)len > OFW_NAME_MAX) + if ((u_int)len > OFIOCMAXNAME) return (ENAMETOOLONG); *cpp = cp = malloc(len + 1, M_TEMP, M_WAITOK); @@ -129,9 +126,7 @@ openfirm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, *(phandle_t *) data = OF_finddevice("/options"); return (0); case OFIOCGET: -#if 0 case OFIOCSET: -#endif case OFIOCNEXTPROP: case OFIOCFINDDEVICE: case OFIOCGETPROPLEN: @@ -186,23 +181,36 @@ openfirm_ioctl(dev_t dev, u_long cmd, caddr_t data, int flags, error = copyout(value, of->of_buf, len); break; -#if 0 case OFIOCSET: + /* + * Note: Text string values for at least the /options node + * have to be null-terminated and the length paramter must + * include this terminating null. However, like OF_getprop(), + * OF_setprop() will return the the actual length of the text + * string, i.e. omitting the terminating null. + */ if ((flags & FWRITE) == 0) return (EBADF); if (node == 0) return (EINVAL); + if ((u_int)of->of_buflen > OFIOCMAXVALUE) + return (ENAMETOOLONG); error = openfirm_getstr(of->of_namelen, of->of_name, &name); if (error) break; - error = openfirm_getstr(of->of_buflen, of->of_buf, &value); + value = malloc(of->of_buflen, M_TEMP, M_WAITOK); + if (value == NULL) { + error = ENOMEM; + break; + } + error = copyin(of->of_buf, value, of->of_buflen); if (error) break; len = OF_setprop(node, name, value, of->of_buflen); - if (len != of->of_buflen) + if (len < 0) error = EINVAL; + of->of_buflen = len; break; -#endif case OFIOCNEXTPROP: if (node == 0 || of->of_buflen < 0) diff --git a/sys/dev/ofw/openfirmio.h b/sys/dev/ofw/openfirmio.h index ae5837e..c4f21d2 100644 --- a/sys/dev/ofw/openfirmio.h +++ b/sys/dev/ofw/openfirmio.h @@ -54,10 +54,8 @@ struct ofiocdesc { /* Get openprom field. */ #define OFIOCGET _IOWR(OFIOC_BASE, 1, struct ofiocdesc) -#if 0 /* Set openprom field. */ -#define OFIOCSET _IOW(OFIOC_BASE, 2, struct ofiocdesc) -#endif +#define OFIOCSET _IOWR(OFIOC_BASE, 2, struct ofiocdesc) /* Get next property. */ #define OFIOCNEXTPROP _IOWR(OFIOC_BASE, 3, struct ofiocdesc) /* Get options node. */ @@ -71,4 +69,9 @@ struct ofiocdesc { /* Retrieve the size of a property. */ #define OFIOCGETPROPLEN _IOWR(OFIOC_BASE, 8, struct ofiocdesc) +/* Maximum accepted name length. */ +#define OFIOCMAXNAME 8191 +/* Maximum accepted value length (maximum of nvramrc property). */ +#define OFIOCMAXVALUE 8192 + #endif /* _DEV_OFW_OPENFIRMIO_H_ */ |