Hi,

after the latest change in ppp(8)/iface.c ppp(8) will loop endlessly if
there's an interface with ifm_version != RTM_VERSION. The pointer to the
if_msghdr structure doesn't point to the next element when continue is
executed.

In addition the inner loop checks the ifm_version a second time,
although that loop iterates over ifa_msghdr structures. That doesn't
make sense to me.

I attached a patch that solved the problem for me (amd64/GENERIC.MP).

Regards,

Oliver Klima
--- usr.sbin/ppp/ppp/iface.c.orig       Sat Jun 27 20:41:25 2009
+++ usr.sbin/ppp/ppp/iface.c    Sun Jun 28 13:46:54 2009
@@ -140,23 +140,23 @@
 
   while (ptr < end && iface == NULL) {
     ifm = (struct if_msghdr *)ptr;                     /* On if_msghdr */
-    if (ifm->ifm_version != RTM_VERSION)
-      continue;
-    if (ifm->ifm_type != RTM_IFINFO)
-      break;
-    dl = (struct sockaddr_dl *)(ifm + 1);              /* Single _dl at end */
-    if (dl->sdl_nlen == namelen && !strncmp(name, dl->sdl_data, namelen)) {
-      iface = (struct iface *)malloc(sizeof *iface);
-      if (iface == NULL) {
-        fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno));
-        return NULL;
-      }
-      iface->name = strdup(name);
-      iface->index = ifm->ifm_index;
-      iface->flags = ifm->ifm_flags;
-      iface->mtu = 0;
-      iface->addrs = 0;
-      iface->addr = NULL;
+    if (ifm->ifm_version == RTM_VERSION) {
+           if (ifm->ifm_type != RTM_IFINFO)
+             break;
+           dl = (struct sockaddr_dl *)(ifm + 1);               /* Single _dl 
at end */
+           if (dl->sdl_nlen == namelen && !strncmp(name, dl->sdl_data, 
namelen)) {
+             iface = (struct iface *)malloc(sizeof *iface);
+             if (iface == NULL) {
+               fprintf(stderr, "iface_Create: malloc: %s\n", strerror(errno));
+               return NULL;
+             }
+             iface->name = strdup(name);
+             iface->index = ifm->ifm_index;
+             iface->flags = ifm->ifm_flags;
+             iface->mtu = 0;
+             iface->addrs = 0;
+             iface->addr = NULL;
+           }
     }
     ptr += ifm->ifm_msglen;                            /* First ifa_msghdr */
     for (; ptr < end; ptr += ifam->ifam_msglen) {
@@ -164,7 +164,7 @@
 
       if (ifam->ifam_type != RTM_NEWADDR)              /* finished this if */
         break;
-      if (ifm->ifm_version != RTM_VERSION)
+      if (ifam->ifam_version != RTM_VERSION)
         continue;
 
       if (iface != NULL && ifam->ifam_addrs & RTA_IFA) {

Reply via email to