Skip to content

Commit b5c91f2

Browse files
committed
Generate random MAC addresses for soft MACs
1 parent d3873ea commit b5c91f2

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

lib/firewall/firewall.cc

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <debug.hh>
88
//#include <fail-simulator-on-error.h>
99
#include <locks.hh>
10+
#include <platform-entropy.hh>
1011
#include <platform-ethernet.hh>
1112
#include <timeout.h>
1213
#include <timeout.hh>
@@ -93,6 +94,44 @@ namespace
9394
*/
9495
using MACAddress = std::array<uint8_t, 6>;
9596

97+
/**
98+
* Returns the MAC address for the network interface.
99+
*/
100+
MACAddress &mac_address()
101+
{
102+
static MACAddress macAddress = []() {
103+
auto &ethernet = lazy_network_interface();
104+
if constexpr (EthernetDevice::has_unique_mac_address())
105+
{
106+
return ethernet.mac_address_default();
107+
}
108+
else
109+
{
110+
std::array<uint8_t, 6> macAddress;
111+
EntropySource entropy;
112+
for (auto &byte : macAddress)
113+
{
114+
byte = entropy();
115+
}
116+
// Set the local bit (second bit transmitted from first byte) to
117+
// 1 to indicate a locally administered MAC
118+
macAddress[0] |= 0b01;
119+
// Make sure that the broadcast bit is 0
120+
macAddress[0] &= ~0b1;
121+
ConditionalDebug<true, "Firewall">::log(
122+
"MAC address: {}:{}:{}:{}:{}:{}",
123+
macAddress[0],
124+
macAddress[1],
125+
macAddress[2],
126+
macAddress[3],
127+
macAddress[4],
128+
macAddress[5]);
129+
return macAddress;
130+
}
131+
}();
132+
return macAddress;
133+
}
134+
96135
/**
97136
* Ethernet header.
98137
*/
@@ -506,6 +545,7 @@ namespace
506545

507546
bool packet_filter_ingress(const uint8_t *data, size_t length)
508547
{
548+
static constinit MACAddress broadcastMAC = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
509549
// Not a valid Ethernet frame (64 bytes including four-byte FCS, which
510550
// is stripped by this point).
511551
if (length < 60)
@@ -515,6 +555,19 @@ namespace
515555
}
516556
EthernetHeader *ethernetHeader =
517557
reinterpret_cast<EthernetHeader *>(const_cast<uint8_t *>(data));
558+
if ((ethernetHeader->destination != mac_address()) &&
559+
(ethernetHeader->destination != broadcastMAC))
560+
{
561+
ConditionalDebug<true, "Firewall">::log(
562+
"Dropping frame with destination MAC address {}:{}:{}:{}:{}:{}",
563+
ethernetHeader->destination[0],
564+
ethernetHeader->destination[1],
565+
ethernetHeader->destination[2],
566+
ethernetHeader->destination[3],
567+
ethernetHeader->destination[4],
568+
ethernetHeader->destination[5]);
569+
return false;
570+
}
518571
switch (ethernetHeader->etherType)
519572
{
520573
#ifdef ENABLE_IPV6
@@ -557,7 +610,9 @@ bool ethernet_driver_start()
557610
}
558611
Debug::log("Initialising network interface");
559612
auto &ethernet = lazy_network_interface();
560-
ethernet.mac_address_set();
613+
// If the device has a unique MAC address, use it. Otherwise, generate a
614+
// random locally administered one.
615+
ethernet.mac_address_set(mac_address());
561616
// Poke the barrier and make the driver thread start.
562617
barrier = 2;
563618
barrier.notify_one();
@@ -768,3 +823,11 @@ void firewall_remove_udpipv6_remote_endpoint(uint8_t *remoteAddress,
768823
}
769824

770825
#endif
826+
827+
uint8_t *firewall_mac_address_get()
828+
{
829+
CHERI::Capability ret{mac_address().data()};
830+
ret.permissions() &= {CHERI::Permission::Load, CHERI::Permission::Global};
831+
ret.bounds() = 6;
832+
return ret;
833+
}

lib/firewall/firewall.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,10 @@ void __cheri_compartment("Firewall")
151151
firewall_remove_udpipv6_remote_endpoint(uint8_t *remoteAddress,
152152
uint16_t localPort,
153153
uint16_t remotePort);
154+
155+
/**
156+
* Get the MAC address of the ethernet device.
157+
*
158+
* Returns a read-only capability to the MAC address.
159+
*/
160+
uint8_t *__cheri_compartment("Firewall") firewall_mac_address_get();

lib/tcpip/startup.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void __cheri_compartment("TCPIP") network_start()
9090
NetMask,
9191
GatewayAddress,
9292
DNSServerAddress,
93-
KunyanEthernet::mac_address_default().data());
93+
firewall_mac_address_get());
9494
// Enable DHCP
9595
endpointIPv4.bits.bWantDHCP = pdTRUE;
9696

0 commit comments

Comments
 (0)