HFI1: Range-check proc->fd_priv_table[]
sockioctl01.c in LTP calls ioctl(1025, ...) and causes kernel page-fault without the range-check. Change-Id: I4117783e20107f274c0857b09745f12a5cc5ce2f
This commit is contained in:
committed by
Balazs Gerofi
parent
ca9894108b
commit
6c0bb9e576
@@ -578,7 +578,8 @@ struct process {
|
|||||||
int nr_processes; /* For partitioned execution */
|
int nr_processes; /* For partitioned execution */
|
||||||
int process_rank; /* Rank in partition */
|
int process_rank; /* Rank in partition */
|
||||||
|
|
||||||
void *fd_priv_table[256];
|
#define MAX_FD_PRIV 256
|
||||||
|
void *fd_priv_table[MAX_FD_PRIV];
|
||||||
/* HFI1 specific */
|
/* HFI1 specific */
|
||||||
void *hfi1_kregbase;
|
void *hfi1_kregbase;
|
||||||
void *hfi1_piobase;
|
void *hfi1_piobase;
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ init_process(struct process *proc, struct process *parent)
|
|||||||
#endif /* POSTK_DEBUG_ARCH_DEP_63 */
|
#endif /* POSTK_DEBUG_ARCH_DEP_63 */
|
||||||
|
|
||||||
// Double check the inheritance from parent
|
// Double check the inheritance from parent
|
||||||
memset(proc->fd_priv_table, 0, 256 * sizeof(void *));
|
memset(proc->fd_priv_table, 0, MAX_FD_PRIV * sizeof(void *));
|
||||||
|
|
||||||
INIT_LIST_HEAD(&proc->threads_list);
|
INIT_LIST_HEAD(&proc->threads_list);
|
||||||
INIT_LIST_HEAD(&proc->children_list);
|
INIT_LIST_HEAD(&proc->children_list);
|
||||||
|
|||||||
@@ -485,7 +485,9 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
|
|||||||
res.private_data &&
|
res.private_data &&
|
||||||
!strncmp((const char *)req->args[0], "/dev/hfi", 8)) {
|
!strncmp((const char *)req->args[0], "/dev/hfi", 8)) {
|
||||||
|
|
||||||
thread->proc->fd_priv_table[rc] = res.private_data;
|
if (rc >= 0 && rc < MAX_FD_PRIV) {
|
||||||
|
thread->proc->fd_priv_table[rc] = res.private_data;
|
||||||
|
}
|
||||||
dkprintf("%s: PID: %d, open fd: %d, filename: "
|
dkprintf("%s: PID: %d, open fd: %d, filename: "
|
||||||
"%s, private_data: 0x%lx\n",
|
"%s, private_data: 0x%lx\n",
|
||||||
__FUNCTION__, thread->proc->pid,
|
__FUNCTION__, thread->proc->pid,
|
||||||
@@ -3140,7 +3142,8 @@ SYSCALL_DECLARE(writev)
|
|||||||
int fd = ihk_mc_syscall_arg0(ctx);
|
int fd = ihk_mc_syscall_arg0(ctx);
|
||||||
struct iovec *iovec = (struct iovec *)ihk_mc_syscall_arg1(ctx);
|
struct iovec *iovec = (struct iovec *)ihk_mc_syscall_arg1(ctx);
|
||||||
int iovcnt = ihk_mc_syscall_arg2(ctx);
|
int iovcnt = ihk_mc_syscall_arg2(ctx);
|
||||||
void *private_data = proc->fd_priv_table[fd];
|
void *private_data = (fd < 0 || fd >= MAX_FD_PRIV) ? NULL : proc->fd_priv_table[fd];
|
||||||
|
|
||||||
if (private_data) {
|
if (private_data) {
|
||||||
return hfi1_aio_write(private_data, iovec, iovcnt);
|
return hfi1_aio_write(private_data, iovec, iovcnt);
|
||||||
}
|
}
|
||||||
@@ -3182,7 +3185,7 @@ SYSCALL_DECLARE(ioctl)
|
|||||||
struct process *proc = thread->proc;
|
struct process *proc = thread->proc;
|
||||||
struct mckfd *fdp;
|
struct mckfd *fdp;
|
||||||
long irqstate;
|
long irqstate;
|
||||||
void *private_data = proc->fd_priv_table[fd];
|
void *private_data = (fd < 0 || fd >= MAX_FD_PRIV) ? NULL : proc->fd_priv_table[fd];
|
||||||
unsigned long t_s = rdtsc();
|
unsigned long t_s = rdtsc();
|
||||||
int sub_rc = 0;
|
int sub_rc = 0;
|
||||||
|
|
||||||
@@ -3342,7 +3345,7 @@ SYSCALL_DECLARE(close)
|
|||||||
rc = syscall_generic_forwarding(__NR_close, ctx);
|
rc = syscall_generic_forwarding(__NR_close, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 256) {
|
if (fd >= 0 && fd < MAX_FD_PRIV) {
|
||||||
thread->proc->fd_priv_table[fd] = NULL;
|
thread->proc->fd_priv_table[fd] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user