]> nv-tegra.nvidia Code Review - linux-2.6.git/commitdiff
[SCTP] bug: sctp_assoc_control_transport() breakage
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 21 Nov 2006 01:03:01 +0000 (17:03 -0800)
committerDavid S. Miller <davem@sunset.davemloft.net>
Sun, 3 Dec 2006 05:26:27 +0000 (21:26 -0800)
a) struct sockaddr_storage * passed to sctp_ulpevent_make_peer_addr_change()
actually points at union sctp_addr field in a structure.  Then that sucker
gets copied to userland, with whatever junk we might have there.

b) it's actually having host-endian sin_port.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/sctp/associola.c

index 7639044b00749a1c5e0e8d149aa2a4a794142c23..746b0b0f5ace9a546baca7a26920cc7af7b3bb82 100644 (file)
@@ -709,6 +709,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
        struct sctp_transport *first;
        struct sctp_transport *second;
        struct sctp_ulpevent *event;
+       struct sockaddr_storage addr;
        struct list_head *pos;
        int spc_state = 0;
 
@@ -731,8 +732,9 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
        /* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the
         * user.
         */
-       event = sctp_ulpevent_make_peer_addr_change(asoc,
-                               (struct sockaddr_storage *) &transport->ipaddr,
+       memset(&addr, 0, sizeof(struct sockaddr_storage));
+       flip_to_n((union sctp_addr *)&addr, &transport->ipaddr);
+       event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
                                0, spc_state, error, GFP_ATOMIC);
        if (event)
                sctp_ulpq_tail_event(&asoc->ulpq, event);