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@xxxxxxxxxx> --- 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 -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility