[Crash-utility] [PATCH] fix open fds display when process using large amount of file descriptors

Dave Anderson anderson at redhat.com
Thu Aug 9 14:58:57 UTC 2018



----- Original Message -----
> Usually, structure fd_set only has 1024 bits size, when a process
> using large amount of file descriptors that exceed the size of fd_set,
> then the display of files and net sockets would mistake caused by the
> out of bounds reading in loop.
> 
> Signed-off-by: Tan Hu <tan.hu at zte.com.cn>

Hello Tan,

Sorry for the delay -- the patch looks good, and my testing verified the issue.  
Queued for crash-7.2.4:

    https://github.com/crash-utility/crash/commit/ba03b66cec24fc0033d4378be08f5f9a96cd4a91

Thanks,
  Dave



> ---
>  filesys.c | 24 ++++++++++++++++++------
>  net.c     | 17 +++++++++++++----
>  2 files changed, 31 insertions(+), 10 deletions(-)
> 
> diff --git a/filesys.c b/filesys.c
> index 0ace8f4..47f5a24 100755
> --- a/filesys.c
> +++ b/filesys.c
> @@ -2380,7 +2380,8 @@ open_files_dump(ulong task, int flags, struct reference
> *ref)
>  	int max_fdset = 0;
>  	int max_fds = 0;
>  	ulong open_fds_addr;
> -	fd_set open_fds;
> +	int open_fds_size;
> +	ulong *open_fds;
>  	ulong fd;
>  	ulong file;
>  	ulong value;
> @@ -2583,16 +2584,25 @@ open_files_dump(ulong task, int flags, struct
> reference *ref)
>  		open_fds_addr = ULONG(files_struct_buf +
>  			OFFSET(files_struct_open_fds));
>  
> +	open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
> +	open_fds = (ulong *)GETBUF(open_fds_size);
> +	if (!open_fds) {
> +		if (fdtable_buf)
> +			FREEBUF(fdtable_buf);
> +		FREEBUF(files_struct_buf);
> +		return;
> +	}
> +
>  	if (open_fds_addr) {
>  		if (VALID_MEMBER(files_struct_open_fds_init) &&
>  		    (open_fds_addr == (files_struct_addr +
>  		    OFFSET(files_struct_open_fds_init))))
>  			BCOPY(files_struct_buf +
>  			        OFFSET(files_struct_open_fds_init),
> -				&open_fds, sizeof(fd_set));
> +				open_fds, open_fds_size);
>  		else
> -			readmem(open_fds_addr, KVADDR, &open_fds,
> -				sizeof(fd_set), "fdtable open_fds",
> +			readmem(open_fds_addr, KVADDR, open_fds,
> +				open_fds_size, "fdtable open_fds",
>  				FAULT_ON_ERROR);
>  	}
>  
> @@ -2607,6 +2617,7 @@ open_files_dump(ulong task, int flags, struct reference
> *ref)
>  		if (fdtable_buf)
>  			FREEBUF(fdtable_buf);
>  		FREEBUF(files_struct_buf);
> +		FREEBUF(open_fds);
>  		return;
>  	}
>  
> @@ -2617,11 +2628,11 @@ open_files_dump(ulong task, int flags, struct
> reference *ref)
>  	j = 0;
>  	for (;;) {
>  		unsigned long set;
> -		i = j * __NFDBITS;
> +		i = j * BITS_PER_LONG;
>  		if (((max_fdset >= 0) && (i >= max_fdset)) ||
>  		    (i >= max_fds))
>  			 break;
> -		set = open_fds.__fds_bits[j++];
> +		set = open_fds[j++];
>  		while (set) {
>  			if (set & 1) {
>          			readmem(fd + i*sizeof(struct file *), KVADDR,
> @@ -2665,6 +2676,7 @@ open_files_dump(ulong task, int flags, struct reference
> *ref)
>  	if (fdtable_buf)
>  		FREEBUF(fdtable_buf);
>  	FREEBUF(files_struct_buf);
> +	FREEBUF(open_fds);
>  }
>  
>  /*
> diff --git a/net.c b/net.c
> index 4199091..f08f22a 100755
> --- a/net.c
> +++ b/net.c
> @@ -1373,7 +1373,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct
> reference *ref)
>  	int max_fdset = 0;
>  	int max_fds = 0;
>  	ulong open_fds_addr = 0;
> -	fd_set open_fds;
> +	ulong *open_fds;
> +	int open_fds_size;
>  	ulong fd;
>  	ulong file;
>  	int i, j;
> @@ -1446,12 +1447,18 @@ dump_sockets_workhorse(ulong task, ulong flag, struct
> reference *ref)
>              		sizeof(void *), "files_struct fd addr", FAULT_ON_ERROR);
>  	}
>  
> +	open_fds_size = MAX(max_fdset, max_fds) / BITS_PER_BYTE;
> +	open_fds = (ulong *)GETBUF(open_fds_size);
> +	if (!open_fds)
> +		return;
> +
>  	if (open_fds_addr)
> -		readmem(open_fds_addr, KVADDR, &open_fds, sizeof(fd_set),
> +		readmem(open_fds_addr, KVADDR, open_fds, open_fds_size,
>  	               	"files_struct open_fds", FAULT_ON_ERROR);
>      	if (!open_fds_addr || !fd) {
>  		if (!NET_REFERENCE_CHECK(ref))
>  			fprintf(fp, "No open sockets.\n");
> +		FREEBUF(open_fds);
>          	return;
>  	}
>  
> @@ -1479,10 +1486,10 @@ dump_sockets_workhorse(ulong task, ulong flag, struct
> reference *ref)
>      	j = 0;
>      	for (;;) {
>  	        unsigned long set;
> -	        i = j * __NFDBITS;
> +	        i = j * BITS_PER_LONG;
>  	        if (((max_fdset >= 0) && (i >= max_fdset)) || (i >= max_fds))
>  	            	break;
> -	        set = open_fds.__fds_bits[j++];
> +	        set = open_fds[j++];
>  	        while (set) {
>  	            	if (set & 1) {
>  		                readmem(fd + i*sizeof(struct file *), KVADDR,
> @@ -1505,6 +1512,8 @@ dump_sockets_workhorse(ulong task, ulong flag, struct
> reference *ref)
>  
>  	if (NET_REFERENCE_FOUND(ref))
>  		fprintf(fp, "\n");
> +
> +	FREEBUF(open_fds);
>  }
>  
>  
> --
> 1.8.3.1
> 
> 




More information about the Crash-utility mailing list