Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 3 Aug 2010 15:02:12 GMT
From:      Stef Walter <stef@memberwebs.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/149240: struct ifm_data.ifi_datalen set to invalid value on 32-bit access to 64-bit kernel
Message-ID:  <201008031502.o73F2CL6016830@www.freebsd.org>
Resent-Message-ID: <201008031510.o73FA3UI016294@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         149240
>Category:       kern
>Synopsis:       struct ifm_data.ifi_datalen set to invalid value on 32-bit access to 64-bit kernel
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 03 15:10:03 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Stef Walter
>Release:        FreeBSD 8.1
>Organization:
>Environment:
FreeBSD a2.ams.npubs.net 8.1-RELEASE FreeBSD 8.1-RELEASE #4: Tue Aug  3 14:31:11 UTC 2010     root@a2.ams.npubs.net:/usr/obj/usr/src/sys/RACK2  amd64
>Description:
The FreeBSD 32 compatibility layer sets the struct ifm_data.ifi_datalen member to the wrong value. ifi_datalen is supposed to contain the size of the ifm_data struct. The FreeBSD 32 compatibility code sets this to the sime of the 64-bit struct ifi_data rather than the 32-bit one.

This casues 32-bit applications using the sysctl() or PF_ROUTE style interfaces to access invalid memory, produce invalid results, and in many cases crash.
>How-To-Repeat:
/* Will produce invalid interface names when run as a 32-bit program on 64-bit */
/* gcc -o test_iflist test_iflist.c */

#include <sys/types.h>
#include <sys/sysctl.h>
#include <sys/socket.h>

#include <net/if.h>
#include <net/if_dl.h>
#include <net/route.h>

#include <string.h>

int
main (void)
{
	char buffer[1024 * 64];
	char name[IFNAMSIZ];
	char *buf, *lim, *next;
	int mib[6];
	size_t length;
	struct if_msghdr *ifm, *nextifm;
	struct ifa_msghdr *ifam;
	struct sockaddr_dl *sdl;
	int addrcount;
	
	mib[0] = CTL_NET;
	mib[1] = PF_ROUTE;
	mib[2] = 0;
	mib[3] = 0;                     /* address family */
	mib[4] = NET_RT_IFLIST;
	mib[5] = 0;

	length = sizeof (buffer);
	if (sysctl (mib, 6, buffer, &length, NULL, 0) < 0)
		err (1, "sysctl failed");

	buf = next = buffer;
	lim = buf + length;

	while (next < lim) {
		ifm = (struct if_msghdr*)next;
		if (ifm->ifm_type != RTM_IFINFO)
			errx (1, "invalid ifm_type");

		if (ifm->ifm_data.ifi_datalen == 0)
			ifm->ifm_data.ifi_datalen = sizeof(struct if_data);
		sdl = (struct sockaddr_dl *)((char *)ifm + 
			sizeof(struct if_msghdr) -
			sizeof(struct if_data) +
			ifm->ifm_data.ifi_datalen);


		if (sdl->sdl_nlen >= sizeof (name))
			err (1, "name too long");
		strncpy (name, sdl->sdl_data, sdl->sdl_nlen);
		
		next += ifm->ifm_msglen;
		warnx ("interface %d %s", ifm->ifm_index, name);	

                ifam = NULL;
                addrcount = 0;
                while (next < lim) {
                        nextifm = (struct if_msghdr*)next;
                
                        if (nextifm->ifm_type != RTM_NEWADDR)
                                break;
                
                        if (ifam == NULL)
                                ifam = (struct ifa_msghdr *)nextifm;
 
                        addrcount++;
                        next += nextifm->ifm_msglen;
                }
	}

	return 0;
}
>Fix:
Patch attached

Patch attached with submission follows:

--- ./sys/net/rtsock.c.orig	2010-08-03 14:19:14.000000000 +0000
+++ ./sys/net/rtsock.c	2010-08-03 14:20:54.000000000 +0000
@@ -1440,5 +1440,5 @@ copy_ifdata32(struct if_data *src, struc
 	CP(*src, *dst, ifi_hdrlen);
 	CP(*src, *dst, ifi_link_state);
-	CP(*src, *dst, ifi_datalen);
+	dst->ifi_datalen = sizeof(struct if_data32);
 	CP(*src, *dst, ifi_mtu);
 	CP(*src, *dst, ifi_metric);


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008031502.o73F2CL6016830>