From nobody Thu Feb 13 10:20:53 2025 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ytrmj50gmz5nHyh; Thu, 13 Feb 2025 10:20:53 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ytrmj2dS4z3YST; Thu, 13 Feb 2025 10:20:53 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739442053; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0KWRbUKTe4lB7OgoMPVj4f7kbmE5i3RmqJT84B6kgd8=; b=Z5VpWUbs9oEPV0YYhI+FBy7Mi721SKjsN0A3jvVeTnQoiE7S5kIiaT9G3raR7RYr91wL5k KjI4Vs1wZSf+A1fBHR7yfUNbHCVVp+hi2o9eW7DQDFmCVIxUBqfD1HsgO4MlSXKCgz/a0y Uh7ObWrzCgn6agy+pnC1xHfbCIiMfV2D83Bj9wkRhc+PkRaIIy0NLvkjdKmOXJmPsQb/ao Rk+H76jnNN23W/eET3zaZ7pG7KfAtGHLbwgxpb80zr70FX0WKoDoIHJKtbi5Sgvbeo2kZh CzN844u6NLuRUlm51lpJvCqBYLP4wsCGGT0bMHDzH5FF2gwGlxoWjSPJpWuCcg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739442053; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0KWRbUKTe4lB7OgoMPVj4f7kbmE5i3RmqJT84B6kgd8=; b=P7lw1H6aMRgdjOJAoBuxA13U2kZ2ZH/3jA8E1cjKwH4ssuoDoQ0Hm09DEG8J+PPicsdsap azfMEeENSZ6ihHFCR0uPFPNgPly6zL4aogVidELq8kSdVaVetrR78Uj82Hd80uUSgo+1ve gsx+OOHzQIfmk03U/Jvs8dRcZPbk0RbLcxHTXlimD+EwM4j27xX9UrqiTlbPNsmHEguUHS E6GpZZ1UFbnqHdzt1aC2ae8Qncje4QXG73eDvVxNyyob+vFvqyVD0cYqWYteu5wjpUsd2O km/uo2AqdDdz6aCEkdHzo4MDe/XMXuUckFXHRe48YrDLOE9BSYE4gPYC7VdcOQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1739442053; a=rsa-sha256; cv=none; b=plOm9E2jTaxCjcL2WoEIUEtw2WKQSt2nk1qhTbLZTYHJEVXCpSliLpH8YBx0YzyhWlQU9O Y6VPoTs2cZRcU7KZzvO+vYkYM/rcd3Y1a30rlgHCUy8zBsBI8cnRFIsTYlglEKAY9qUqAO R4ZYAg6Vy93fIi1oUdf+hzHbNNr8+8P6pAZ3Mil7dDzNu2GAF78CQcRENWH5bDMcGIaBQG TWd0rOHGhFugdO/um6wBGBdvclXQ3ok1m5x37eivdBD7hxeaZq/r3TOreSAAGjW2PXKbQr wCFQtQhuxy9TxUBGj2lxItkF82LJWWNS3UWMq4ZNJBI4S33Rpzvd6aD1P4T7NQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none 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 4Ytrmj2DqJzgxW; Thu, 13 Feb 2025 10:20:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 51DAKrnD025668; Thu, 13 Feb 2025 10:20:53 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 51DAKrro025665; Thu, 13 Feb 2025 10:20:53 GMT (envelope-from git) Date: Thu, 13 Feb 2025 10:20:53 GMT Message-Id: <202502131020.51DAKrro025665@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Zhenlei Huang Subject: git: 8ca77f9f9ece - stable/14 - sysctl: Harden sysctl_handle_string() against unterminated string List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: zlei X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 8ca77f9f9ece9d89161d080eee6a1aa706001878 Auto-Submitted: auto-generated The branch stable/14 has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=8ca77f9f9ece9d89161d080eee6a1aa706001878 commit 8ca77f9f9ece9d89161d080eee6a1aa706001878 Author: Zhenlei Huang AuthorDate: 2025-02-09 17:17:11 +0000 Commit: Zhenlei Huang CommitDate: 2025-02-13 10:19:57 +0000 sysctl: Harden sysctl_handle_string() against unterminated string In case a variable string which is not null-terminated is passed in, strlen() may report a length exceeding the max length, hence it is possible to leak a portion of kernel memory to the userland. Harden that by using strnlen() to limit the length to the max length. While here, refactor the code a little to improve readability. Note that, when calculating the out length, the null terminator '\0' of the string is taken into account if available. This is not really necessary but userland applications may have already relied on this behavior. Reviewed by: avg, kib, olce Fixes: 210176ad76ee sysctl(9): add CTLFLAG_NEEDGIANT flag MFC after: 4 days Differential Revision: https://reviews.freebsd.org/D48881 (cherry picked from commit 1951235537fb62150f1bb15dd7e170ac30853d35) --- sys/kern/kern_sysctl.c | 42 ++++++++++++++++++++---------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 3d66de0b18bb..b9ca0e7e5041 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1785,8 +1785,7 @@ int sysctl_handle_string(SYSCTL_HANDLER_ARGS) { char *tmparg; - size_t outlen; - int error = 0, ro_string = 0; + int error = 0; /* * If the sysctl isn't writable and isn't a preallocated tunable that @@ -1798,33 +1797,32 @@ sysctl_handle_string(SYSCTL_HANDLER_ARGS) */ if ((oidp->oid_kind & (CTLFLAG_WR | CTLFLAG_TUN)) == 0 || arg2 == 0 || kdb_active) { - arg2 = strlen((char *)arg1) + 1; - ro_string = 1; - } + size_t outlen; - if (req->oldptr != NULL) { - if (ro_string) { - tmparg = arg1; - outlen = strlen(tmparg) + 1; - } else { + if (arg2 == 0) + outlen = arg2 = strlen(arg1) + 1; + else + outlen = strnlen(arg1, arg2 - 1) + 1; + + tmparg = req->oldptr != NULL ? arg1 : NULL; + error = SYSCTL_OUT(req, tmparg, outlen); + } else { + size_t outlen; + + if (req->oldptr != NULL) { tmparg = malloc(arg2, M_SYSCTLTMP, M_WAITOK); sx_slock(&sysctlstringlock); memcpy(tmparg, arg1, arg2); sx_sunlock(&sysctlstringlock); - outlen = strlen(tmparg) + 1; - } - - error = SYSCTL_OUT(req, tmparg, outlen); - - if (!ro_string) - free(tmparg, M_SYSCTLTMP); - } else { - if (!ro_string) + outlen = strnlen(tmparg, arg2 - 1) + 1; + } else { + tmparg = NULL; sx_slock(&sysctlstringlock); - outlen = strlen((char *)arg1) + 1; - if (!ro_string) + outlen = strnlen(arg1, arg2 - 1) + 1; sx_sunlock(&sysctlstringlock); - error = SYSCTL_OUT(req, NULL, outlen); + } + error = SYSCTL_OUT(req, tmparg, outlen); + free(tmparg, M_SYSCTLTMP); } if (error || !req->newptr) return (error);