[PATCH] binutils: objcopy/strip: fix preserving dates in ar archives
Dmitry V. Levin
ldv@altlinux.org
Mon Sep 27 22:57:19 GMT 2021
On Tue, Sep 28, 2021 at 01:09:55AM +0300, Gleb Fotengauer-Malinovskiy wrote:
> After commit 985e0264516 copy_archive function began to pass invalid values to
> the utimensat(2) function when it tries to preserve timestamps in ar archives:
>
> $ gcc -c -xc /dev/null -o t.o
> $ ar rcsU t.a t.o
> $ strace --failed-only -e /time strip -p t.a
> utimensat(AT_FDCWD, "steICERy/t.o", [{tv_sec=140428413401793, tv_nsec=48} /* 4451969-04-09T19:36:33.000000048+0000 */, {tv_sec=1632773474, tv_nsec=94919810130032}], 0) = -1 EINVAL (Invalid argument)
> strip: steICERy/t.o: cannot set time: Invalid argument
> +++ exited with 0 +++
> $ strace --failed-only -e /time objcopy -p t.a t1.a
> utimensat(AT_FDCWD, "stk5ToKP/t.o", [{tv_sec=640, tv_nsec=48} /* 1970-01-01T00:10:40.000000048+0000 */, {tv_sec=0, tv_nsec=223338299408}], 0) = -1 EINVAL (Invalid argument)
> objcopy: stk5ToKP/t.o: cannot set time: Invalid argument
> +++ exited with 0 +++
>
> This happens because the bfd_stat_arch_elt implementation for ar
> archives fills only the st_mtim.tv_sec part of the st_mtim timespec
> structure, but leaves the st_mtim.tv_nsec part and the whole st_atim timespec
> untouched leaving them uninitialized.
> This behavior did not lead to any problems before because only
> the st_atim.tv_sec were passed to the utime(2) function uninitialized,
> but it was applied to temporary file, whose access time doesn't affect
> archive contents later.
>
> Fixes: 985e0264516 ("PR27725, better objcopy -p times")
Thanks for the analysis.
> PR binutils/28391
> * binutils/objcopy.c (copy_archive): Clear buf using memset.
> ---
> binutils/objcopy.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/binutils/objcopy.c b/binutils/objcopy.c
> index a6c2e0dcc26..867aba32cd4 100644
> --- a/binutils/objcopy.c
> +++ b/binutils/objcopy.c
> @@ -3600,6 +3600,7 @@ copy_archive (bfd *ibfd, bfd *obfd, const char *output_target,
>
> if (preserve_dates)
> {
> + memset(buf, &buf, 0, sizeof(buf));
> stat_status = bfd_stat_arch_elt (this_element, &buf);
Did you mean memset(&buf, 0, sizeof(buf)) ?
--
ldv
More information about the Binutils
mailing list