This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[patch] For memory access error when calling _stp_sockaddr_str with addrlen set to 0
- From: "Zhaolei" <zhaolei at cn dot fujitsu dot com>
- To: <systemtap at sourceware dot org>
- Cc: "Zhaolei" <zhaolei at cn dot fujitsu dot com>
- Date: Wed, 5 Sep 2007 17:34:28 +0900
- Subject: [patch] For memory access error when calling _stp_sockaddr_str with addrlen set to 0
- References: <1188780895.5736.ezmlm@sourceware.org> <006d01c7edd9$55a2b080$85697c0a@guest004>
Hi, everyone
I found a memory access error in aux_syscall.stp's _stp_sockaddr_str
function.
When probing a function which uses _stp_sockaddr_str with addrlen set to 0,
Ex: bind(sockfd, my_addr, 0);
the calling stack is:
probe bind [bind(sockfd, my_addr, 0)]
--> _struct_sockaddr_u [copy 0 byte from my_addr in userspace to buf]
--> _stp_sockaddr_str [access buf's content in switch (sa->sa_family)]
In this case, sa->sa_family will not be initialized.
Also, I think the buf's length should be considered when using it.
If no objection, I will commit the following patch:
Signed-off-by: "Zhaolei" zhaolei@cn.fujitsu.com
--- aux_syscalls.stp.old 2007-08-30 14:56:29.000000000 +0900
+++ aux_syscalls.stp 2007-08-30 15:38:40.000000000 +0900
@@ -309,36 +309,31 @@ function _struct_itimerval:string(addr:l
void _stp_sockaddr_str(char *str, const int strlen, char *buf, int len)
{
struct sockaddr *sa = (struct sockaddr *)buf;
- switch (sa->sa_family) {
- case AF_INET:
+ if ((sa->sa_family == AF_INET)&&(len == 16))
{
struct sockaddr_in *sin = (struct sockaddr_in *)buf;
const unsigned char *addr = (unsigned char *)&sin->sin_addr;
snprintf(str, strlen, "{AF_INET, %d.%d.%d.%d, %d}",
addr[0], addr[1], addr[2], addr[3], ntohs(sin->sin_port));
- break;
}
- case AF_UNIX:
+ else if ((sa->sa_family == AF_UNIX)&&(len == 110))
{
struct sockaddr_un *sun = (struct sockaddr_un *)buf;
snprintf(str, strlen, "{AF_UNIX, %s}", sun->sun_path);
- break;
}
- case AF_NETLINK:
+ else if ((sa->sa_family == AF_NETLINK)&&(len == 12))
{
struct sockaddr_nl *nl = (struct sockaddr_nl *)buf;
snprintf(str, strlen, "{AF_NETLINK, pid=%d, groups=%08x}", nl->nl_pid, nl->nl_groups);
- break;
}
- case AF_INET6:
+ else if ((sa->sa_family == AF_INET6)&&(len == 28))
{
// FIXME. Address is probably not correctly displayed
struct sockaddr_in6 *sin = (struct sockaddr_in6 *)buf;
snprintf(str, strlen, "{AF_INET6, %016llx, %d}",
*(long long *)&sin->sin6_addr, ntohs(sin->sin6_port));
- break;
}
- case AF_PACKET:
+ else if ((sa->sa_family == AF_PACKET)&&(len == 18))
{
/* FIXME. This needs tested */
struct sockaddr_ll *sll = (struct sockaddr_ll *)buf;
@@ -351,11 +346,17 @@ void _stp_sockaddr_str(char *str, const
(int)sll->sll_protocol, sll->sll_ifindex, (int)sll->sll_hatype, (int)sll->sll_pkttype,
(int)sll->sll_halen, *(uint64_t *)sll->sll_addr);
#endif
- break;
}
-
- default:
- snprintf(str, strlen, "{unknown address family %d}", sa->sa_family);
+ else
+ {
+ if (len >= 2)
+ {
+ snprintf(str, strlen, "{unknown sockaddr with sa=%d, salen=%d}", sa->sa_family, len);
+ }
+ else
+ {
+ snprintf(str, strlen, "{unknown sockaddr with salen=%d}", len);
+ }
}
}
%}
Regards
Zhaolei