This commit is contained in:
ankimaha-sys 2026-07-16 16:43:12 +05:30 committed by GitHub
commit 368f7fedf9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 64 additions and 23 deletions

View file

@ -1111,25 +1111,37 @@ out:
return ret;
}
/*
* This helper owns new_fd. On failure it closes either new_fd or, after
* reopen_fd_as() succeeds, the descriptor moved to fle->fe->fd.
*/
int setup_and_serve_out(struct fdinfo_list_entry *fle, int new_fd)
{
struct file_desc *d = fle->desc;
pid_t pid = fle->pid;
if (reopen_fd_as(fle->fe->fd, new_fd))
return -1;
goto err;
new_fd = fle->fe->fd;
if (fcntl(fle->fe->fd, F_SETFD, fle->fe->flags) == -1) {
pr_perror("Unable to set file descriptor flags");
return -1;
goto err;
}
BUG_ON(fle->stage != FLE_INITIALIZED);
fle->stage = FLE_OPEN;
/*
* After FLE_OPEN the descriptor may already be referenced
* by other parts of restore; don't close it on failure.
*/
if (serve_out_fd(pid, fle->fe->fd, d))
return -1;
return 0;
err:
close(new_fd);
return -1;
}
static int open_fd(struct fdinfo_list_entry *fle)

View file

@ -1741,7 +1741,7 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
{
struct fdinfo_list_entry *fle, *fle_peer;
struct unix_sk_info *peer = ui->peer;
int sk[2], tmp;
int sk[2], ret;
fle = file_master(&ui->d);
pr_info_opening("master", ui, fle);
@ -1765,29 +1765,39 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
* Below setup_and_serve_out() will reuse this fd,
* so this dups it in something else.
*/
tmp = dup(sk[0]);
if (tmp < 0) {
ret = dup(sk[0]);
if (ret < 0) {
pr_perror("Can't dup()");
return -1;
goto err;
}
close(sk[0]);
sk[0] = tmp;
sk[0] = ret;
}
if (setup_and_serve_out(fle_peer, sk[1])) {
ret = setup_and_serve_out(fle_peer, sk[1]);
sk[1] = -1;
if (ret) {
pr_err("Can't send pair slave\n");
return -1;
goto err;
}
sk[1] = fle_peer->fe->fd;
if (bind_unix_sk(sk[0], ui))
return -1;
goto err;
if (bind_unix_sk(sk[1], peer))
return -1;
if (bind_unix_sk(fle_peer->fe->fd, peer))
goto err;
*new_fd = sk[0];
return 1;
err:
close_safe(&sk[1]);
close_safe(&sk[0]);
/*
* Don't close fle_peer->fe->fd here: once setup_and_serve_out()
* succeeds the descriptor is at FLE_OPEN and may already be
* referenced by other restore participants.
*/
return -1;
}
static int open_unixsk_pair_slave(struct unix_sk_info *ui, int *new_fd)
@ -1820,6 +1830,7 @@ static int setup_second_end(int *sks, struct fdinfo_list_entry *second_end)
ret = dup(sks[0]);
if (ret < 0) {
pr_perror("Can't dup()");
close(sks[1]);
return -1;
}
close(sks[0]);
@ -1837,7 +1848,7 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
{
struct unix_sk_info *queuer = ui->queuer;
struct unix_sk_info *peer = ui->peer;
struct fdinfo_list_entry *fle;
struct fdinfo_list_entry *fle, *second_end = NULL;
int sk;
fle = file_master(&ui->d);
@ -1882,13 +1893,17 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
return -1;
}
if (send_criu_dump_resp(sks[1], true, true) == -1)
if (send_criu_dump_resp(sks[1], true, true) == -1) {
close(sks[0]);
close(sks[1]);
return -1;
}
close(sks[1]);
sk = sks[0];
} else if ((ui->ue->state == TCP_ESTABLISHED && ui->ue->type != SOCK_DGRAM) && queuer &&
queuer->ue->ino == FAKE_INO) {
struct fdinfo_list_entry *queuer_fle;
int ret, sks[2];
if (ui->ue->shutdown != SK_SHUTDOWN__BOTH) {
@ -1902,11 +1917,16 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
return -1;
}
if (setup_second_end(sks, file_master(&queuer->d)))
queuer_fle = file_master(&queuer->d);
if (setup_second_end(sks, queuer_fle)) {
close(sks[0]);
return -1;
}
second_end = queuer_fle;
sk = sks[0];
} else if (ui->ue->type == SOCK_DGRAM && queuer && queuer->ue->ino == FAKE_INO) {
struct fdinfo_list_entry *queuer_fle;
struct sockaddr_un addr;
int sks[2];
@ -1930,12 +1950,18 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
*/
if (connect(sk, (struct sockaddr *)&addr, sizeof(addr.sun_family))) {
pr_perror("Can't clear socket's peer");
close(sks[0]);
close(sks[1]);
return -1;
}
if (setup_second_end(sks, file_master(&queuer->d)))
queuer_fle = file_master(&queuer->d);
if (setup_second_end(sks, queuer_fle)) {
close(sks[0]);
return -1;
}
second_end = queuer_fle;
sk = sks[0];
} else {
if (ui->ue->uflags & USK_CALLBACK) {
@ -1962,16 +1988,14 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
}
if (bind_unix_sk(sk, ui)) {
close(sk);
return -1;
goto err;
}
if (ui->ue->state == TCP_LISTEN) {
pr_info("\tPutting %u into listen state\n", ui->ue->ino);
if (listen(sk, ui->ue->backlog) < 0) {
pr_perror("Can't make usk listen");
close(sk);
return -1;
goto err;
}
ui->listen = 1;
wake_connected_sockets(ui);
@ -1991,10 +2015,15 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
out:
if (restore_sk_common(sk, ui))
return -1;
goto err;
*new_fd = sk;
return 0;
err:
if (second_end)
close(second_end->fe->fd);
close(sk);
return -1;
}
static int open_unix_sk(struct file_desc *d, int *new_fd)

View file

@ -2345,9 +2345,9 @@ static int pty_create_ptmx_index(int dfd, int index, int flags)
return -1;
id = fdstore_add(fd);
close(fd);
if (id < 0)
return -1;
close(fd);
list_for_each_entry(info, &all_ttys, list) {
if (!is_pty(info->driver))