[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#673112: lintian: hardening-no-stackprotector check has many false positives



On 2012-05-22 13:05, Niels Thykier wrote:
> [...]
> 
> Turns out hardening-check has a verbose flag that makes it print the
> affected functions - testing amarok (testing i386) I got[1].  Looks like
> memcpy is the primary source of false-positives (for amarok).
> 
> If it turns out that memcpy is (in general) the primary source of these
> false-positives, perhaps it would be better to skip that particular
> function than disable the entire check.
> 
> ~Niels
> 
> [1]
> [...]
> 
> 
> 


Okay, final "spam" for now.

I think it would be a very good idea to drop at least memcpy from the
hardening-check because GCC 4.7 (at -O2 or higher), GCC may replace
strcpy and other functions with memcpy[1].

I have tested a little code snippet[2] with gcc-4.7 and it indeed it
replaces strcpy with memcpy at -O2.  Also it never uses the fortified
variant of strcpy/memcpy (not even at -O0) in this "trivial case".

So for -O0 binaries we would still get false-positives in this case (and
binaries compiled with < 4.7), but we would presumably avoid a lot of
false-positiives for binaries compiled by gcc-4.7 -O2 in this way.

~Niels

[1] http://gcc.gnu.org/gcc-4.7/changes.html

"""
A string length optimization pass has been added. It attempts to track
string lengths and optimize various standard C string functions like
strlen, strchr, strcpy, strcat, stpcpy and their _FORTIFY_SOURCE
counterparts into faster alternatives. This pass is enabled by default
at -O2 or above, unless optimizing for size, and can be disabled by the
-fno-optimize-strlen option. The pass can e.g. optimize

char *bar (const char *a)
{
  size_t l = strlen (a) + 2;
  char *p = malloc (l); if (p == NULL) return p;
  strcpy (p, a); strcat (p, "/"); return p;
}

into:

char *bar (const char *a)
{
  size_t tmp = strlen (a);
  char *p = malloc (tmp + 2); if (p == NULL) return p;
  memcpy (p, a, tmp); memcpy (p + tmp, "/", 2); return p;
}
[...]
"""

[2] // Poor man's strdup
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv) {
  const char *s = argv[0];
  size_t l = strlen(s);
  char *cpy = malloc (l + 1);
  if (!cpy)
    return 1;
  strcpy(cpy, s);
  cpy[0] = 'b';
  printf("%s\n", cpy);
  return 0;
}





Reply to: