Nmap Development mailing list archives

-fno-strict-aliasing and strict-aliasing rules


From: David Fifield <david () bamsoftware com>
Date: Tue, 21 Jul 2009 19:06:13 -0600

On Mon, Jul 20, 2009 at 04:02:56AM +0400, Solar Designer wrote:
Attached is a patch for:

ncat_ssl.c:134: warning: passing arg 2 of `ASN1_item_d2i' from incompatible pointer type
ncat_ssl.c:138: warning: passing arg 2 of pointer to function from incompatible pointer type

 #if (OPENSSL_VERSION_NUMBER > 0x00907000L)
     if (method->it != NULL) {
         ext_str = ASN1_item_d2i(NULL,
-            (const unsigned char **) &ext->value->data,
+            (unsigned char **) &ext->value->data,
             ext->value->length, ASN1_ITEM_ptr(method->it));
     } else {
         ext_str = method->d2i(NULL,
-            (const unsigned char **) &ext->value->data,
+            (unsigned char **) &ext->value->data,
             ext->value->length);
     }
 #else

BTW, those typecasts are also potentially problematic as it relates to C
strict aliasing rules.  There are no warnings from gcc on that, but gcc
prints those "strict aliasing warnings" in _some_ cases only, depending
on the optimizer.  ...Oh, I've just realized that you build with
-fno-strict-aliasing, which should be avoiding the warnings too.  Yet
this does not fix the underlying problem, which may well bite you when
you build with a modern compiler other than gcc.

This is a valid concern. Nmap is built with -fno-strict-aliasing but
Ncat is not. I only became aware of the meaning of this option a little
while ago, after I upgraded my compiler and added -Wall to the default
Ncat flags. With GCC 4.4.0 I started to get

ncat_main.c: In function #main#:
ncat_main.c:580: warning: dereferencing pointer #srcaddr.60# does break strict-aliasing rules
ncat_main.c:580: note: initialized from here
ncat_main.c:586: warning: dereferencing pointer #srcaddr.62# does break strict-aliasing rules
ncat_main.c:586: note: initialized from here
ncat_main.c:629: warning: dereferencing pointer #sin# does break strict-aliasing rules
ncat_main.c:214: note: initialized from here
ncat_main.c:746: warning: dereferencing pointer #sin# does break strict-aliasing rules

I guess that GCC 4.4.0 is being more aggressive about strict aliasing
optimizations, because I didn't get these errors with -Wall before. The
code it references is code like this:

        struct sockaddr_in *sin = (struct sockaddr_in *) &targetss;

Which is very common practice and blessed by some standards, like RFC 3493:

        "[sockaddr_storage is] aligned at an appropriate boundary so
        that pointers to it can be cast as pointers to protocol specific
        address structures and used to access the fields of those
        structures without alignment problems."

But it is technically an aliasing violation.

You can see a sample strict aliasing fix here:

http://cvsweb.openwall.com/cgi/cvsweb.cgi/Owl/packages/popa3d/popa3d/auth_pam.c.diff?r1=1.3;r2=1.4

IIRC, another valid approach is to use a union, but I prefer separate
variables.

Thanks, I was looking for ideas to solve this. Let me be sure I
understand. In this case it works because it is a char pointer doing the
aliasing, and char pointers are specifically exempt from aliasing rules?
It would not work if template were of another type?

For Ncat I am thinking of making a sockaddr_union as suggested here:

https://bugzilla.redhat.com/show_bug.cgi?id=448743

Thanks for the help! I would appreciate your opinion if you have any
advice.

David Fifield

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: