blob: 4245a4c957501f9c3d9386d420a7897fad858c33 [file]
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2025 Andrea Cervesato <[email protected]>
*/
/*\
* Test for CVE-2025-21756 fixed in kernel v6.14:
* fcdd2242c023 vsock: Keep the binding until socket destruction
*
* Reproducer based on:
* https://lore.kernel.org/all/[email protected]/
*
* Beware, this test will crash the system.
*/
#include "tst_test.h"
#include "lapi/vm_sockets.h"
#define MAX_PORT_RETRIES 24
#define VMADDR_CID_NONEXISTING 42
static int vsock_bind(unsigned int cid, unsigned int port, int type)
{
int sock;
struct sockaddr_vm sa = {
.svm_family = AF_VSOCK,
.svm_cid = cid,
.svm_port = port,
};
sock = SAFE_SOCKET(AF_VSOCK, type, 0);
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
if (errno == EINVAL)
tst_brk(TCONF, "VM socket is not supported");
tst_brk(TBROK | TERRNO, "bind() error");
}
return sock;
}
static void run(void)
{
int sockets[MAX_PORT_RETRIES];
struct sockaddr_vm addr;
int socket, sock_count;
socklen_t alen;
socket = vsock_bind(VMADDR_CID_LOCAL, VMADDR_PORT_ANY, SOCK_SEQPACKET);
alen = sizeof(addr);
SAFE_GETSOCKNAME(socket, (struct sockaddr *)&addr, &alen);
for (sock_count = 0; sock_count < MAX_PORT_RETRIES; ++sock_count) {
sockets[sock_count] = vsock_bind(VMADDR_CID_ANY,
++addr.svm_port, SOCK_SEQPACKET);
}
SAFE_CLOSE(socket);
socket = SAFE_SOCKET(AF_VSOCK, SOCK_SEQPACKET, 0);
if (!connect(socket, (struct sockaddr *)&addr, alen))
tst_brk(TBROK, "Unexpected connect() #1 success");
addr.svm_cid = VMADDR_CID_NONEXISTING;
if (!connect(socket, (struct sockaddr *)&addr, alen))
tst_brk(TBROK, "Unexpected connect() #2 success");
addr.svm_cid = VMADDR_CID_LOCAL;
addr.svm_port = VMADDR_PORT_ANY;
/* Vulnerable system may crash now. */
SAFE_BIND(socket, (struct sockaddr *)&addr, alen);
SAFE_CLOSE(socket);
if (tst_taint_check())
tst_res(TFAIL, "Kernel is vulnerable");
else
tst_res(TPASS, "Kernel survived after socket unbinding");
while (sock_count--)
SAFE_CLOSE(sockets[sock_count]);
}
static struct tst_test test = {
.test_all = run,
.taint_check = TST_TAINT_W | TST_TAINT_D,
.tags = (const struct tst_tag[]) {
{"linux-git", "fcdd2242c0231032fc84e1404315c245ae56322a"},
{"CVE", "2025-21756"},
{}
},
};