Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 24 additions & 3 deletions groups/nts/ntsu/ntsu_socketutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -937,27 +937,48 @@ ntsa::Error SocketUtil::Impl::convert(ntsa::Endpoint* endpoint,
const bsl::size_t pathOffset =
offsetof(struct sockaddr_un, sun_path);

if (socketAddressSize == pathOffset) {
const bsl::size_t addressSize =
static_cast<bsl::size_t>(socketAddressSize);

if (addressSize <= pathOffset) {
localName->setUnnamed();
}
else {
// The address length reported by the socket API is the
// authoritative extent of 'sun_path': the field is not
// guaranteed to be null-terminated (abstract names never are,
// and a peer may supply a truncated or unterminated path).
// Bound the scan by that length, clamped to the capacity of
// the field itself, so the scan never reads bytes outside the
// address.

bsl::size_t pathSize = addressSize - pathOffset;
if (pathSize > sizeof(socketAddressLocal->sun_path)) {
pathSize = sizeof(socketAddressLocal->sun_path);
}

const char* begin = socketAddressLocal->sun_path;
const char* limit = begin + pathSize;

if (*begin == 0) {
localName->setAbstract();
++begin;
}

const char* end = begin;
while (*end != 0) {
while (end != limit && *end != 0) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For abstract addresses, unix(7) says all sun_path bytes covered by the address length are part of the name; embedded NULs have no special significance. Do not stop at the first NUL.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaving the exsisting decoding logic that stops at the first NUL as-is. See my rationalization in my PR comments.

++end;
}

if (begin == end) {
localName->setUnnamed();
}
else {
localName->setValue(bslstl::StringRef(begin, end));
ntsa::Error error =
localName->setValue(bslstl::StringRef(begin, end));
if (error) {
return error;
}
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion groups/nts/ntsu/ntsu_socketutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,11 @@ struct SocketUtil {

/// Load into the specified 'endpoint' the conversion of the specified
/// 'socketAddress' having the specified 'socketAddressSize'. Return the
/// error.
/// error. Note a 'socketAddress' indicating a Unix domain name with an
/// embedded NUL is successfully decoded but the resulting 'endpoint' local
/// name only contains characters up to the first NUL character, not
/// including the initital NUL character, if any, that indicates the Unix
/// domain name is in the abstract namespace.
static ntsa::Error decodeEndpoint(ntsa::Endpoint* endpoint,
const void* socketAddress,
bsl::size_t socketAddressSize);
Expand Down
Loading
Loading