From nobody Tue Jul 09 21:42:24 2024 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 4WJZG82SfVz5R8DJ; Tue, 09 Jul 2024 21:42:24 +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 4WJZG820nPz53Py; Tue, 9 Jul 2024 21:42:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1720561344; 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=pPH0RKBdZDZjsZwl9GuhR4ErXD/99jwdpn6NIZ9uJAo=; b=eGtOtY+33azsYsiFY56Lfd9OxzDjNcbJmKp/ENlF+ksCH66zk3Hb7nN0hQCkDuzNFRhpxL d2U4z/YT79D5JngMKgmnTiijtmVymTWxGBJ1qH1yuyUyfdYPkKJq/EseYqUkITViWbRnpX 8ExvuU9L8aTejQFcG2AnTm10SW3vAc5M6iXq8UU5oP+LsRfHgSRWysOGRiBsWsyjzbnHRn NGJoZpg+thh7/7x95wu5oJStJe7OL01k5nefUfcIG31ImTpvIHIOFfcU3KqRz0AFZPj1bP 31aYKVJbGbYaW93pC9gSx1D9tvO3VC/lsTRd2V/s3k41AVLtrnV9nqgkzTNfFQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1720561344; a=rsa-sha256; cv=none; b=m5kqmQbmELpJjy/ajjGGx6+rsAScpNv3sfLHACle7oacvXYREYavN3juq8PH7TcOkWasgy /wQA3T2Sln82hGdFhObA1iOiHyUix0upEISSSUeF3JdNQsOsFTSF7CUGcNLMDuIv4HtS69 v1a0wcT5kSvhieQx48c4Q9+DUTmhgPhiTPtwuMoMfjlBUzUjYxuPwpthFx3AFGGc7r/9GO LErH194Bx/1JTiuPYPA1ny+grvQFLqG8mVkPvFbc5BL98He/IvsRAYqziYn766qxDXtInH 9Go4KnQ02lGva+f830lypyGXwMqmqSxZxBUl55CZbEPS4zr+sJvO3v4aUEUjBw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1720561344; 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=pPH0RKBdZDZjsZwl9GuhR4ErXD/99jwdpn6NIZ9uJAo=; b=ggnD66k79KYKAe6k2F7ACs7kSMcBrf2QXFSVPU1bSTRNcDQTrkTIUNjvfDGtSyhPHruKKd ayxS67H3uLmNvk9BG0R7ffTxauXPHnfMNwPkGk9eN/yGYM11Ce3EJAdHbjjiu5LKzbzCaS 1DDVWxdFiU0FlXYCGtdV1Wy4Esn0+KL0O3ugwbJC+Z+Hqm6gVrAg/zscQkYg7ruOLwSsV/ fUzww0D/cF5SgJ68E1u2Hg2/1QDpVYaoaaGcABXPxSxJ3BVjQF2hlxps/5M9ITtPsE16J2 jOkElrnxfUA4j5KxQkaop0WAFUokBqM34Yog0lZ+FnN5acRP2gtlTtYu1IBPFw== 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 4WJZG81bjPzqgV; Tue, 9 Jul 2024 21:42:24 +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 469LgOAM093061; Tue, 9 Jul 2024 21:42:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 469LgOjT093057; Tue, 9 Jul 2024 21:42:24 GMT (envelope-from git) Date: Tue, 9 Jul 2024 21:42:24 GMT Message-Id: <202407092142.469LgOjT093057@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: 77362b5eb7a5 - stable/14 - tftpd: Code cleanup. 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: des X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 77362b5eb7a558d4327187bd6997df4051301059 Auto-Submitted: auto-generated The branch stable/14 has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=77362b5eb7a558d4327187bd6997df4051301059 commit 77362b5eb7a558d4327187bd6997df4051301059 Author: Dag-Erling Smørgrav AuthorDate: 2024-07-05 22:05:49 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-07-09 21:40:26 +0000 tftpd: Code cleanup. MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D45871 (cherry picked from commit c15290fb9d8fdf4b11b9c6e7406b67c73a98402d) --- libexec/tftpd/tftpd.c | 91 +++++++++++++++++++++++---------------------------- 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/libexec/tftpd/tftpd.c b/libexec/tftpd/tftpd.c index 00c1257ce548..cef8d0278a55 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -692,28 +692,27 @@ find_next_name(char *filename, int *fd) int validate_access(int peer, char **filep, int mode) { - struct stat stbuf; - int fd; - int error; - struct dirlist *dirp; static char pathname[MAXPATHLEN]; + struct stat sb; + struct dirlist *dirp; char *filename = *filep; + int err, fd; /* * Prevent tricksters from getting around the directory restrictions */ - if (strstr(filename, "/../")) + if (strncmp(filename, "../", 3) == 0 || + strstr(filename, "/../") != NULL) return (EACCESS); if (*filename == '/') { /* - * Allow the request if it's in one of the approved locations. - * Special case: check the null prefix ("/") by looking - * for length = 1 and relying on the arg. processing that - * it's a /. + * Absolute file name: allow the request if it's in one of the + * approved locations. */ for (dirp = dirs; dirp->name != NULL; dirp++) { if (dirp->len == 1) + /* Only "/" can have len 1 */ break; if (strncmp(filename, dirp->name, dirp->len) == 0 && filename[dirp->len] == '/') @@ -722,30 +721,20 @@ validate_access(int peer, char **filep, int mode) /* If directory list is empty, allow access to any file */ if (dirp->name == NULL && dirp != dirs) return (EACCESS); - if (stat(filename, &stbuf) < 0) + if (stat(filename, &sb) != 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); - if ((stbuf.st_mode & S_IFMT) != S_IFREG) + if (!S_ISREG(sb.st_mode)) return (ENOTFOUND); if (mode == RRQ) { - if ((stbuf.st_mode & S_IROTH) == 0) + if ((sb.st_mode & S_IROTH) == 0) return (EACCESS); } else { - if (check_woth && ((stbuf.st_mode & S_IWOTH) == 0)) + if (check_woth && (sb.st_mode & S_IWOTH) == 0) return (EACCESS); } } else { - int err; - /* * Relative file name: search the approved locations for it. - * Don't allow write requests that avoid directory - * restrictions. - */ - - if (!strncmp(filename, "../", 3)) - return (EACCESS); - - /* * If the file exists in one of the directories and isn't * readable, continue looking. However, change the error code * to give an indication that the file exists. @@ -753,18 +742,20 @@ validate_access(int peer, char **filep, int mode) err = ENOTFOUND; for (dirp = dirs; dirp->name != NULL; dirp++) { snprintf(pathname, sizeof(pathname), "%s/%s", - dirp->name, filename); - if (stat(pathname, &stbuf) == 0 && - (stbuf.st_mode & S_IFMT) == S_IFREG) { - if (mode == RRQ) { - if ((stbuf.st_mode & S_IROTH) != 0) - break; - } else { - if (!check_woth || ((stbuf.st_mode & S_IWOTH) != 0)) - break; - } - err = EACCESS; + dirp->name, filename); + if (stat(pathname, &sb) != 0) + continue; + if (!S_ISREG(sb.st_mode)) + continue; + err = EACCESS; + if (mode == RRQ) { + if ((sb.st_mode & S_IROTH) == 0) + continue; + } else { + if (check_woth && (sb.st_mode & S_IWOTH) == 0) + continue; } + break; } if (dirp->name != NULL) *filep = filename = pathname; @@ -778,27 +769,27 @@ validate_access(int peer, char **filep, int mode) * This option is handled here because it (might) require(s) the * size of the file. */ - option_tsize(peer, NULL, mode, &stbuf); + option_tsize(peer, NULL, mode, &sb); - if (mode == RRQ) + if (mode == RRQ) { fd = open(filename, O_RDONLY); - else { - if (create_new) { - if (increase_name) { - error = find_next_name(filename, &fd); - if (error > 0) - return (error + 100); - } else - fd = open(filename, - O_WRONLY | O_TRUNC | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | - S_IWGRP | S_IROTH | S_IWOTH ); - } else - fd = open(filename, O_WRONLY | O_TRUNC); + } else if (create_new) { + if (increase_name) { + err = find_next_name(filename, &fd); + if (err > 0) + return (err + 100); + } else { + fd = open(filename, + O_WRONLY | O_TRUNC | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | + S_IWGRP | S_IROTH | S_IWOTH ); + } + } else { + fd = open(filename, O_WRONLY | O_TRUNC); } if (fd < 0) return (errno + 100); - file = fdopen(fd, (mode == RRQ)? "r":"w"); + file = fdopen(fd, mode == RRQ ? "r" : "w"); if (file == NULL) { close(fd); return (errno + 100);