Skip to content

Commit 4465377

Browse files
bzbarsky-applepull[bot]
authored andcommitted
Fix alignment problem when casting struct sockaddr pointers to SockAddr. (#26488)
* Fix alignment problem when casting struct sockaddr pointers to SockAddr. SockAddr, because it includes sockaddr_storage, has a more stringent alignment requirement than struct sockaddr does. As a result, the casting we do of "sockaddr &" to "SockAddr &" is not really OK. The fix is to have a version of SockAddr that lets us do the type-punning we want to do without including sockaddr_storage. We don't need storage in this case because we are working with an existing sockaddr that lives somewhere, not storing one of our own. This also lets us enable UndefinedBehaviorSanitizer for libCHIP in the Darwin framework tests. * Fix typo in comment.
1 parent 630902e commit 4465377

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

.github/workflows/darwin.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ jobs:
145145
# And a different port from the test harness too; the test harness uses port 5541.
146146
../../../out/debug/chip-ota-requestor-app --interface-id -1 --secured-device-port 5542 --discriminator 1111 --KVS /tmp/chip-ota-requestor-kvs1 --otaDownloadPath /tmp/chip-ota-requestor-downloaded-image1 --autoApplyImage > >(tee /tmp/darwin/framework-tests/ota-requestor-app-1.log) 2> >(tee /tmp/darwin/framework-tests/ota-requestor-app-err-1.log >&2) &
147147
../../../out/debug/chip-ota-requestor-app --interface-id -1 --secured-device-port 5543 --discriminator 1112 --KVS /tmp/chip-ota-requestor-kvs2 --otaDownloadPath /tmp/chip-ota-requestor-downloaded-image2 --autoApplyImage > >(tee /tmp/darwin/framework-tests/ota-requestor-app-2.log) 2> >(tee /tmp/darwin/framework-tests/ota-requestor-app-err-2.log >&2) &
148-
xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-incomplete-umbrella -Wno-unguarded-availability-new' > >(tee /tmp/darwin/framework-tests/darwin-tests.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-err.log >&2)
148+
# UndefinedBehaviorSanitizer is enabled in the Xcode scheme, so the code in Matter.framework gets instrumented,
149+
# but to instrument the code in the underlying libCHIP we need to pass CHIP_IS_UBSAN=YES
150+
xcodebuild test -target "Matter" -scheme "Matter Framework Tests" -sdk macosx OTHER_CFLAGS='${inherited} -Werror -Wconversion -Wno-incomplete-umbrella -Wno-unguarded-availability-new' CHIP_IS_UBSAN=YES > >(tee /tmp/darwin/framework-tests/darwin-tests.log) 2> >(tee /tmp/darwin/framework-tests/darwin-tests-err.log >&2)
149151
working-directory: src/darwin/Framework
150152
- name: Uploading log files
151153
uses: actions/upload-artifact@v3

src/inet/IPAddress.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ struct in6_addr IPAddress::ToIPv6() const
237237
return ipAddr;
238238
}
239239

240-
CHIP_ERROR IPAddress::GetIPAddressFromSockAddr(const SockAddr & sockaddr, IPAddress & outIPAddress)
240+
CHIP_ERROR IPAddress::GetIPAddressFromSockAddr(const SockAddrWithoutStorage & sockaddr, IPAddress & outIPAddress)
241241
{
242242
#if INET_CONFIG_ENABLE_IPV4
243243
if (sockaddr.any.sa_family == AF_INET)

src/inet/IPAddress.h

+23-2
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,34 @@ enum class IPv6MulticastFlag : uint8_t
107107
using IPv6MulticastFlags = BitFlags<IPv6MulticastFlag>;
108108

109109
#if CHIP_SYSTEM_CONFIG_USE_SOCKETS
110+
/**
111+
* SockAddr should be used when calling any API that returns (by copying into
112+
* it) a sockaddr, because that will need enough storage that it can hold data
113+
* for any socket type.
114+
*
115+
* It can also be used when calling an API that accepts a sockaddr, to simplify
116+
* the type-punning needed.
117+
*/
110118
union SockAddr
111119
{
112120
sockaddr any;
113121
sockaddr_in in;
114122
sockaddr_in6 in6;
115123
sockaddr_storage storage;
116124
};
125+
126+
/**
127+
* SockAddrWithoutStorage can be used any time we want to do the sockaddr
128+
* type-punning but will not store the data ourselves (e.g. we're working with
129+
* an existing sockaddr pointer, and reintepret it as a
130+
* pointer-to-SockAddrWithoutStorage).
131+
*/
132+
union SockAddrWithoutStorage
133+
{
134+
sockaddr any;
135+
sockaddr_in in;
136+
sockaddr_in6 in6;
137+
};
117138
#endif // CHIP_SYSTEM_CONFIG_USE_SOCKETS
118139

119140
/**
@@ -550,10 +571,10 @@ class DLL_EXPORT IPAddress
550571
/**
551572
* Get the IP address from a SockAddr.
552573
*/
553-
static CHIP_ERROR GetIPAddressFromSockAddr(const SockAddr & sockaddr, IPAddress & outIPAddress);
574+
static CHIP_ERROR GetIPAddressFromSockAddr(const SockAddrWithoutStorage & sockaddr, IPAddress & outIPAddress);
554575
static CHIP_ERROR GetIPAddressFromSockAddr(const sockaddr & sockaddr, IPAddress & outIPAddress)
555576
{
556-
return GetIPAddressFromSockAddr(reinterpret_cast<const SockAddr &>(sockaddr), outIPAddress);
577+
return GetIPAddressFromSockAddr(reinterpret_cast<const SockAddrWithoutStorage &>(sockaddr), outIPAddress);
557578
}
558579
static IPAddress FromSockAddr(const sockaddr_in6 & sockaddr) { return IPAddress(sockaddr.sin6_addr); }
559580
#if INET_CONFIG_ENABLE_IPV4

0 commit comments

Comments
 (0)