[CRIU] [PATCH v2 01/15] files: Fix find_unused_fd() overflow

Pavel Emelyanov xemul at virtuozzo.com
Mon May 30 04:32:15 PDT 2016


On 05/27/2016 04:05 PM, Kirill Tkhai wrote:
> This function may catch overflow near INT_MAX, so
> it becomes return strange fd, like fd = -2147483648.
> Fix that.
> 
> Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
> ---
>  criu/files.c         |   31 +++++++++++++++++++++++++++++++
>  criu/include/files.h |    8 +-------
>  2 files changed, 32 insertions(+), 7 deletions(-)
> 
> diff --git a/criu/files.c b/criu/files.c
> index 16bc74d..a52e12f 100644
> --- a/criu/files.c
> +++ b/criu/files.c
> @@ -97,6 +97,37 @@ static inline struct file_desc *find_file_desc(FdinfoEntry *fe)
>  	return find_file_desc_raw(fe->type, fe->id);
>  }
>  
> +unsigned int find_unused_fd(struct list_head *head, int hint_fd)
> +{
> +	struct fdinfo_list_entry *fle;
> +	int fd, prev_fd;
> +
> +	if ((hint_fd >= 0) && (!fd_is_used(head, hint_fd))) {
> +		fd = hint_fd;
> +		goto out;
> +	}
> +	/* Return last used fd +1 */
> +	fd = list_entry(head->prev, typeof(struct fdinfo_list_entry), used_list)->fe->fd;
> +
> +	if (likely(fd < INT_MAX)) {
> +		fd++;

Is INT_MAX a valid file descriptor?

> +		goto out;
> +	}
> +	prev_fd = INT_MAX;
> +
> +	list_for_each_entry_reverse(fle, head, used_list) {

What's the point int list_entry(head->prev,...) above if we're scanning the
list. Can you make this code have only list_for_each_entry_reverse?

> +		fd = fle->fe->fd;
> +		if (prev_fd > fd) {
> +			fd++;
> +			goto out;
> +		}
> +		prev_fd = fd - 1;
> +	}
> +	BUG();
> +out:
> +	return fd;
> +}
> +
>  /*
>   * A file may be shared between several file descriptors. E.g
>   * when doing a fork() every fd of a forker and respective fds
> diff --git a/criu/include/files.h b/criu/include/files.h
> index f89164e..d46b3cd 100644
> --- a/criu/include/files.h
> +++ b/criu/include/files.h
> @@ -137,13 +137,7 @@ static inline bool fd_is_used(struct list_head *head, int fd)
>  	return false;
>  }
>  
> -static inline unsigned int find_unused_fd(struct list_head *head, int hint_fd)
> -{
> -	if ((hint_fd >= 0) && (!fd_is_used(head, hint_fd)))
> -		return hint_fd;
> -	/* Return last used fd +1 */
> -	return list_entry(head->prev, typeof(struct fdinfo_list_entry), used_list)->fe->fd + 1;
> -}
> +unsigned int find_unused_fd(struct list_head *head, int hint_fd);
>  
>  struct file_desc {
>  	u32			id;		/* File id, unique */
> 
> _______________________________________________
> CRIU mailing list
> CRIU at openvz.org
> https://lists.openvz.org/mailman/listinfo/criu
> .
> 



More information about the CRIU mailing list