]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Move safememcpy() to util.c so it doesn't get inlined.
authorGuy Harris <[email protected]>
Thu, 16 Jan 2014 02:12:06 +0000 (18:12 -0800)
committerGuy Harris <[email protected]>
Thu, 16 Jan 2014 02:12:06 +0000 (18:12 -0800)
It appears that some C compilers will inline safememcpy() *and* will, as
a result, optimize to assume alignment it if it's passed a
putatively-aligned pointer. As the pointers in question are not
guaranteed to be aligned, that can cause crashes on, for example, SPARC.

Also, rename the function to unaligned_memcpy(), to clarify what's
"safe" about it, and change some direct memcpy() calls to use it as
well.

interface.h
netdissect.h
print-isakmp.c
util.c

index f551752f87efcc0da35579796d2e960345656bef..8ed4a4a8f747ff2bc40150e20d8b82d86612ccaf 100644 (file)
@@ -158,6 +158,8 @@ extern char *copy_argv(char **);
 extern void safeputchar(int);
 extern void safeputs(const char *, int);
 
+extern void unaligned_memcpy(void *, const void *, size_t);
+
 extern const char *isonsap_string(const u_char *, register u_int);
 extern const char *protoid_string(const u_char *);
 extern const char *ipxsap_string(u_short);
index 8369eda6240db612e9f2bdb5a8c2ff360e6f1031..0b194c95661753702e00fb94a6d1f53f529477c1 100644 (file)
@@ -270,6 +270,8 @@ extern char *copy_argv(netdissect_options *, char **);
 extern void safeputchar(int);
 extern void safeputs(const char *, int);
 
+extern void unaligned_memcpy(void *, const void *, size_t);
+
 #define PLURAL_SUFFIX(n) \
        (((n) != 1) ? "s" : "")
 
index e2dbf7d354c2cfdfb02fc8112326a5a3fd3bde52..194a28379d35560bcba29014cbe17b9b4f512f07 100644 (file)
@@ -645,7 +645,6 @@ static const u_char *ikev2_sub_print(netdissect_options *ndo,
 
 
 static char *numstr(int);
-static void safememcpy(void *, const void *, size_t);
 
 static void
 ikev1_print(netdissect_options *ndo,
@@ -808,13 +807,13 @@ cookie_record(cookie_t *in, const u_char *bp2)
                sin->sin_len = sizeof(struct sockaddr_in);
 #endif
                sin->sin_family = AF_INET;
-               memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
+               unaligned_memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
                sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
 #ifdef HAVE_SOCKADDR_SA_LEN
                sin->sin_len = sizeof(struct sockaddr_in);
 #endif
                sin->sin_family = AF_INET;
-               memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
+               unaligned_memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
                break;
 #ifdef INET6
        case 6:
@@ -829,19 +828,19 @@ cookie_record(cookie_t *in, const u_char *bp2)
                sin6->sin6_len = sizeof(struct sockaddr_in6);
 #endif
                sin6->sin6_family = AF_INET6;
-               memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
+               unaligned_memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
                sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
 #ifdef HAVE_SOCKADDR_SA_LEN
                sin6->sin6_len = sizeof(struct sockaddr_in6);
 #endif
                sin6->sin6_family = AF_INET6;
-               memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
+               unaligned_memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
                break;
 #endif
        default:
                return;
        }
-       memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
+       unaligned_memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
        ninitiator = (ninitiator + 1) % MAXINITIATORS;
 }
 
@@ -869,7 +868,7 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator)
                sin->sin_len = sizeof(struct sockaddr_in);
 #endif
                sin->sin_family = AF_INET;
-               memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
+               unaligned_memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
                break;
 #ifdef INET6
        case 6:
@@ -879,7 +878,7 @@ cookie_sidecheck(int i, const u_char *bp2, int initiator)
                sin6->sin6_len = sizeof(struct sockaddr_in6);
 #endif
                sin6->sin6_family = AF_INET6;
-               memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
+               unaligned_memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
                break;
 #endif
        default:
@@ -1072,7 +1071,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_sa *)ext;
        ND_TCHECK(*p);
-       safememcpy(&sa, ext, sizeof(sa));
+       unaligned_memcpy(&sa, ext, sizeof(sa));
        doi = ntohl(sa.doi);
        sit = ntohl(sa.sit);
        if (doi != 1) {
@@ -1098,7 +1097,7 @@ ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
        np = (u_char *)ext + sizeof(sa);
        if (sit != 0x01) {
                ND_TCHECK2(*(ext + 1), sizeof(ident));
-               safememcpy(&ident, ext + 1, sizeof(ident));
+               unaligned_memcpy(&ident, ext + 1, sizeof(ident));
                ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));
                np += sizeof(ident);
        }
