Skip to content

Commit 301a62d

Browse files
mmhalkuba-moo
authored andcommitted
vsock/test: Add test for UAF due to socket unbinding
Fail the autobind, then trigger a transport reassign. Socket might get unbound from unbound_sockets, which then leads to a reference count underflow. Reviewed-by: Stefano Garzarella <[email protected]> Signed-off-by: Michal Luczaj <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent ac12b7e commit 301a62d

File tree

1 file changed

+58
-0
lines changed

1 file changed

+58
-0
lines changed

tools/testing/vsock/vsock_test.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1693,6 +1693,59 @@ static void test_stream_msgzcopy_leak_zcskb_server(const struct test_opts *opts)
16931693
close(fd);
16941694
}
16951695

1696+
#define MAX_PORT_RETRIES 24 /* net/vmw_vsock/af_vsock.c */
1697+
1698+
/* Test attempts to trigger a transport release for an unbound socket. This can
1699+
* lead to a reference count mishandling.
1700+
*/
1701+
static void test_stream_transport_uaf_client(const struct test_opts *opts)
1702+
{
1703+
int sockets[MAX_PORT_RETRIES];
1704+
struct sockaddr_vm addr;
1705+
int fd, i, alen;
1706+
1707+
fd = vsock_bind(VMADDR_CID_ANY, VMADDR_PORT_ANY, SOCK_STREAM);
1708+
1709+
alen = sizeof(addr);
1710+
if (getsockname(fd, (struct sockaddr *)&addr, &alen)) {
1711+
perror("getsockname");
1712+
exit(EXIT_FAILURE);
1713+
}
1714+
1715+
for (i = 0; i < MAX_PORT_RETRIES; ++i)
1716+
sockets[i] = vsock_bind(VMADDR_CID_ANY, ++addr.svm_port,
1717+
SOCK_STREAM);
1718+
1719+
close(fd);
1720+
fd = socket(AF_VSOCK, SOCK_STREAM, 0);
1721+
if (fd < 0) {
1722+
perror("socket");
1723+
exit(EXIT_FAILURE);
1724+
}
1725+
1726+
if (!vsock_connect_fd(fd, addr.svm_cid, addr.svm_port)) {
1727+
perror("Unexpected connect() #1 success");
1728+
exit(EXIT_FAILURE);
1729+
}
1730+
1731+
/* Vulnerable system may crash now. */
1732+
if (!vsock_connect_fd(fd, VMADDR_CID_HOST, VMADDR_PORT_ANY)) {
1733+
perror("Unexpected connect() #2 success");
1734+
exit(EXIT_FAILURE);
1735+
}
1736+
1737+
close(fd);
1738+
while (i--)
1739+
close(sockets[i]);
1740+
1741+
control_writeln("DONE");
1742+
}
1743+
1744+
static void test_stream_transport_uaf_server(const struct test_opts *opts)
1745+
{
1746+
control_expectln("DONE");
1747+
}
1748+
16961749
static struct test_case test_cases[] = {
16971750
{
16981751
.name = "SOCK_STREAM connection reset",
@@ -1838,6 +1891,11 @@ static struct test_case test_cases[] = {
18381891
.run_client = test_stream_msgzcopy_leak_zcskb_client,
18391892
.run_server = test_stream_msgzcopy_leak_zcskb_server,
18401893
},
1894+
{
1895+
.name = "SOCK_STREAM transport release use-after-free",
1896+
.run_client = test_stream_transport_uaf_client,
1897+
.run_server = test_stream_transport_uaf_server,
1898+
},
18411899
{},
18421900
};
18431901

0 commit comments

Comments
 (0)