* @brief Accepts a connection on a socket. * * This system call is used to accept a pending connection request on a socket. It extracts the * first connection request from the incoming queue, creates a new socket for the connection, * and stores the address information of the remote peer in the provided address structure. * The original socket must be a listening socket that has been previous
| 5090 | * to buffer overflows or undefined behavior. |
| 5091 | */ |
| 5092 | sysret_t sys_accept(int socket, struct musl_sockaddr *addr, socklen_t *addrlen) |
| 5093 | { |
| 5094 | int ret = -1; |
| 5095 | struct sockaddr ksa; |
| 5096 | struct musl_sockaddr kmusladdr; |
| 5097 | socklen_t uaddrlen; |
| 5098 | socklen_t kaddrlen; |
| 5099 | |
| 5100 | if (addr) |
| 5101 | { |
| 5102 | if (!lwp_user_accessable(addrlen, sizeof(socklen_t))) |
| 5103 | { |
| 5104 | return -EFAULT; |
| 5105 | } |
| 5106 | lwp_get_from_user(&uaddrlen, addrlen, sizeof(socklen_t)); |
| 5107 | if (!uaddrlen) |
| 5108 | { |
| 5109 | return -EINVAL; |
| 5110 | } |
| 5111 | |
| 5112 | if (!lwp_user_accessable(addr, uaddrlen)) |
| 5113 | { |
| 5114 | return -EFAULT; |
| 5115 | } |
| 5116 | } |
| 5117 | |
| 5118 | kaddrlen = sizeof(struct sockaddr); |
| 5119 | ret = accept(socket, &ksa, &kaddrlen); |
| 5120 | if (ret >= 0) |
| 5121 | { |
| 5122 | if (addr) |
| 5123 | { |
| 5124 | sockaddr_tomusl(&ksa, &kmusladdr); |
| 5125 | if (uaddrlen > sizeof(struct musl_sockaddr)) |
| 5126 | { |
| 5127 | uaddrlen = sizeof(struct musl_sockaddr); |
| 5128 | } |
| 5129 | lwp_put_to_user(addr, &kmusladdr, uaddrlen); |
| 5130 | lwp_put_to_user(addrlen, &uaddrlen, sizeof(socklen_t)); |
| 5131 | } |
| 5132 | } |
| 5133 | return ret; |
| 5134 | } |
| 5135 | |
| 5136 | /** |
| 5137 | * @brief Binds a socket to a local address. |
nothing calls this directly
no test coverage detected