From owner-svn-ports-all@freebsd.org Tue Apr 24 11:07:13 2018 Return-Path: Delivered-To: svn-ports-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 68CD2F89E6E; Tue, 24 Apr 2018 11:07:13 +0000 (UTC) (envelope-from garga@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D50B28374D; Tue, 24 Apr 2018 11:07:12 +0000 (UTC) (envelope-from garga@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C50C0124A7; Tue, 24 Apr 2018 11:07:12 +0000 (UTC) (envelope-from garga@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w3OB7CcV046909; Tue, 24 Apr 2018 11:07:12 GMT (envelope-from garga@FreeBSD.org) Received: (from garga@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w3OB7Cws046907; Tue, 24 Apr 2018 11:07:12 GMT (envelope-from garga@FreeBSD.org) Message-Id: <201804241107.w3OB7Cws046907@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: garga set sender to garga@FreeBSD.org using -f From: Renato Botelho Date: Tue, 24 Apr 2018 11:07:12 +0000 (UTC) To: ports-committers@freebsd.org, svn-ports-all@freebsd.org, svn-ports-head@freebsd.org Subject: svn commit: r468197 - in head/security/sudo: . files X-SVN-Group: ports-head X-SVN-Commit-Author: garga X-SVN-Commit-Paths: in head/security/sudo: . files X-SVN-Commit-Revision: 468197 X-SVN-Commit-Repository: ports MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-ports-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: SVN commit messages for the ports tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Apr 2018 11:07:13 -0000 Author: garga Date: Tue Apr 24 11:07:12 2018 New Revision: 468197 URL: https://svnweb.freebsd.org/changeset/ports/468197 Log: Add a patch to fix cryptographic digest in command specification for shell scripts and other interpreted files. Error happens because fexecve() requires /dev/fd to be mounted. This patch detects if /dev/fd/N exists before attempt to use fexecve and workaround the issue. PR: 223587 Submitted by: Todd C. Miller Reported by: vas@mpeks.tomsk.su Obtained from: https://bugzilla.sudo.ws/show_bug.cgi?id=831 MFH: 2018Q2 Sponsored by: Rubicon Communications, LLC (Netgate) Added: head/security/sudo/files/patch-plugins_sudoers_match.c (contents, props changed) Modified: head/security/sudo/Makefile Modified: head/security/sudo/Makefile ============================================================================== --- head/security/sudo/Makefile Tue Apr 24 10:48:56 2018 (r468196) +++ head/security/sudo/Makefile Tue Apr 24 11:07:12 2018 (r468197) @@ -3,7 +3,7 @@ PORTNAME= sudo PORTVERSION= 1.8.22 -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= security MASTER_SITES= SUDO Added: head/security/sudo/files/patch-plugins_sudoers_match.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/security/sudo/files/patch-plugins_sudoers_match.c Tue Apr 24 11:07:12 2018 (r468197) @@ -0,0 +1,95 @@ +--- plugins/sudoers/match.c.orig 2018-04-24 10:49:39 UTC ++++ plugins/sudoers/match.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) 1996, 1998-2005, 2007-2017 ++ * Copyright (c) 1996, 1998-2005, 2007-2018 + * Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any +@@ -446,32 +446,22 @@ do_stat(int fd, const char *path, struct stat *sb) + debug_return_bool(stat(path, sb) == 0); + } + ++#ifdef HAVE_FEXECVE + /* +- * On systems with fexecve(2), set the close-on-exec flag on the file +- * descriptor only if the file is not a script. Because scripts need +- * to be executed by an interpreter the fd must remain open for the +- * interpreter to use. ++ * Check whether the fd refers to a shell script with a "#!" shebang. + */ +-static void +-set_cloexec(int fd) ++static bool ++is_script(int fd) + { +- bool is_script = false; +-#ifdef HAVE_FEXECVE ++ bool ret = false; + char magic[2]; + +- /* Check for #! cookie and set is_script. */ + if (read(fd, magic, 2) == 2) { + if (magic[0] == '#' && magic[1] == '!') +- is_script = true; ++ ret = true; + } + (void) lseek(fd, (off_t)0, SEEK_SET); +-#endif /* HAVE_FEXECVE */ +- /* +- * Shell scripts go through namei twice and so we can't set the close +- * on exec flag on the fd for fexecve(2). +- */ +- if (!is_script) +- (void)fcntl(fd, F_SETFD, FD_CLOEXEC); ++ return ret; + } + + /* +@@ -500,10 +490,36 @@ open_cmnd(const char *path, const struct sudo_digest * + if (fd == -1) + debug_return_bool(false); + +- set_cloexec(fd); ++ if (is_script(fd)) { ++ char fdpath[PATH_MAX]; ++ struct stat sb; ++ ++ /* We can only use fexecve() on a script if /dev/fd/N exists. */ ++ snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd); ++ if (stat(fdpath, &sb) != 0) { ++ close(fd); ++ debug_return_bool(true); ++ } ++ ++ /* ++ * Shell scripts go through namei twice so we can't set the ++ * close on exec flag on the fd for fexecve(2). ++ */ ++ } else { ++ /* Not a script, close on exec is safe. */ ++ (void)fcntl(fd, F_SETFD, FD_CLOEXEC); ++ } ++ + *fdp = fd; + debug_return_bool(true); + } ++#else /* HAVE_FEXECVE */ ++static bool ++open_cmnd(const char *path, const struct sudo_digest *digest, int *fdp) ++{ ++ return true; ++} ++#endif /* HAVE_FEXECVE */ + + static bool + command_matches_fnmatch(const char *sudoers_cmnd, const char *sudoers_args, +@@ -728,6 +744,7 @@ digest_matches(int fd, const char *file, const struct + debug_decl(digest_matches, SUDOERS_DEBUG_MATCH) + + file_digest = sudo_filedigest(fd, file, sd->digest_type, &digest_len); ++ lseek(fd, SEEK_SET, (off_t)0); + if (file_digest == NULL) { + /* Warning (if any) printed by sudo_filedigest() */ + goto done;