[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