Tan,
I will review your patch when I return from vacation next week.
Thanks,
Dave
----- 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(a)zte.com.cn>
---
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