Skip to content

Commit 1b1762f

Browse files
Meziufincs
authored andcommitted
Return sockaddr_in length from functions that have in/out addrlen
Previously the socket funtions did not write the sockaddr_in struct fully and instead always returned the "internal" length, which did not account for the zeroed padding.
1 parent 04b9418 commit 1b1762f

File tree

4 files changed

+44
-17
lines changed

4 files changed

+44
-17
lines changed

libctru/source/services/soc/soc_accept.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,14 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
6161

6262
if(ret >= 0 && addr != NULL) {
6363
addr->sa_family = tmpaddr[1];
64-
if(*addrlen > tmpaddr[0])
65-
*addrlen = tmpaddr[0];
66-
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
64+
65+
socklen_t user_addrlen = tmpaddr[0];
66+
if(addr->sa_family == AF_INET)
67+
user_addrlen += 8; // Accounting for the 8 bytes of sin_zero padding, which must be written for compatibility.
68+
69+
if(*addrlen > user_addrlen)
70+
*addrlen = user_addrlen;
71+
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - sizeof(addr->sa_family));
6772
}
6873

6974
if(ret < 0) {

libctru/source/services/soc/soc_getpeername.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
1616
return -1;
1717
}
1818

19+
memset(tmpaddr, 0, ADDR_STORAGE_LEN);
20+
1921
cmdbuf[0] = IPC_MakeHeader(0x18,2,2); // 0x180082
2022
cmdbuf[1] = (u32)sockfd;
2123
cmdbuf[2] = ADDR_STORAGE_LEN;
@@ -47,11 +49,15 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
4749
return -1;
4850
}
4951

50-
if(*addrlen > tmpaddr[0])
51-
*addrlen = tmpaddr[0];
52-
memset(addr, 0, sizeof(struct sockaddr));
5352
addr->sa_family = tmpaddr[1];
54-
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
53+
54+
socklen_t user_addrlen = tmpaddr[0];
55+
if(addr->sa_family == AF_INET)
56+
user_addrlen += 8;
57+
58+
if(*addrlen > user_addrlen)
59+
*addrlen = user_addrlen;
60+
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - sizeof(addr->sa_family));
5561

5662
return ret;
5763
}

libctru/source/services/soc/soc_getsockname.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
1616
return -1;
1717
}
1818

19+
memset(tmpaddr, 0, ADDR_STORAGE_LEN);
20+
1921
cmdbuf[0] = IPC_MakeHeader(0x17,2,2); // 0x170082
2022
cmdbuf[1] = (u32)sockfd;
2123
cmdbuf[2] = ADDR_STORAGE_LEN;
@@ -47,11 +49,15 @@ int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
4749
return -1;
4850
}
4951

50-
if(*addrlen > tmpaddr[0])
51-
*addrlen = tmpaddr[0];
52-
memset(addr, 0, sizeof(struct sockaddr));
5352
addr->sa_family = tmpaddr[1];
54-
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - 2);
53+
54+
socklen_t user_addrlen = tmpaddr[0];
55+
if(addr->sa_family == AF_INET)
56+
user_addrlen += 8;
57+
58+
if(*addrlen > user_addrlen)
59+
*addrlen = user_addrlen;
60+
memcpy(addr->sa_data, &tmpaddr[2], *addrlen - sizeof(addr->sa_family));
5561

5662
return ret;
5763
}

libctru/source/services/soc/soc_recvfrom.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,14 @@ ssize_t socuipc_cmd7(int sockfd, void *buf, size_t len, int flags, struct sockad
5353

5454
if(src_addr != NULL) {
5555
src_addr->sa_family = tmpaddr[1];
56-
if(*addrlen > tmpaddr[0])
57-
*addrlen = tmpaddr[0];
58-
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
56+
57+
socklen_t user_addrlen = tmpaddr[0];
58+
if(src_addr->sa_family == AF_INET)
59+
user_addrlen += 8;
60+
61+
if(*addrlen > user_addrlen)
62+
*addrlen = user_addrlen;
63+
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - sizeof(src_addr->sa_family));
5964
}
6065

6166
return ret;
@@ -113,9 +118,14 @@ ssize_t socuipc_cmd8(int sockfd, void *buf, size_t len, int flags, struct sockad
113118

114119
if(src_addr != NULL) {
115120
src_addr->sa_family = tmpaddr[1];
116-
if(*addrlen > tmpaddr[0])
117-
*addrlen = tmpaddr[0];
118-
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - 2);
121+
122+
socklen_t user_addrlen = tmpaddr[0];
123+
if(src_addr->sa_family == AF_INET)
124+
user_addrlen += 8;
125+
126+
if(*addrlen > user_addrlen)
127+
*addrlen = user_addrlen;
128+
memcpy(src_addr->sa_data, &tmpaddr[2], *addrlen - sizeof(src_addr->sa_family));
119129
}
120130

121131
return ret;

0 commit comments

Comments
 (0)