From nobody Fri Jul 05 22:06:07 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 4WG6zM59SHz5QdVC; Fri, 05 Jul 2024 22:06:07 +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 4WG6zM4fMyz428p; Fri, 5 Jul 2024 22:06:07 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1720217167; 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=ewKGB+zcJrKKOoDd6yHcOZDNhRFX6jniLvOOun+3hBU=; b=x6SVvASCvRY9MAg4wcnHm+6MlSBHwL3JV18z0ACuRxwgTbUfxg+RHgx5UIH0MxScLYhxX5 EsbVNgFV8A4Dgb6TCUwaH/f46cFzM7kAePjSGgAjvfKojrvia25SboYVQsLpawEYneqNHL kJcimR+6hrJBQK2t46WyidtjdLl/OlonbCvdlCYnD+PfKWy2gRtZIfEFuDZUUoYeZrkdz8 rKcwnkF2Ub9AMjLXZCfc4+U3rimyqA7pXyQqESXuW6ZZ+C+T13mVgug/RNf2fUpZim6Ih1 ahNkx1WkKvHhsTaoVEetg1J9cqGGFJ08U1R3CxhMYkgrYIBe6HYqI47szt1W7Q== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1720217167; a=rsa-sha256; cv=none; b=ussantwqDpxPa4HkwJmHiDHAur3Ao8+ZUm7u0PfEt4eVR0KVIkyV596rQzJCXV2sQZQUU1 rtj1j7XjzE3N1DMD+oH+Uz6yjKZM1DcLLTaAVtwGgbBuKTERBxc7miTyKYaXA0boa+OuyT iKl9f8ErPIKXzUzpByKm5mcAxJg+bUy0+qVYHQgU0QwcnZIngM2+rSFgSKY15vmr1O1mCn 8ukCM7O3ATRni/RECtAs0lVuhXKavWSAiPz+j+LaRRTbgIzVGAPaBU3UwFGvetYwjWUqR/ 6Xalj98MNhb9uBRYpyJSDUPtLttSjxvOMQOyMBj1i+XjoAjctpUu0DOaqXma7Q== 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=1720217167; 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=ewKGB+zcJrKKOoDd6yHcOZDNhRFX6jniLvOOun+3hBU=; b=PnHpyKBmxykcT/wgwWfEQeLNbzhgCehYWt+UiVoRsxwh6Ge+oHKLOhmiVHOTHvk0/ldM2y ga/q/0Ar2hFnVOZzr4tCd84L1htiTwEsFJQ5cNx+nFNMdjYKIOD0sbbfq0kOjmyaslyLRH JFBKpDdQLJ6YfVb/cwbWMHMT8dRzAJHWQJNQ5erimra3Z6OyTHFRY1zXYy6BxgW3ZPmwzN 11sbQJcPl/UL1Ol2s7xF1D8Gplep7qVsFOwqq7NhTPWvkk1EIjuV8C+fcz8WqTnlHs7i/D MAS64PwqMNVCgIBMpR9wV2C6JnQVlXzwZpNUh2wbAE7/u0XFzKPzTAWcFGvI5Q== 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 4WG6zM47LLzDsq; Fri, 5 Jul 2024 22:06:07 +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 465M67Lx088602; Fri, 5 Jul 2024 22:06:07 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 465M673P088599; Fri, 5 Jul 2024 22:06:07 GMT (envelope-from git) Date: Fri, 5 Jul 2024 22:06:07 GMT Message-Id: <202407052206.465M673P088599@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Dag-Erling =?utf-8?Q?Sm=C3=B8rgrav?= Subject: git: c15290fb9d8f - main - 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/main X-Git-Reftype: branch X-Git-Commit: c15290fb9d8fdf4b11b9c6e7406b67c73a98402d Auto-Submitted: auto-generated The branch main has been updated by des: URL: https://cgit.FreeBSD.org/src/commit/?id=c15290fb9d8fdf4b11b9c6e7406b67c73a98402d commit c15290fb9d8fdf4b11b9c6e7406b67c73a98402d Author: Dag-Erling Smørgrav AuthorDate: 2024-07-05 22:05:49 +0000 Commit: Dag-Erling Smørgrav CommitDate: 2024-07-05 22:05:49 +0000 tftpd: Code cleanup. MFC after: 3 days Sponsored by: Klara, Inc. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D45871 --- 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 3f67ad2920cf..a51fb4742985 100644 --- a/libexec/tftpd/tftpd.c +++ b/libexec/tftpd/tftpd.c @@ -680,28 +680,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] == '/') @@ -710,30 +709,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. @@ -741,18 +730,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; @@ -766,27 +757,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);