mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-30 22:05:36 +00:00
files: Fix crossing unused and service fds of shared fd tables
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@virtuozzo.com> Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
This commit is contained in:
committed by
Andrei Vagin
parent
8cb7b43a49
commit
4f23a1fd90
@@ -160,7 +160,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) {
|
||||
@@ -926,7 +926,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;
|
||||
|
@@ -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__ */
|
||||
|
@@ -462,9 +462,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);
|
||||
|
Reference in New Issue
Block a user