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

UB in dns.cc / socket_address sock_addr(const sockaddr * addr, socklen_t len) #2288

Open
VzdornovNA88 opened this issue Jun 7, 2024 · 0 comments

Comments

@VzdornovNA88
Copy link

This is about undefined behavior on type punning case using reinterpret_cast, it generally violates lifetime and aliassing rules and probably alignment

return *in;

https://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_accessibility
5) Any object pointer type T1* can be converted to another object pointer type cv T2*. This is exactly equivalent to static_cast<cv T2*>(static_cast<cv void*>(expression)) (which implies that if T2's alignment requirement is not stricter than T1's, the value of the pointer does not change and conversion of the resulting pointer back to its original type yields the original value). In any case, the resulting pointer may only be dereferenced safely if the dereferenced value is type-accessible.

If a type T_ref is similar to any of the following types, an object of dynamic type T_obj is type-accessible through a lvalue(until C++11)glvalue(since C++11) of type T_ref

  • char
  • unsigned char
std::byte (since C++17)
  • T_obj
  • the signed or unsigned type corresponding to T_obj

If a program attempts to read or modify the stored value of an object through a lvalue(until C++11)glvalue(since C++11) through which it is not type-accessible, the behavior is undefined.


socket_address sock_addr(const sockaddr * addr, socklen_t len)
 {
        if (addr->sa_family != AF_INET) {
            throw std::invalid_argument("No ipv6 yet");
        }
        auto in = reinterpret_cast<const sockaddr_in *>(addr);
        return *in;
    }

/* Structure describing a generic socket address.  */
struct sockaddr
  {
    __SOCKADDR_COMMON (sa_);	/* Common data: address family and length.  */
    char sa_data[14];		/* Address data.  */
  };

struct sockaddr_in
  {
    __SOCKADDR_COMMON (sin_);
    in_port_t sin_port;			/* Port number.  */
    struct in_addr sin_addr;		/* Internet address.  */

    /* Pad to size of `struct sockaddr'.  */
    unsigned char sin_zero[sizeof (struct sockaddr) - __SOCKADDR_COMMON_SIZE - sizeof (in_port_t) - sizeof (struct in_addr)];
  };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant