Jump to content

  •  

Bug Tracker Migration

June 3rd
Good news everyone! The staff has decided that it is time to slowly kill off this Bug Tracker. We will begin the process of slowly migrating from this Bug Tracker over to our Github Issues which can be found here: https://github.com/HerculesWS/Hercules/issues

Over the next couple of days, I will be closing off any opportunity to create new reports. However, I still will keep the opportunity to reply to existing Bug Reports. Doing this will allow us to slowly fix any bug reports we have listed here so that we can easily migrate over to our Issue Tracker.

Update - June 7th 2015: Creating new bug posts has been disabled. Please use our https://github.com/HerculesWS/Hercules/issues tracker to post bugs. Users are still able to reply to existing bug posts.

- Administration

Issue Information

  • #000765

  • 1 - Low

  • Confirmed

Issue Confirmations

  • Yes (0)No (0)
Photo

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.
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)

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 */
};


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.