This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] For memory access error when calling _stp_sockaddr_str with addrlen set to 0


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]