segmentation fault on memcpy

the full code is in

http://docs.google.com/file/d/0B09y_TWqTtwlaHNjdjYybHVIcjA/edit?usp=sharing

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
        char data[]="just for a try";
        u_char *packet=(u_char *)malloc(28+sizeof(data));
         ...
         ...


        u_char *udp_data=(u_char *)malloc(8+sizeof(data));
        if(udp_data == NULL )
                perror("allocating space for udp_data fails\n");
        memcpy(udp_data, &udp, sizeof(udp));
        memcpy(udp_data+8, data, sizeof(data));
        udp.check = in_cksum_udp(ip.ip_src.s_addr, ip.ip_dst.s_addr, (unsigned short *)udp_data, sizeof(udp)+sizeof(data)); // if I comment this line, no segmentation fault!
        free(udp_data);
        udp_data=NULL;
        
        // I get segmentation fault on the next line:
        memcpy(packet + 20, &udp, sizeof(udp));


so the problem is the cksum_udp() function
the in_cksum_udp() function is as below, I don't see any problems:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    struct psd_udp {
        struct in_addr src;
        struct in_addr dst;
        unsigned char pad;
        unsigned char proto;
        unsigned short udp_len;
        struct udphdr udp;
    };

    unsigned short in_cksum(unsigned short *addr, int len)
    {
        int nleft = len;
        int sum = 0;
        unsigned short *w = addr;
        unsigned short answer = 0;

        while (nleft > 1) {
                sum += *w++;
                nleft -= 2;
        }

        if (nleft == 1) {
                *(unsigned char *) (&answer) = *(unsigned char *) w;
                sum += answer;
        }

        sum = (sum >> 16) + (sum & 0xFFFF);
        sum += (sum >> 16);
        answer = ~sum;
        return (answer);
    }


    unsigned short in_cksum_udp(int src, int dst, unsigned short *addr, int len)
    {
        struct psd_udp buf;

        memset(&buf, 0, sizeof(buf));
        buf.src.s_addr = src;
        buf.dst.s_addr = dst;
        buf.pad = 0;
        buf.proto = IPPROTO_UDP;
        buf.udp_len = htons(len);
        memcpy(&(buf.udp), addr, len);
        return in_cksum((unsigned short *)&buf, 12 + len);
    }


basically, it seems the function has nothing to do with the memory pointed by the pointer packet
what are potential problems?
thanks!
Last edited on
// if I comment this line, no segmentation fault!

Unfortunately, this does not tell you anything.

To assume the problem is in that function based on this alone is probably not the best move. That's what's so nasty about memory corruption issues.

You're lucky, though, in that the crash is easy and consistent to reproduce.




Start with the memcpy call itself. For memcpy to call a segfault, you must be stepping out of bounds either during the read or the write. The write is more likely.

Put breakpoints after the initialization of packet and on the memcpy line. Look at the contents of the pointer (ie: the address it's pointing to) to make sure it's the same at both times.

If it's different, it's likely that memory corruption is causing your pointer to point to somewhere else, making it a bad pointer. This is very likely to cause a segfault. If that's the case, step through your code, keeping an eye on that pointer to see where it gets changed. Or better yet, if your IDE/Debugger supports it, set a "memory breakpoint" to trigger when that variable changes.


If the pointer is correct at the time of the memcpy... then that means either the memory it points to is either no longer allocated (you're accidentally free'ing it prematurely)... or it's a problem with the source buffer.

I don't think it's the latter since udp looks like a local variable.. so there's no way the pointer to it could be corrupted.
Make sure 28+sizeof(data) is bigger than 8+sizeof(udp)
Last edited on
Topic archived. No new replies allowed.