From owner-svn-src-stable-12@freebsd.org Wed Dec 2 21:44:42 2020 Return-Path: Delivered-To: svn-src-stable-12@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id CDCD24A73B6; Wed, 2 Dec 2020 21:44:42 +0000 (UTC) (envelope-from dim@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 "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CmXYk3M1Dz3rR1; Wed, 2 Dec 2020 21:44:42 +0000 (UTC) (envelope-from dim@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 656F363DC; Wed, 2 Dec 2020 21:44:42 +0000 (UTC) (envelope-from dim@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0B2LigXM088072; Wed, 2 Dec 2020 21:44:42 GMT (envelope-from dim@FreeBSD.org) Received: (from dim@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0B2LifAk088069; Wed, 2 Dec 2020 21:44:41 GMT (envelope-from dim@FreeBSD.org) Message-Id: <202012022144.0B2LifAk088069@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: dim set sender to dim@FreeBSD.org using -f From: Dimitry Andric Date: Wed, 2 Dec 2020 21:44:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org Subject: svn commit: r368286 - in stable: 11/contrib/elftoolchain/elfcopy 12/contrib/elftoolchain/elfcopy X-SVN-Group: stable-12 X-SVN-Commit-Author: dim X-SVN-Commit-Paths: in stable: 11/contrib/elftoolchain/elfcopy 12/contrib/elftoolchain/elfcopy X-SVN-Commit-Revision: 368286 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-12@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: SVN commit messages for only the 12-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 Dec 2020 21:44:42 -0000 Author: dim Date: Wed Dec 2 21:44:41 2020 New Revision: 368286 URL: https://svnweb.freebsd.org/changeset/base/368286 Log: MFC r367809: When elftoolchain's objcopy (or strip) is rewriting a file in-place, make it create the temporary file in the same directory as the source file by default, instead of always using $TMPDIR or /tmp. If creating that file fails because the directory is not writable, also fallback to $TMPDIR or /tmp. This has also been submitted upstream as: https://sourceforge.net/p/elftoolchain/tickets/597/ Reported by: cem PR: 250872 Modified: stable/12/contrib/elftoolchain/elfcopy/archive.c stable/12/contrib/elftoolchain/elfcopy/elfcopy.h stable/12/contrib/elftoolchain/elfcopy/main.c Directory Properties: stable/12/ (props changed) Changes in other areas also in this revision: Modified: stable/11/contrib/elftoolchain/elfcopy/archive.c stable/11/contrib/elftoolchain/elfcopy/elfcopy.h stable/11/contrib/elftoolchain/elfcopy/main.c Directory Properties: stable/11/ (props changed) Modified: stable/12/contrib/elftoolchain/elfcopy/archive.c ============================================================================== --- stable/12/contrib/elftoolchain/elfcopy/archive.c Wed Dec 2 21:39:54 2020 (r368285) +++ stable/12/contrib/elftoolchain/elfcopy/archive.c Wed Dec 2 21:44:41 2020 (r368286) @@ -68,7 +68,7 @@ process_ar_obj(struct elfcopy *ecp, struct ar_obj *obj int fd; /* Output to a temporary file. */ - create_tempfile(&tempfile, &fd); + create_tempfile(NULL, &tempfile, &fd); if ((ecp->eout = elf_begin(fd, ELF_C_WRITE, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); Modified: stable/12/contrib/elftoolchain/elfcopy/elfcopy.h ============================================================================== --- stable/12/contrib/elftoolchain/elfcopy/elfcopy.h Wed Dec 2 21:39:54 2020 (r368285) +++ stable/12/contrib/elftoolchain/elfcopy/elfcopy.h Wed Dec 2 21:44:41 2020 (r368286) @@ -298,7 +298,7 @@ void create_scn(struct elfcopy *_ecp); void create_srec(struct elfcopy *_ecp, int _ifd, int _ofd, const char *_ofn); void create_symtab(struct elfcopy *_ecp); void create_symtab_data(struct elfcopy *_ecp); -void create_tempfile(char **_fn, int *_fd); +void create_tempfile(const char *_src, char **_fn, int *_fd); void finalize_external_symtab(struct elfcopy *_ecp); void free_elf(struct elfcopy *_ecp); void free_sec_act(struct elfcopy *_ecp); Modified: stable/12/contrib/elftoolchain/elfcopy/main.c ============================================================================== --- stable/12/contrib/elftoolchain/elfcopy/main.c Wed Dec 2 21:39:54 2020 (r368285) +++ stable/12/contrib/elftoolchain/elfcopy/main.c Wed Dec 2 21:44:41 2020 (r368286) @@ -512,44 +512,57 @@ free_elf(struct elfcopy *ecp) /* Create a temporary file. */ void -create_tempfile(char **fn, int *fd) +create_tempfile(const char *src, char **fn, int *fd) { + static const char _TEMPDIR[] = "/tmp/"; + static const char _TEMPFILE[] = "ecp.XXXXXXXX"; const char *tmpdir; - char *cp, *tmpf; - size_t tlen, plen; + char *tmpf; + size_t tlen, slen, plen; -#define _TEMPFILE "ecp.XXXXXXXX" -#define _TEMPFILEPATH "/tmp/ecp.XXXXXXXX" - if (fn == NULL || fd == NULL) return; - /* Repect TMPDIR environment variable. */ - tmpdir = getenv("TMPDIR"); - if (tmpdir != NULL && *tmpdir != '\0') { - tlen = strlen(tmpdir); - plen = strlen(_TEMPFILE); - tmpf = malloc(tlen + plen + 2); + for (;;) { + if (src == NULL) { + /* Respect TMPDIR environment variable. */ + tmpdir = getenv("TMPDIR"); + if (tmpdir == NULL || *tmpdir == '\0') + tmpdir = _TEMPDIR; + tlen = strlen(tmpdir); + slen = tmpdir[tlen - 1] == '/' ? 0 : 1; + } else { + /* Create temporary file relative to source file. */ + if ((tmpdir = strrchr(src, '/')) == NULL) { + /* No path, only use a template filename. */ + tlen = 0; + } else { + /* Append the template after the slash. */ + tlen = ++tmpdir - src; + tmpdir = src; + } + slen = 0; + } + plen = strlen(_TEMPFILE) + 1; + tmpf = malloc(tlen + slen + plen); if (tmpf == NULL) err(EXIT_FAILURE, "malloc failed"); - strncpy(tmpf, tmpdir, tlen); - cp = &tmpf[tlen - 1]; - if (*cp++ != '/') - *cp++ = '/'; - strncpy(cp, _TEMPFILE, plen); - cp[plen] = '\0'; - } else { - tmpf = strdup(_TEMPFILEPATH); - if (tmpf == NULL) - err(EXIT_FAILURE, "strdup failed"); + if (tlen > 0) + memcpy(tmpf, tmpdir, tlen); + if (slen > 0) + tmpf[tlen] = '/'; + /* Copy template filename including NUL terminator. */ + memcpy(tmpf + tlen + slen, _TEMPFILE, plen); + if ((*fd = mkstemp(tmpf)) != -1) + break; + if (errno != EACCES || src == NULL) + err(EXIT_FAILURE, "mkstemp %s failed", tmpf); + /* Permission denied, try again using TMPDIR or /tmp. */ + free(tmpf); + src = NULL; } - if ((*fd = mkstemp(tmpf)) == -1) - err(EXIT_FAILURE, "mkstemp %s failed", tmpf); if (fchmod(*fd, 0644) == -1) err(EXIT_FAILURE, "fchmod %s failed", tmpf); *fn = tmpf; - -#undef _TEMPFILE -#undef _TEMPFILEPATH } /* @@ -571,16 +584,16 @@ copy_from_tempfile(const char *src, const char *dst, i if (rename(src, dst) >= 0) { *outfd = infd; return (0); - } else if (errno != EXDEV) + } else if (errno != EXDEV && errno != EACCES) return (-1); - + /* * If the rename() failed due to 'src' and 'dst' residing in * two different file systems, invoke a helper function in * libelftc to do the copy. */ - if (unlink(dst) < 0) + if (errno != EACCES && unlink(dst) < 0) return (-1); } @@ -630,7 +643,7 @@ create_file(struct elfcopy *ecp, const char *src, cons err(EXIT_FAILURE, "fstat %s failed", src); if (dst == NULL) - create_tempfile(&tempfile, &ofd); + create_tempfile(src, &tempfile, &ofd); else if ((ofd = open(dst, O_RDWR|O_CREAT, 0755)) == -1) err(EXIT_FAILURE, "open %s failed", dst); @@ -663,7 +676,7 @@ create_file(struct elfcopy *ecp, const char *src, cons if (ecp->oed == ELFDATANONE) ecp->oed = ELFDATA2LSB; } - create_tempfile(&elftemp, &efd); + create_tempfile(src, &elftemp, &efd); if ((ecp->eout = elf_begin(efd, ELF_C_WRITE, NULL)) == NULL) errx(EXIT_FAILURE, "elf_begin() failed: %s", elf_errmsg(-1)); @@ -723,7 +736,7 @@ create_file(struct elfcopy *ecp, const char *src, cons tempfile); free(tempfile); } - create_tempfile(&tempfile, &ofd0); + create_tempfile(src, &tempfile, &ofd0); /*