kern/91307: Spoil struct ifnet content in fwip initializing

Alex Semenyaka alex at semenyaka.ru
Wed Jan 4 05:50:05 PST 2006


>Number:         91307
>Category:       kern
>Synopsis:       Spoil  struct ifnet  content in fwip initializing
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jan 04 13:50:02 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Alex Semenyaka
>Release:        FreeBSD 4.10-STABLE i386
>Organization:
private
>Environment:
System: FreeBSD snark.rinet.ru 6.0-STABLE FreeBSD 6.0-STABLE #0: Sat Nov 26 21:44:43 MSK 2005     root at snark.rinet.ru:/usr/obj/usr/src/sys/SNARK  amd64

>Description:

During the initializing of fwip interface structure fw_com should be
filled up with the proper values. The reference to that structure is kept in
the structure ifnet. Unfortunatelly in the if_fwsubr.c instead of taking
the reference to struct fw_com, the struct ifnet itself is used (with the
proper type reduction though). To do it the macro IFP2FC() is used (instead
of right macro IFP2FWC()). The IFP2FWC is defined globally (while IFP2FC
is defined only in if_fwsubr.c, where it is used).

On the i386 boxes the problem hides since the overwriten memory is not
used in the output. But on amd64 box (due to different size of structures
fields) the interface name becomes overwritten, so from 'fwip0' it changes to
'f^@ip0' (here ^@ is the character NUL) - couple of lines go with the name
'fwip0' while then name becomes 'f^@ip0'.

But since illegal operation does occur on i386 boxes as well it may be
a cause of different unclear problems.

>How-To-Repeat:

1) Install FreeBSD on amd64 box.
2) Load fwip as the kernel module (or put it into the kernel config,
recompile kernel and reboot)
3) Observe broken interface name in the kernel output to console.

>Fix:

Apply the patch below


--- if_fwsubr.c.orig	Sun Nov 27 14:52:01 2005
+++ if_fwsubr.c	Sun Nov 27 15:45:15 2005
@@ -62,8 +62,6 @@
 #include <netinet6/nd6.h>
 #endif
 
-#define IFP2FC(IFP) ((struct fw_com *)IFP)
-
 MALLOC_DEFINE(M_FWCOM, "fw_com", "firewire interface internals");
 
 struct fw_hwaddr firewire_broadcastaddr = {
@@ -79,7 +77,7 @@
 firewire_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst,
     struct rtentry *rt0)
 {
-	struct fw_com *fc = IFP2FC(ifp);
+	struct fw_com *fc = IFP2FWC(ifp);
 	int error, type;
 	struct rtentry *rt = NULL;
 	struct m_tag *mtag;
@@ -499,7 +497,7 @@
 void
 firewire_input(struct ifnet *ifp, struct mbuf *m, uint16_t src)
 {
-	struct fw_com *fc = IFP2FC(ifp);
+	struct fw_com *fc = IFP2FWC(ifp);
 	union fw_encap *enc;
 	int type, isr;
 
@@ -667,7 +665,7 @@
 			struct sockaddr *sa;
 
 			sa = (struct sockaddr *) & ifr->ifr_data;
-			bcopy(&IFP2FC(ifp)->fc_hwaddr,
+			bcopy(&IFP2FWC(ifp)->fc_hwaddr,
 			    (caddr_t) sa->sa_data, sizeof(struct fw_hwaddr));
 		}
 		break;
@@ -747,7 +745,7 @@
 void
 firewire_ifattach(struct ifnet *ifp, struct fw_hwaddr *llc)
 {
-	struct fw_com *fc = IFP2FC(ifp);
+	struct fw_com *fc = IFP2FWC(ifp);
 	struct ifaddr *ifa;
 	struct sockaddr_dl *sdl;
 	static const char* speeds[] = {
@@ -794,7 +792,7 @@
 void
 firewire_busreset(struct ifnet *ifp)
 {
-	struct fw_com *fc = IFP2FC(ifp);
+	struct fw_com *fc = IFP2FWC(ifp);
 	struct fw_reass *r;
 	struct mbuf *m;
 

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


More information about the freebsd-bugs mailing list