Issue Information
-
#000765
-
1 - Low
-
Confirmed
Issue Confirmations
-
Yes (0)No (0)
0
Network Interface Detection Code Bugs On Freebsd
Posted by Hercules Bot on 07 January 2008 - 10:21 PM
Originally posted by theultramage
http://www.eathena.w...ker&showbug=765
A long time ago, I reported that the code that executes at startup - to enumerate the machine's network interfaces - reads random junk instead of what it should.
I investigated that in detail yesterday. And came up with this.
Memory dump reveals the following:
Problem: the eathena code assumes that the individual ifreq structures have the same size and can be iterated over like an array.
On FreeBSD, they have variable-size (but use a dummy sockaddr structure) and are packed together. Thus you need to process one to know where the next begins. Not sure if this is standardized behavior... looks more like kernel-specific stuff. I'd use the Windows approach myself (gethostname + gethostbyname)...
PS: the valgrind 'uninitialized memory' error message goes away if you memset() the buffer first.
http://www.eathena.w...ker&showbug=765
A long time ago, I reported that the code that executes at startup - to enumerate the machine's network interfaces - reads random junk instead of what it should.
I investigated that in detail yesterday. And came up with this.
CODE
==1915== Conditional jump or move depends on uninitialised value(s)
==1915== at 0x8056D1E: socket_getips (socket.c:1180)
==1915== by 0x8056D91: socket_init (socket.c:1225)
==1915== by 0x805523C: main (core.c:244)
==1915== at 0x8056D1E: socket_getips (socket.c:1180)
==1915== by 0x8056D91: socket_init (socket.c:1225)
==1915== by 0x805523C: main (core.c:244)
Memory dump reveals the following:
CODE
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
38 (16 bytes)
12 (AF_LINK)
01 00 06 04 06 00 66 78 70 30 00 30 05 08 5B 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 01 00 00 00 00 02 30 05 FF FE 08 5B 60 00 00 00 00
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 C0 A8 00 01 00 00 00 00 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
38 (16 bytes)
12 (AF_LINK)
02 00 06 03 06 00 72 6C 30 00 E0 4C C4 31 93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 02 00 00 00 00 02 E0 4C FF FE C4 31 93 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 0A 14 06 1E 00 00 00 00 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
38 (16 bytes)
12 (AF_LINK)
03 00 18 03 00 00 6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 03 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 7F 00 00 01 00 00 00 00 00 00 00 00
struct ifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags[2];
short ifru_index;
int ifru_metric;
int ifru_mtu;
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int ifru_cap[2];
} ifr_ifru;
struct sockaddr {
unsigned char sa_len; /* total length */
sa_family_t sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
38 (16 bytes)
12 (AF_LINK)
01 00 06 04 06 00 66 78 70 30 00 30 05 08 5B 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 01 00 00 00 00 02 30 05 FF FE 08 5B 60 00 00 00 00
66 78 70 30 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 C0 A8 00 01 00 00 00 00 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
38 (16 bytes)
12 (AF_LINK)
02 00 06 03 06 00 72 6C 30 00 E0 4C C4 31 93 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 02 00 00 00 00 02 E0 4C FF FE C4 31 93 00 00 00 00
72 6C 30 00 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 0A 14 06 1E 00 00 00 00 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
38 (16 bytes)
12 (AF_LINK)
03 00 18 03 00 00 6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
1C (28 bytes)
1C (AF_INET6)
00 00 00 00 00 00 FE 80 00 03 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00
6C 6F 30 00 00 00 00 00 00 00 00 00 00 00 00 00
10 (16 bytes)
02 (AF_INET)
00 00 7F 00 00 01 00 00 00 00 00 00 00 00
struct ifreq {
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
union {
struct sockaddr ifru_addr;
struct sockaddr ifru_dstaddr;
struct sockaddr ifru_broadaddr;
short ifru_flags[2];
short ifru_index;
int ifru_metric;
int ifru_mtu;
int ifru_phys;
int ifru_media;
caddr_t ifru_data;
int ifru_cap[2];
} ifr_ifru;
struct sockaddr {
unsigned char sa_len; /* total length */
sa_family_t sa_family; /* address family */
char sa_data[14]; /* actually longer; address value */
};
Problem: the eathena code assumes that the individual ifreq structures have the same size and can be iterated over like an array.
On FreeBSD, they have variable-size (but use a dummy sockaddr structure) and are packed together. Thus you need to process one to know where the next begins. Not sure if this is standardized behavior... looks more like kernel-specific stuff. I'd use the Windows approach myself (gethostname + gethostbyname)...
PS: the valgrind 'uninitialized memory' error message goes away if you memset() the buffer first.