[CRIU] [PATCH RESEND] files: Fix crossing unused and service fds of shared fd tables
Andrei Vagin
avagin at virtuozzo.com
Sat Jul 8 02:22:35 MSK 2017
Applied, thanks
On Wed, Jun 28, 2017 at 01:45:42PM +0300, Kirill Tkhai wrote:
> service_fd_id is id of a specific task, while other tasks
> in shared fd table group may have bigger id numbers.
> In this case given unused fd intersects with service fds
> of such tasks. This leads to undefined behaviour. Fix that.
>
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
> criu/files.c | 4 ++--
> criu/include/servicefd.h | 4 +++-
> criu/util.c | 9 +++++++--
> 3 files changed, 12 insertions(+), 5 deletions(-)
>
> diff --git a/criu/files.c b/criu/files.c
> index a36eb366e..1b0e02626 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -153,7 +153,7 @@ unsigned int find_unused_fd(struct pstree_item *task, int hint_fd)
> goto out;
> }
>
> - prev_fd = service_fd_min_fd() - 1;
> + prev_fd = service_fd_min_fd(task) - 1;
> head = &rsti(task)->fds;
>
> list_for_each_entry_reverse(fle, head, ps_list) {
> @@ -877,7 +877,7 @@ int prepare_fd_pid(struct pstree_item *item)
> if (ret <= 0)
> break;
>
> - if (e->fd >= service_fd_min_fd()) {
> + if (e->fd >= service_fd_min_fd(item)) {
> ret = -1;
> pr_err("Too big FD number to restore %d\n", e->fd);
> break;
> diff --git a/criu/include/servicefd.h b/criu/include/servicefd.h
> index b77922394..29e5b0bdb 100644
> --- a/criu/include/servicefd.h
> +++ b/criu/include/servicefd.h
> @@ -28,6 +28,8 @@ enum sfd_type {
> SERVICE_FD_MAX
> };
>
> +struct pstree_item;
> +
> extern int clone_service_fd(int id);
> extern int init_service_fd(void);
> extern int get_service_fd(enum sfd_type type);
> @@ -36,6 +38,6 @@ extern int install_service_fd(enum sfd_type type, int fd);
> extern int close_service_fd(enum sfd_type type);
> extern bool is_service_fd(int fd, enum sfd_type type);
> extern bool is_any_service_fd(int fd);
> -extern int service_fd_min_fd(void);
> +extern int service_fd_min_fd(struct pstree_item *);
>
> #endif /* __CR_SERVICE_FD_H__ */
> diff --git a/criu/util.c b/criu/util.c
> index db484f2f8..6c55b13c1 100644
> --- a/criu/util.c
> +++ b/criu/util.c
> @@ -417,9 +417,14 @@ static int __get_service_fd(enum sfd_type type, int service_fd_id)
> return service_fd_rlim_cur - type - SERVICE_FD_MAX * service_fd_id;
> }
>
> -int service_fd_min_fd(void)
> +int service_fd_min_fd(struct pstree_item *item)
> {
> - return service_fd_rlim_cur - (SERVICE_FD_MAX - 1) - SERVICE_FD_MAX * service_fd_id;
> + struct fdt *fdt = rsti(item)->fdt;
> + int id = 0;
> +
> + if (fdt)
> + id = fdt->nr - 1;
> + return service_fd_rlim_cur - (SERVICE_FD_MAX - 1) - SERVICE_FD_MAX * id;
> }
>
> static DECLARE_BITMAP(sfd_map, SERVICE_FD_MAX);
>
More information about the CRIU
mailing list