GCC7 adds warnings for snprintf formatting into too small buffers.
Fix the two issues pointed out by the new warning. The ar header
fields are fixed length containing left-justified strings without
zero terminator. snprintf always adds a '\0' char at the end (which
we then don't copy into the ar header field) and numbers are decimal
strings of fixed 10 chars (-Wformat-length thinks formatting
them as size_t might overflow the buffer on 64bit arches).
Signed-off-by: Mark Wielaard <mjw@redhat.com>
+2016-11-10 Mark Wielaard <mjw@redhat.com>
+
+ * ar.c (write_member): Make sure tmpbuf is large enough to contain
+ a starting '/' and ending '\0' char.
+ (do_oper_insert): Likewise.
+ * arlib.c (arlib_finalize): Format tmpbuf as PRId32 decimal.
+
2016-11-02 Mark Wielaard <mjw@redhat.com>
* addr2line.c (handle_address): Add fallthrough comment.
/* Create, modify, and extract from archives.
- Copyright (C) 2005-2012 Red Hat, Inc.
+ Copyright (C) 2005-2012, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2005.
off_t end_off, int newfd)
{
struct ar_hdr arhdr;
- char tmpbuf[sizeof (arhdr.ar_name) + 1];
+ /* The ar_name is not actually zero teminated, but we need that for
+ snprintf. Also if the name is too long, then the string starts
+ with '/' plus an index off number (decimal). */
+ char tmpbuf[sizeof (arhdr.ar_name) + 2];
bool changed_header = memb->long_name_off != -1;
if (changed_header)
/* Create the header. */
struct ar_hdr arhdr;
- char tmpbuf[sizeof (arhdr.ar_name) + 1];
+ /* The ar_name is not actually zero teminated, but we
+ need that for snprintf. Also if the name is too
+ long, then the string starts with '/' plus an index
+ off number (decimal). */
+ char tmpbuf[sizeof (arhdr.ar_name) + 2];
if (all->long_name_off == -1)
{
size_t namelen = strlen (all->name);
}
else
{
- snprintf (tmpbuf, sizeof (arhdr.ar_name) + 1, "/%-*ld",
+ snprintf (tmpbuf, sizeof (tmpbuf), "/%-*ld",
(int) sizeof (arhdr.ar_name), all->long_name_off);
memcpy (arhdr.ar_name, tmpbuf, sizeof (arhdr.ar_name));
}
/* Functions to handle creation of Linux archives.
- Copyright (C) 2007-2012 Red Hat, Inc.
+ Copyright (C) 2007-2012, 2016 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper@redhat.com>, 2007.
#include <assert.h>
#include <error.h>
#include <gelf.h>
+#include <inttypes.h>
#include <libintl.h>
#include <stdio.h>
#include <stdlib.h>
void
arlib_finalize (void)
{
+ /* Note that the size is stored as decimal string in 10 chars,
+ without zero terminator (we add + 1 here only so snprintf can
+ put it at the end, we then don't use it when we memcpy it). */
char tmpbuf[sizeof (((struct ar_hdr *) NULL)->ar_size) + 1];
symtab.longnameslen = obstack_object_size (&symtab.longnamesob);
symtab.longnames = obstack_finish (&symtab.longnamesob);
- int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ int s = snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
- symtab.longnameslen - sizeof (struct ar_hdr));
+ (uint32_t) (symtab.longnameslen - sizeof (struct ar_hdr)));
memcpy (&((struct ar_hdr *) symtab.longnames)->ar_size, tmpbuf, s);
}
/* See comment for ar_date above. */
memcpy (&((struct ar_hdr *) symtab.symsoff)->ar_size, tmpbuf,
- snprintf (tmpbuf, sizeof (tmpbuf), "%-*zu",
+ snprintf (tmpbuf, sizeof (tmpbuf), "%-*" PRIu32 "",
(int) sizeof (((struct ar_hdr *) NULL)->ar_size),
- symtab.symsofflen + symtab.symsnamelen
- - sizeof (struct ar_hdr)));
+ (uint32_t) (symtab.symsofflen + symtab.symsnamelen
+ - sizeof (struct ar_hdr))));
}