From owner-dev-commits-src-main@freebsd.org Thu Jul 22 16:23:35 2021 Return-Path: Delivered-To: dev-commits-src-main@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D8C4965FFDF; Thu, 22 Jul 2021 16:23:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GVyS75qY3z3qln; Thu, 22 Jul 2021 16:23:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id A3D7915303; Thu, 22 Jul 2021 16:23:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 16MGNZYf023291; Thu, 22 Jul 2021 16:23:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 16MGNZDu023290; Thu, 22 Jul 2021 16:23:35 GMT (envelope-from git) Date: Thu, 22 Jul 2021 16:23:35 GMT Message-Id: <202107221623.16MGNZDu023290@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Alan Somers Subject: git: 6c9506559080 - main - Escape any '.' characters in sysctl node names MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: asomers X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 6c9506559080da2914749bf611225d7c0a153609 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-main@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for the main branch of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 22 Jul 2021 16:23:35 -0000 The branch main has been updated by asomers: URL: https://cgit.FreeBSD.org/src/commit/?id=6c9506559080da2914749bf611225d7c0a153609 commit 6c9506559080da2914749bf611225d7c0a153609 Author: Alan Somers AuthorDate: 2021-07-21 21:11:00 +0000 Commit: Alan Somers CommitDate: 2021-07-22 16:22:48 +0000 Escape any '.' characters in sysctl node names ZFS creates some sysctl nodes that include a pool name, and '.' is an allowed character in pool names. But it's the separator in the sysctl tree, so it can't be included in a sysctl name. Replace it with "%25". Handily, "%" is illegal in ZFS pool names, so there's no ambiguity there. PR: 257316 MFC after: 3 weeks Sponsored by: Axcient Reviewed by: freqlabs Differential Revision: https://reviews.freebsd.org/D31265 --- sys/kern/kern_sysctl.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index e46584758c9b..c472db18aac7 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -122,6 +122,7 @@ static int sysctl_root(SYSCTL_HANDLER_ARGS); /* Root list */ struct sysctl_oid_list sysctl__children = SLIST_HEAD_INITIALIZER(&sysctl__children); +static char* sysctl_escape_name(const char*); static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse); static int sysctl_old_kernel(struct sysctl_req *, const void *, size_t); @@ -747,6 +748,46 @@ sysctl_remove_name(struct sysctl_oid *parent, const char *name, return (error); } +/* + * Duplicate the provided string, escaping any illegal characters. The result + * must be freed when no longer in use. + * + * The list of illegal characters is ".". + */ +static char* +sysctl_escape_name(const char* orig) +{ + int i, s = 0, d = 0, nillegals = 0; + char *new; + + /* First count the number of illegal characters */ + for (i = 0; orig[i] != '\0'; i++) { + if (orig[i] == '.') + nillegals++; + } + + /* Allocate storage for new string */ + new = malloc(i + 2 * nillegals + 1, M_SYSCTLOID, M_WAITOK); + + /* Copy the name, escaping characters as we go */ + while (orig[s] != '\0') { + if (orig[s] == '.') { + /* %25 is the hexadecimal representation of '.' */ + new[d++] = '%'; + new[d++] = '2'; + new[d++] = '5'; + s++; + } else { + new[d++] = orig[s++]; + } + } + + /* Finally, nul-terminate */ + new[d] = '\0'; + + return (new); +} + static int sysctl_remove_oid_locked(struct sysctl_oid *oidp, int del, int recurse) { @@ -828,14 +869,17 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, const char *label) { struct sysctl_oid *oidp; + char *escaped; /* You have to hook up somewhere.. */ if (parent == NULL) return(NULL); + escaped = sysctl_escape_name(name); /* Check if the node already exists, otherwise create it */ SYSCTL_WLOCK(); - oidp = sysctl_find_oidname(name, parent); + oidp = sysctl_find_oidname(escaped, parent); if (oidp != NULL) { + free(escaped, M_SYSCTLOID); if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) { oidp->oid_refcnt++; /* Update the context */ @@ -854,7 +898,7 @@ sysctl_add_oid(struct sysctl_ctx_list *clist, struct sysctl_oid_list *parent, SLIST_INIT(&oidp->oid_children); oidp->oid_number = number; oidp->oid_refcnt = 1; - oidp->oid_name = strdup(name, M_SYSCTLOID); + oidp->oid_name = escaped; oidp->oid_handler = handler; oidp->oid_kind = CTLFLAG_DYN | kind; oidp->oid_arg1 = arg1;