why does the sendto function return error: Bad File descriptor? This only happens on Linux (in Windows it works properly).
Here is my code:
json object hb is a classical json object, such as { "name": "alfa", "surname": "beta"}
, converted to string by its method
int fd;
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
print_time();
perror("Socket failed\n");
exit(EXIT_FAILURE);
}
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
//memset(&cliaddr, 0, sizeof(cliaddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(9900);
serveraddr.sin_addr.s_addr = inet_addr("192.168.1.96");
char ui_request_str[] = "";
strcpy(ui_request_str, json_object_to_json_string(hb));
if (sendto(fd, ui_request_str, strlen(ui_request_str), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("Error");
}
else
{
debug_level > 0 && printf("message sent: %s\n", ui_request_str);
}
close(fd);
CodePudding user response:
problem
Your problem comes from memory that you don't allocate:
char ui_request_str[] = "";
strcpy(ui_request_str, json_object_to_json_string(hb));
Of first line, you allocate a one bytes array.
On second line, you try to write the memory you reserved with the output of json_object_to_json_string
You are code generates a buffer overruns:
From man strcpy:
Bugs
If the destination string of astrcpy()
is not large enough, then anything might happen. Overflowing fixed-length string buffers is a favorite cracker technique for taking complete control of the machine. Any time a program reads or copies data into a buffer, the program first needs to check that there's enough space. This may be unnecessary if you can show that overflow is impossible, but be careful: programs can get changed over time, in ways that may make the impossible possible.
solution
Don't make ui_request_str
an array, make it a pointer:
char * ui_request_str[];
ui_request_str = json_object_to_json_string(hb);
if (NULL == ui_request_str) {
perror(";json_object_to_json_string");
exit(0);
}
if (sendto(fd, ui_request_str, strlen(ui_request_str), 0, (struct sockaddr *)&serveraddr, sizeof(serveraddr)) < 0)
{
perror("Error");
}
else
{
debug_level > 0 && printf("message sent: %s\n", ui_request_str);
}