Index: share/man/man9/Makefile =================================================================== --- share/man/man9/Makefile +++ share/man/man9/Makefile @@ -972,6 +972,7 @@ MLINKS+=dev_refthread.9 devvn_refthread.9 \ dev_refthread.9 dev_relthread.9 MLINKS+=devctl_notify.9 devctl_notifyf.9 +MLINKS+=devctl_safe_quote_sb.9 devctl_safe_quote_sb_len.9 MLINKS+=devfs_set_cdevpriv.9 devfs_clear_cdevpriv.9 \ devfs_set_cdevpriv.9 devfs_get_cdevpriv.9 MLINKS+=device_add_child.9 device_add_child_ordered.9 Index: share/man/man9/devctl_safe_quote_sb.9 =================================================================== --- share/man/man9/devctl_safe_quote_sb.9 +++ share/man/man9/devctl_safe_quote_sb.9 @@ -23,17 +23,20 @@ .\" .\" $FreeBSD$ .\" -.Dd September 22, 2020 +.Dd March 12, 2022 .Dt DEVCTL_SAFE_QUOTE_SB 9 .Os .Sh NAME -.Nm devctl_safe_quote_sb +.Nm devctl_safe_quote_sb , +.Nm devctl_safe_quote_sb_len .Nd Insert a string, properly quoted, into a sbuf .Sh SYNOPSIS .In sys/devctl.h .In sys/sbuf.h .Ft void .Fn devctl_safe_quote_sb "struct sbuf *sb" "const char *src" +.Ft void +.Fn devctl_safe_quote_sb_len "struct sbuf *sb" "const char *src" "size_t len" .Sh DESCRIPTION Copy the string from .Va src @@ -46,8 +49,15 @@ All other characters are copied without modification. The .Xr devctl 4 -protocol requires quoted string to be quoted thus. +protocol requires a quoted string to have these special characters escaped. This routine centralizes this knowledge. +.Pp +The +.Fn devctl_safe_quote_sb_len +will limit escaping to the first +.Fa len +characters of +.Va src . .Sh SEE ALSO .Xr devd 8 .Sh AUTHORS Index: sys/kern/subr_bus.c =================================================================== --- sys/kern/subr_bus.c +++ sys/kern/subr_bus.c @@ -878,6 +878,30 @@ } } +/** + * @brief safely quotes strings that might have double quotes in them. + * + * The devctl protocol relies on quoted strings having matching quotes. + * This routine quotes any internal quotes so the resulting string + * is safe to pass to snprintf to construct, for example pnp info strings. + * + * @param sb sbuf to place the characters into + * @param src Original buffer. + * @param len Max length of the buffer to process. + */ +void +devctl_safe_quote_sb_len(struct sbuf *sb, const char *src, size_t len) +{ + const char *srcp; + + srcp = src; + while (*srcp != '\0' && (srcp - src) != len) { + if (*srcp == '"' || *srcp == '\\') + sbuf_putc(sb, '\\'); + sbuf_putc(sb, *srcp++); + } +} + /* End of /dev/devctl code */ static struct device_list bus_data_devices; Index: sys/sys/devctl.h =================================================================== --- sys/sys/devctl.h +++ sys/sys/devctl.h @@ -19,6 +19,7 @@ const char *__type, const char *__data); struct sbuf; void devctl_safe_quote_sb(struct sbuf *__sb, const char *__src); +void devctl_safe_quote_sb_len(struct sbuf *sb, const char *src, size_t len); #endif #endif /* _SYS_DEVCTL_H_ */