DF-5690 / fix.diff
--- a/sys/libprop/prop_string.c +++ b/sys/libprop/prop_string.c @@ -185,6 +185,31 @@ * Create an immutable string that contains a refrence to the * provided C string. */ +#if defined(_KERNEL) || defined(PROP_RIG_FORCE_NOCOPY_COPY) +/* + * DF-5690: in a kernel build the "nocopy" borrowing semantics are a + * use-after-free / heap-overflow foot-gun: the prop_string keeps a raw + * pointer to caller-owned memory, never owns or copies it + * (_prop_string_free skips PS_F_NOCOPY buffers, prop_string.c:85-87), and + * ps_size is frozen at creation while prop_string_cstring()/ + * externalization re-read the buffer to its *current* NUL + * (prop_string.c:302-304). A plist that outlives (or outgrows) the + * caller's buffer therefore reads freed/stale kernel memory into data + * copied back to userspace (prop_array_copyout_ioctl externalize path), + * and the copy variant can overflow its ps_size+1 allocation. There are + * no in-kernel callers today; make the kernel build copy so a plist can + * never reference caller-owned transient memory. + * + * PROP_RIG_FORCE_NOCOPY_COPY is a verification-rig-only activation define + * (findings/poc/DF-5690); it is undefined in every real build. + */ +prop_string_t +prop_string_create_cstring_nocopy(const char *str) +{ + + return (prop_string_create_cstring(str)); +} +#else prop_string_t prop_string_create_cstring_nocopy(const char *str) { @@ -198,6 +223,7 @@ } return (ps); } +#endif /* * prop_string_copy -- |