1
0
mirror of https://github.com/open-simh/simh.git synced 2026-02-22 23:38:22 +00:00

ETH_MAC indirection erratum

Pervasive misuse of "ETH_MAC *" (a pointer to an ETH_MAC, aka a 6
element unsigned char array) when a simple "ETH_MAC" is correct.  The
best example of this was eth_mac_fmt() in sim_ether.c with the following
prototype:

    t_stat eth_mac_fmt (ETH_MAC* const mac, char* strmac)

The first parameter is a pointer to an array of 6 unsigned characters,
whereas it really just wants to be a pointer to the first element of the
array:

    t_stat eth_mac_scan (const ETH_MAC mac, char* strmac)

The "ETH_MAC *" indirection error also results in subtle memcpy() and
memcmp() issues, e.g.:

    void network_func(DEVICE *dev, ETH_MAC *mac)
    {
      ETH_MAC other_mac;

      /* ...code... */

      /* memcpy() bug: */
      memcpy(other_mac, mac, sizeof(ETH_MAC));

      /* or worse: */
      memcpy(mac, other_mac, sizeof(ETH_MAC));
    }

eth_copy_mac() and eth_mac_cmp() replace calls to memcpy() and memcmp()
that copy or compare Ethernet MAC addresses. These are type-enforcing
functions, i.e., the parameters are ETH_MAC-s, to avoid the subtle
memcpy() and memcmp() bugs.

This fix solves at least one Heisenbug in _eth_close() while free()-ing
write request buffers (and possibly other Heisenbugs.)
This commit is contained in:
B. Scott Michel
2025-03-03 16:26:28 -08:00
committed by Paul Koning
parent 73e5df3928
commit c20b391eea
10 changed files with 256 additions and 225 deletions

View File

@@ -557,7 +557,7 @@ t_stat ni_setmac(UNIT *uptr, int32 val, CONST char* cptr, void* desc)
UNUSED(desc);
status = SCPE_OK;
status = eth_mac_scan_ex(&ni.macs[NI_NIC_MAC], cptr, uptr);
status = eth_mac_scan_ex(ni.macs[NI_NIC_MAC], cptr, uptr);
if (status == SCPE_OK) {
eth_filter(ni.eth, ni.filter_count, ni.macs, 0, 0);
@@ -577,7 +577,7 @@ t_stat ni_showmac(FILE* st, UNIT* uptr, int32 val, CONST void* desc)
UNUSED(val);
UNUSED(desc);
eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer);
eth_mac_fmt(ni.macs[NI_NIC_MAC], buffer);
fprintf(st, "MAC=%s", buffer);
return SCPE_OK;
}
@@ -591,12 +591,12 @@ t_stat ni_show_filters(FILE* st, UNIT* uptr, int32 val, CONST void* desc)
UNUSED(val);
UNUSED(desc);
eth_mac_fmt(&ni.macs[NI_NIC_MAC], buffer);
eth_mac_fmt(ni.macs[NI_NIC_MAC], buffer);
fprintf(st, "Physical Address=%s\n", buffer);
if (ni.filter_count > 0) {
fprintf(st, "Filters:\n");
for (i=0; i < ni.filter_count; i++) {
eth_mac_fmt((ETH_MAC *) ni.macs[i], buffer);
eth_mac_fmt(ni.macs[i], buffer);
fprintf(st, "[%2d]: %s\n", i, buffer);
}
fprintf(st, "\n");
@@ -948,7 +948,7 @@ t_stat ni_attach(UNIT *uptr, CONST char *cptr)
return status;
}
status = eth_check_address_conflict(ni.eth, &ni.macs[NI_NIC_MAC]);
status = eth_check_address_conflict(ni.eth, ni.macs[NI_NIC_MAC]);
if (status != SCPE_OK) {
sim_debug(DBG_ERR, &ni_dev, "ni_attach failure: mac check\n");
eth_close(ni.eth);