From owner-p4-projects@FreeBSD.ORG Fri May 7 04:21:46 2010 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 96D3F1065673; Fri, 7 May 2010 04:21:46 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 576C1106566B for ; Fri, 7 May 2010 04:21:46 +0000 (UTC) (envelope-from gcooper@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 45F5F8FC08 for ; Fri, 7 May 2010 04:21:46 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id o474Lk6a029109 for ; Fri, 7 May 2010 04:21:46 GMT (envelope-from gcooper@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id o474LkR4029107 for perforce@freebsd.org; Fri, 7 May 2010 04:21:46 GMT (envelope-from gcooper@FreeBSD.org) Date: Fri, 7 May 2010 04:21:46 GMT Message-Id: <201005070421.o474LkR4029107@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to gcooper@FreeBSD.org using -f From: Garrett Cooper To: Perforce Change Reviews Precedence: bulk Cc: Subject: PERFORCE change 177875 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 May 2010 04:21:46 -0000 http://p4web.freebsd.org/@@177875?ac=10 Change 177875 by gcooper@gcooper-bayonetta on 2010/05/07 04:20:47 Add code to avoid race conditions with archive_read_filename by using archive_read_fd as recommended by kientzle@. Affected files ... .. //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/usr.sbin/pkg_install/lib/file.c#13 edit Differences ... ==== //depot/projects/soc2007/gcooper-pkg_install-enhancements-simplified/usr.sbin/pkg_install/lib/file.c#13 (text+ko) ==== @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -375,7 +376,7 @@ FILE *fd = NULL; /* int fd = -1; */ - int r; + int archive_fd = -1, r; if (pkg == NULL || strcmp(pkg, "-") == 0) pkg_name_humanized = "(stdin)"; @@ -390,8 +391,21 @@ archive_read_support_compression_all(archive); archive_read_support_format_tar(archive); + /* + * Avoid potential race conditions with archive_read_open_filename(3), + * by opening the file beforehand. + */ + if (pkg == NULL) + archive_fd = fileno(stdin); + else + archive_fd = open(pkg, O_RDONLY); + /* The initial open failed */ - if (archive_read_open_filename(archive, pkg, + if (archive_fd == -1) + warn("%s: unable to open the package from %s", + __func__, pkg_name_humanized); + /* archive(3) failed to open the file. */ + else if (archive_read_open_fd(archive, archive_fd, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { error = archive_error_string(archive); @@ -438,6 +452,10 @@ archive_read_finish(archive); + /* Close any open descriptors. */ + if (0 <= archive_fd) + close(archive_fd); + return fd; } @@ -459,7 +477,7 @@ const char *entry_pathname = NULL; const char *error = NULL; const char *pkg_name_humanized; - int r; + int archive_fd = -1, r, serrno; if (file_expr == NULL || strcmp("*", file_expr) == 0) extract_whole_archive = TRUE; @@ -483,8 +501,20 @@ archive_read_support_compression_all(archive); archive_read_support_format_tar(archive); + /* + * Avoid potential race conditions with archive_read_open_filename(3), + * by opening the file beforehand. + */ + if (pkg == NULL) + archive_fd = fileno(stdin); + else + archive_fd = open(pkg, O_RDONLY); + /* The initial open failed */ - if (archive_read_open_filename(archive, pkg, + if (archive_fd == -1) + warn("%s: unable to open the package from %s", + __func__, pkg_name_humanized); + else if (archive_read_open_fd(archive, archive_fd, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { error = archive_error_string(archive); @@ -523,9 +553,14 @@ } + serrno = errno; archive_read_finish(archive); - return (error == NULL ? 0 : 1); + /* Close any open descriptors. */ + if (0 <= archive_fd) + close(archive_fd); + + return (error == NULL && errno == 0 ? 0 : 1); }