随机双免或无效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
选项)。这样,您将获得文件名和行号以帮助您进行调试。
所以我的程序现在遇到了问题(好吧,更多的是我编写的共享库)。我正在尝试实施 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
选项)。这样,您将获得文件名和行号以帮助您进行调试。