随机双免或无效next_size

Random double free or invalid next_size

所以我的程序现在遇到了问题(好吧,更多的是我编写的共享库)。我正在尝试实施 TCP/IP 堆栈,目前正在尝试实施 ARP。 ARP 工作,解析和回复,但是我的 ARP 服务器会随机崩溃(有时 运行 10-20 分钟,每秒被 40-50 个 arp 请求淹没)来自 Double free() 或无效 next_size(总是在 rx_buff 指针上)。

失败时,总是在最后一行或倒数第二行的空闲位置失败。

你们中有人知道为什么会这样吗? 要点在这里:https://gist.github.com/thehunt33r/651f76fe08ca06ec74ee

编辑:感谢将代码包含在编辑中的人,谢谢 :)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <stdint.h>
#include <errno.h>
#include <arpa/inet.h>
#include <linux/if_packet.h>
#include <sys/ioctl.h>
//#include <net/if.h>
#include <netinet/ether.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <linux/netdevice.h>
#define ARP 1
/* Define structures */
typedef struct {
    uint8_t mac_dest[6];
    uint8_t mac_src[6];
    uint16_t ether_type;
} eth_header_t;
typedef struct {
    uint16_t hardware_type;
    uint16_t protocol_type;
    uint8_t hardware_l;
    uint8_t protocol_l;
    uint16_t operation;
    uint8_t sender_hwa[6];
    uint8_t sender_ip[4];
    uint8_t target_hwa[6];
    uint8_t target_ip[4];
} arp_header_t;
/* End Structures*/

eth_header_t parse_eth_header(uint8_t *buffer) { //parse eth header
    int i = 0;
    eth_header_t tmp;
    for (i = 0; i < 6; i++) {
        tmp.mac_dest[i] = buffer[i];
    }
    buffer += 6;
    for (i = 0; i < 6; i++) {
        tmp.mac_src[i] = buffer[i];
    }
    tmp.ether_type = (buffer[7] << 8) | buffer[6];
    uint8_t *tmp_8 = (uint8_t * ) & tmp.ether_type;
    tmp_8[0] = buffer[6];
    tmp_8[1] = buffer[7];

    return tmp;
}

/* Reading function */
int sup_read(int protocol, uint8_t *buffer, int buffer_length) {
    int s;
    s = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (s == -1) {
        printf("Erreur lors de l'ouverture de la socket");
    }
    uint8_t *rx_buff = (uint8_t *) malloc(1500);
    int exit = 1;
    int length = 0;
    while (exit) {
        length = recvfrom(s, rx_buff, 65535, 0, NULL, NULL);
        uint8_t *tmp1 = rx_buff;
        eth_header_t tmp_head = parse_eth_header(rx_buff);
        eth_header_t *eth_head = &tmp_head;
        eth_head->ether_type = htons(eth_head->ether_type);
        switch (eth_head->ether_type) {
        case 0x0806:
            if (protocol == ARP) {
                tmp1 = rx_buff;
                tmp1 += sizeof(eth_header_t);
                length -=sizeof(eth_header_t);
                memcpy(buffer,rx_buff,length);
                printf("This is an ARP frame");
                exit=0;
            }
            break;
        }
    }
    close(s);
    free(rx_buff);
    return length;
}
/*End reading*/


int main(){
  uint8_t *buffer = (uint8_t *) malloc(1500);
  while(1){
     sup_read(1, buffer, sizeof(buffer));
}
}

sup_read() 中,您有:

uint8_t *rx_buff = (uint8_t *) malloc(1500);
int exit = 1;
int length = 0;
while (exit) {
    length = recvfrom(s, rx_buff, 65535, 0, NULL, NULL);

您分配了 1500 个字节,但您告诉 recvfrom() 它有 65535 个字节可供使用。这可能是你问题的一部分。

如果是问题所在,运行 valgrind 或类似的东西会很快告诉您滥用情况。如果您遇到双重释放问题或其他类似的内存分配问题,valgrind 很有可能会及时帮助您。请记住为目标文件和最终可执行文件进行调试编译(通常是 -g 选项)。这样,您将获得文件名和行号以帮助您进行调试。