From nobody Sun Feb 9 17:23:10 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 4YrZKp606vz5mjpH; Sun, 09 Feb 2025 17:23:10 +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 4YrZKp5WJ5z46KH; Sun, 09 Feb 2025 17:23:10 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739121790; 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=XVx541XHd5EHBih2NmqpKClCf2sojxB0YEBz23bH7mI=; b=TO7XGmIhVEOzz3QUgYGWEyNNKZxkYCxFLD3ufHT0NRCQEthutEV8WE9OlJvQNm04tmnxxq Mwmw3Kfz7K491YueZDvO42PYF4VwHWhcaRrKmmkWWqIi4MoCnoAP+rtb4mXeUZIjEMPaWn GArIca8Asubu9HmVwUt/wSKbUQjFyfS/2PGWjTebBBtYDyinw761W0gNwiBljaj+NwhuFy 9xXI/ApIYtcEov4+2YKi/fe5UvTfSa3Gs1XJn60zaYxyme7HJ2yHntiWFeQucIq15BdJl6 qmpzr5azI03EpVGIkbuflgbm6fHyMgwh6bVORdF2qpf+bzpOV3l/rYwwFZjh8g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1739121790; 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=XVx541XHd5EHBih2NmqpKClCf2sojxB0YEBz23bH7mI=; b=QBWOWBKSy6lH4W7EZNEn9VNB/iM3WK8/1EKt+BtY7m/J/DZDyPxra+J779GvEmHhDbn5XA MOkVQRvZcvkvItVM/roRNwtqqt+FpEJO4BRpnDlbh8jonWOauAg7vhu7cFIhd2o8Is8sjn f/b/Ni9yc3Qepu4i4EDpa0VZnzr5nYZGmvZ8lMcnjwsGXtvpCTDanMJHaJPXwpr/r9Zt9x FRQQogxPX+cnejzrsc8WgByA244DOobfJXxY0KkJ0D08lVUHMx1S4w+pULWUsS5I1rU8al uR2D5fwL5fxRlAAjSMrCCDxgZK3Y6WjU0lMax1OcCabYLzvpbDt5Xbnxf5BCNg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1739121790; a=rsa-sha256; cv=none; b=FecWbrCdAdk7vo2Tu8iZJzGWrin1cz4R2/Q4cAInPhj/fBJYvh240vsutQ/Tr67r/e5I3X zBL66/sTcXyCVRQo3mCEuel+h0AbC9YniT6KLeXBO76xr/TII7i8rhBx8C9G3hiskVU1n3 m/UNiRn7ya49JrVa0CcHnYUnC0LYUUYv2ZcSM05Ojo6Bg1YHXts3MT8SNxePs7zwjKYFm4 4iUJz4xw1MEwrlqXYueVRFyV1v/ZJ/XLJkrGk7fYkz7pCLkvge9+BQP6/P4nDiNV0IgrFZ 68LZw7eeb7ICRZe+8NUo9GMBiQCkzTA+ZmNTHbF/Vr+pux2DI/BONDYpu3hZqg== 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 4YrZKp4mRrz15lg; Sun, 09 Feb 2025 17:23:10 +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 519HNADR013085; Sun, 9 Feb 2025 17:23:10 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 519HNAM5013082; Sun, 9 Feb 2025 17:23:10 GMT (envelope-from git) Date: Sun, 9 Feb 2025 17:23:10 GMT Message-Id: <202502091723.519HNAM5013082@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Zhenlei Huang Subject: git: 1951235537fb - main - 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/main X-Git-Reftype: branch X-Git-Commit: 1951235537fb62150f1bb15dd7e170ac30853d35 Auto-Submitted: auto-generated The branch main has been updated by zlei: URL: https://cgit.FreeBSD.org/src/commit/?id=1951235537fb62150f1bb15dd7e170ac30853d35 commit 1951235537fb62150f1bb15dd7e170ac30853d35 Author: Zhenlei Huang AuthorDate: 2025-02-09 17:17:11 +0000 Commit: Zhenlei Huang CommitDate: 2025-02-09 17:17:11 +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 --- 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 da09aaed5558..8cf8e7b19c89 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1885,8 +1885,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 @@ -1898,33 +1897,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);