-
Notifications
You must be signed in to change notification settings - Fork 88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed stack corruption on some phones... #4
base: master
Are you sure you want to change the base?
Conversation
…oved that to a block allocated in main memory.
I tried your code and it's still doing stack corruptions... :/ |
Me too... |
I also had a stack corrution and I think, I found the cause. The array struct ifaddrs *l_links[l_numLinks]; is too small. Its size is determined by counting the RTM_NEWLINK messages, but is is indexed by l_info->ifi_index - 1. When e.g. network namespaces are used, ifi_index values are not continuous. I added some print statements and got this output: l_numLinks=2 So, l_numLinks should be determined by finding the max value of l_info->ifi_index. |
The code also does not behave correctly, when the buffer for receiving Netlink messages is too small. Here is my fix for both problems: --- getifaddrs.c (revision 15518)
+++ getifaddrs.c (working copy)
@@ -96,8 +96,11 @@
l_msg.msg_control = NULL;
l_msg.msg_controllen = 0;
l_msg.msg_flags = 0;
- int l_result = recvmsg(p_socket, &l_msg, 0);
-
+ int l_result = recvmsg(p_socket, &l_msg, MSG_PEEK | MSG_TRUNC);
+ if (l_result > p_len)// buffer was too small
+ return -1;
+
+ l_result = recvmsg(p_socket, &l_msg, 0);
if(l_result < 0)
{
if(errno == EINTR)
@@ -106,11 +109,6 @@
}
return -2;
}
-
- if(l_msg.msg_flags & MSG_TRUNC)
- { // buffer was too small
- return -1;
- }
return l_result;
}
}
@@ -521,9 +519,9 @@
}
}
-static unsigned countLinks(int p_socket, NetlinkList *p_netlinkList)
+static unsigned get_max_ifi_index(int p_socket, NetlinkList *p_netlinkList)
{
- unsigned l_links = 0;
+ unsigned l_max_ifi_index = 0;
pid_t l_pid = getpid();
for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
{
@@ -543,12 +541,14 @@
if(l_hdr->nlmsg_type == RTM_NEWLINK)
{
- ++l_links;
+ struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(l_hdr);
+ if (l_max_ifi_index < l_info->ifi_index)
+ l_max_ifi_index = l_info->ifi_index;
}
}
}
- return l_links;
+ return l_max_ifi_index;
}
int getifaddrs(struct ifaddrs **ifap)
@@ -580,9 +580,9 @@
return -1;
}
- unsigned l_numLinks = countLinks(l_socket, l_linkResults) + countLinks(l_socket, l_addrResults);
- struct ifaddrs *l_links[l_numLinks];
- memset(l_links, 0, l_numLinks * sizeof(struct ifaddrs *));
+ unsigned l_max_ifi_index = get_max_ifi_index(l_socket, l_linkResults) + get_max_ifi_index(l_socket, l_addrResults);
+ struct ifaddrs *l_links[l_max_ifi_index];
+ memset(l_links, 0, l_max_ifi_index * sizeof(struct ifaddrs *));
interpret(l_socket, l_linkResults, l_links, ifap);
interpret(l_socket, l_addrResults, l_links, ifap); |
In the end I copied the implementation from aosp: https://github.com/Mygod/DHCPv6-Client-Android/tree/master/mobile/src/main/cpp |
The aosp version is only 240 lines, while this implementation is 600 lines. But the short version uses an RX buffer with fixed size of 8192. I have not enough experience with Netlink communication to be sure, that it always is lage enough and no Netlink message gets truncated. |
me too.. |
I cannot understand this diff, please make a PULL REQUEST with the fixed code if possible :( @Mario-Klebsch |
These days I use this code for try to add functions to support my Android HUAWEI P9. Because my HUAWEI P9 is API level 23, which doesn't have this function in NDK. When I write a small program for test, It's always cause stack corruption in my Android phone. After debug and trace, I found at: Line 473 in 8f9a87c
char l_mask[16] = {0}; I change this line to: char l_mask[20] = {0}; It looks like work well now. |
the dynamically allocated array on the stack can crash some phones, moved that to a block allocated in main memory.