@@ -1129,7 +1128,7 @@ ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_p *)ext;
        ND_TCHECK(*p);
-       safememcpy(&prop, ext, sizeof(prop));
+       unaligned_memcpy(&prop, ext, sizeof(prop));
        ND_PRINT((ndo," #%d protoid=%s transform=%d",
                  prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
        if (prop.spi_size) {
@@ -1296,7 +1295,7 @@ ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_t *)ext;
        ND_TCHECK(*p);
-       safememcpy(&t, ext, sizeof(t));
+       unaligned_memcpy(&t, ext, sizeof(t));
 
        switch (proto) {
        case 1:
@@ -1358,7 +1357,7 @@ ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
@@ -1395,7 +1394,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_id *)ext;
        ND_TCHECK(*p);
-       safememcpy(&id, ext, sizeof(id));
+       unaligned_memcpy(&id, ext, sizeof(id));
        if (sizeof(*p) < item_len) {
                data = (u_char *)(p + 1);
                len = item_len - sizeof(*p);
@@ -1428,7 +1427,7 @@ ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
 
                p = (struct ipsecdoi_id *)ext;
                ND_TCHECK(*p);
-               safememcpy(&id, ext, sizeof(id));
+               unaligned_memcpy(&id, ext, sizeof(id));
                ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
                if (id.proto_id) {
 #ifndef WIN32
@@ -1569,7 +1568,7 @@ ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_cert *)ext;
        ND_TCHECK(*p);
-       safememcpy(&cert, ext, sizeof(cert));
+       unaligned_memcpy(&cert, ext, sizeof(cert));
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
        if (2 < ndo->ndo_vflag && 4 < item_len) {
@@ -1601,7 +1600,7 @@ ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_cert *)ext;
        ND_TCHECK(*p);
-       safememcpy(&cert, ext, sizeof(cert));
+       unaligned_memcpy(&cert, ext, sizeof(cert));
        ND_PRINT((ndo," len=%d", item_len - 4));
        ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
        if (2 < ndo->ndo_vflag && 4 < item_len) {
@@ -1626,7 +1625,7 @@ ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
@@ -1650,7 +1649,7 @@ ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
@@ -1676,7 +1675,7 @@ ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
@@ -1754,7 +1753,7 @@ ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_n *)ext;
        ND_TCHECK(*p);
-       safememcpy(&n, ext, sizeof(n));
+       unaligned_memcpy(&n, ext, sizeof(n));
        doi = ntohl(n.doi);
        proto = n.prot_id;
        if (doi != 1) {
@@ -1851,7 +1850,7 @@ ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev1_pl_d *)ext;
        ND_TCHECK(*p);
-       safememcpy(&d, ext, sizeof(d));
+       unaligned_memcpy(&d, ext, sizeof(d));
        doi = ntohl(d.doi);
        proto = d.prot_id;
        if (doi != 1) {
@@ -1890,7 +1889,7 @@ ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
        ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
        if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
                ND_PRINT((ndo," "));
@@ -1922,7 +1921,7 @@ ikev2_gen_print(netdissect_options *ndo, u_char tpay,
        struct isakmp_gen e;
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
 
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
@@ -1954,7 +1953,7 @@ ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
 
        p = (struct ikev2_t *)ext;
        ND_TCHECK(*p);
-       safememcpy(&t, ext, sizeof(t));
+       unaligned_memcpy(&t, ext, sizeof(t));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
 
        t_id = ntohs(t.t_id);
@@ -2027,7 +2026,7 @@ ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
 
        p = (struct ikev2_p *)ext;
        ND_TCHECK(*p);
-       safememcpy(&prop, ext, sizeof(prop));
+       unaligned_memcpy(&prop, ext, sizeof(prop));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
 
        ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
@@ -2062,7 +2061,7 @@ ikev2_sa_print(netdissect_options *ndo, u_char tpay,
        int    osa_length, sa_length;
 
        ND_TCHECK(*ext1);
-       safememcpy(&e, ext1, sizeof(e));
+       unaligned_memcpy(&e, ext1, sizeof(e));
        ikev2_pay_print(ndo, "sa", e.critical);
 
        osa_length= ntohs(e.len);
@@ -2091,7 +2090,7 @@ ikev2_ke_print(netdissect_options *ndo, u_char tpay,
 
        k = (struct ikev2_ke *)ext;
        ND_TCHECK(*ext);
-       safememcpy(&ke, ext, sizeof(ke));
+       unaligned_memcpy(&ke, ext, sizeof(ke));
        ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
 
        ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
@@ -2121,7 +2120,7 @@ ikev2_ID_print(netdissect_options *ndo, u_char tpay,
        unsigned char *typedata;
 
        ND_TCHECK(*ext);
-       safememcpy(&id, ext, sizeof(id));
+       unaligned_memcpy(&id, ext, sizeof(id));
        ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
 
        id_len = ntohs(id.h.len);
@@ -2224,7 +2223,7 @@ ikev2_auth_print(netdissect_options *ndo, u_char tpay,
        unsigned int len;
 
        ND_TCHECK(*ext);
-       safememcpy(&a, ext, sizeof(a));
+       unaligned_memcpy(&a, ext, sizeof(a));
        ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
        len = ntohs(a.h.len);
 
@@ -2256,7 +2255,7 @@ ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
        struct isakmp_gen e;
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, "nonce", e.critical);
 
        ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
@@ -2291,7 +2290,7 @@ ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
 
        p = (struct ikev2_n *)ext;
        ND_TCHECK(*p);
-       safememcpy(&n, ext, sizeof(n));
+       unaligned_memcpy(&n, ext, sizeof(n));
        ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
 
        showspi = 1;
@@ -2505,7 +2504,7 @@ ikev2_vid_print(netdissect_options *ndo, u_char tpay,
        int i, len;
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
        ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
 
@@ -2568,7 +2567,7 @@ ikev2_e_print(netdissect_options *ndo,
        volatile int dlen;
 
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
        ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
 
        dlen = ntohs(e.len)-4;
@@ -2640,7 +2639,7 @@ ike_sub0_print(netdissect_options *ndo,
 
        cp = (u_char *)ext;
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
 
        /*
         * Since we can't have a payload length of less than 4 bytes,
@@ -2683,7 +2682,7 @@ ikev1_sub_print(netdissect_options *ndo,
        while (np) {
                ND_TCHECK(*ext);
 
-               safememcpy(&e, ext, sizeof(e));
+               unaligned_memcpy(&e, ext, sizeof(e));
 
                ND_TCHECK2(*ext, ntohs(e.len));
 
@@ -2718,17 +2717,6 @@ numstr(int x)
        return buf;
 }
 
-/*
- * some compiler tries to optimize memcpy(), using the alignment constraint
- * on the argument pointer type.  by using this function, we try to avoid the
- * optimization.
- */
-static void
-safememcpy(void *p, const void *q, size_t l)
-{
-       memcpy(p, q, l);
-}
-
 static void
 ikev1_print(netdissect_options *ndo,
            const u_char *bp,  u_int length,
@@ -2815,7 +2803,7 @@ ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
 
        cp = (u_char *)ext;
        ND_TCHECK(*ext);
-       safememcpy(&e, ext, sizeof(e));
+       unaligned_memcpy(&e, ext, sizeof(e));
 
        /*
         * Since we can't have a payload length of less than 4 bytes,
@@ -2871,7 +2859,7 @@ ikev2_sub_print(netdissect_options *ndo,
                pcount++;
                ND_TCHECK(*ext);
 
-               safememcpy(&e, ext, sizeof(e));
+               unaligned_memcpy(&e, ext, sizeof(e));
 
                ND_TCHECK2(*ext, ntohs(e.len));
 
@@ -2983,7 +2971,7 @@ isakmp_print(netdissect_options *ndo,
                return;
        }
 
-       safememcpy(&base, p, sizeof(base));
+       unaligned_memcpy(&base, p, sizeof(base));
 
        ND_PRINT((ndo,"isakmp"));
        major = (base.vers & ISAKMP_VERS_MAJOR)
diff --git a/util.c b/util.c
index d7aa1fa75c28b871f3724570645caea06002beba..f93ed43767340c8bd00643d6955fcec9ddef9a5f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -601,3 +601,14 @@ safeputchar(int c)
        else
                printf("\\0x%02x", ch);
 }
+
+/*
+ * some compiler tries to optimize memcpy(), using the alignment constraint
+ * on the argument pointer type.  by using this function, we try to avoid the
+ * optimization.
+ */
+void
+unaligned_memcpy(void *p, const void *q, size_t l)
+{
+       memcpy(p, q, l);
+}