unix: Add fake interconnected sockets

We're going to split interconnected pair restore
on two stages. Since we need the second end
to restore message queue in (future) post open,
we add it to the process, who is owner of the first
end.

Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
Kirill Tkhai 2018-01-30 18:41:56 +03:00 committed by Andrei Vagin
parent cc0c57d988
commit 0f6f224656

View file

@ -1249,12 +1249,18 @@ done:
static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
{
int sk[2];
struct fdinfo_list_entry *fle, *fle_peer;
struct unix_sk_info *peer = ui->peer;
int sk[2];
pr_info("Opening pair master (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer);
fle = file_master(&ui->d);
fle_peer = file_master(&peer->d);
BUG_ON(fle->task != fle_peer->task); /* See interconnected_pair() */
if (set_netns(ui->ue->ns_id))
return -1;
@ -1628,10 +1634,32 @@ static void set_peer(struct unix_sk_info *ui, struct unix_sk_info *peer)
peer->queuer = ui->ue->id;
}
static void interconnected_pair(struct unix_sk_info *ui, struct unix_sk_info *peer)
/* This function is called from post prepare only */
static int interconnected_pair(struct unix_sk_info *ui, struct unix_sk_info *peer)
{
struct fdinfo_list_entry *fle, *fle_peer;
ui->flags |= USK_PAIR_MASTER;
peer->flags |= USK_PAIR_SLAVE;
fle = file_master(&ui->d);
fle_peer = file_master(&peer->d);
/*
* Since queue restore is delayed, every socket of the pair
* should have another end to send the queue packets.
* To fit that, we make the both file_master's to be owned
* by the only task.
* This function is called from run_post_prepare() and
* after add_fake_fds_masters(), so we must not add masters,
* which fle->task has no permissions to restore. But
* it has permissions on ui, so it has permissions on peer.
*/
if (fle->task != fle_peer->task &&
!get_fle_for_task(&peer->d, fle->task, true))
return -1;
return 0;
}
static int fixup_unix_peer(struct unix_sk_info *ui)
@ -1649,7 +1677,8 @@ static int fixup_unix_peer(struct unix_sk_info *ui)
pr_info("Connected %#x -> %#x (%#x) flags %#x\n",
ui->ue->ino, ui->ue->peer, peer->ue->ino, ui->flags);
/* socketpair or interconnected sockets */
interconnected_pair(ui, peer);
if (interconnected_pair(ui, peer))
return -1;
}
return 0;