Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

destiny: memcpying with the wrong length #1266

Closed
wants to merge 1 commit into from

Conversation

cgundogan
Copy link
Member

when calling posix bind, the user will probably pass a
struct sockaddr_in6 and its corresponding sizeof() return value.
However, in further steps this struct is cast to a sockaddr6_t.
This cast by itself is not dangerous, since the former struct
encapsulates the sockaddr6_t plus an additional field.
But in later steps, memcpy is used with the former sizeof() value,
which was passed to the posix bind call.

Due to different sizes of struct sockaddr_in6 and sockaddr6_t,
the port value of the foreign address field gets overwritten.
But TCP expects the foreign address to be completely zero
in order to handle further connections with this socket.

@Kijewski
Copy link
Contributor

Kijewski commented Jun 3, 2014

Wouldn't a simple copy be enough?

    get_socket(s)->socket_values.local_address = *name; // ← no memcpy here
    get_socket(s)->socket_values.tcp_control.rto = TCP_INITIAL_ACK_TIMEOUT;
    get_socket(s)->recv_pid = pid;

And caching the result of get_socket() like socket_internal_t *sock = get_socket(s) would be good, too, I guess.

struct sockaddr_in6 and its corresponding sizeof() return value.
However, in further steps this struct is cast to a sockaddr6_t.
This cast by itself is not dangerous, since the former struct
encapsulates the sockaddr6_t plus an additional field.
But in later steps, memcpy is used with the former sizeof() value,
which was passed to the posix bind call.

Due to different sizes of struct sockaddr_in6 and sockaddr6_t,
the port value of the foreign address field gets overwritten.
But TCP expects the foreign address to be completely zero
in order to handle further connections with this socket.

destiny: simple copy and caching the struct.
A simple copy suffices here. In addition the socket is cached to serve multiple assignments.
@cgundogan
Copy link
Member Author

I changed the PR to include a simple copy and caching the struct for multiple uses

@Kijewski Kijewski added this to the Release NEXT MAJOR milestone Jun 3, 2014
@Kijewski
Copy link
Contributor

Kijewski commented Jun 3, 2014

But TCP expects the foreign address to be completely zero
in order to handle further connections with this socket.

Could you please elaborate on this sentence a little bit more. I did not look further into the implementation, and I don't really see the problem. I.e. why do these bits need to be zero?

@cgundogan
Copy link
Member Author

the implementation in destiny iterates through the socket list (in a later step) in order to find an adequate socket for the incoming connection establishment. However, if the foreign_address part of that socket is not NULL, the proper socket is just ignored. (sockets in a listening state have no foreign_address)

The current memcpy uses a copy length, which is bigger than sizeof(copy source). Thus,
the foreign_address, which follows immediatly the local_address within the struct, gets overwritten with corrupt data.

The current implementation was probably correct some time ago, because you would pass directly the sockaddr6_t and a valid length parameter based on that type.

But with the introduction of posix, and the needs to fulfill their API, the user needs to pass a struct sockaddr_in6, which is slightly bigger than the internal sockaddr6_t. But when memcpying, the size of sockaddr_in6 is used.

@@ -271,9 +273,9 @@ int bind_tcp_socket(int s, sockaddr6_t *name, int namelen, uint8_t pid)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

@cgundogan do you have any idea what this chunk of code is doing? seems to be some sort of assert check?!

@OlegHahm OlegHahm assigned miri64 and unassigned OlegHahm Jun 9, 2014
@OlegHahm
Copy link
Member

Will be part of #1508

@OlegHahm OlegHahm closed this Sep 11, 2014
@cgundogan cgundogan deleted the fix_socket_bind_memcpy branch February 2, 2015 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: network Area: Networking Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants