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:
Masamichi Takagi
2018-06-11 14:20:25 +09:00
committed by Balazs Gerofi
parent ca9894108b
commit 6c0bb9e576
3 changed files with 10 additions and 6 deletions

View File

@ -578,7 +578,8 @@ struct process {
int nr_processes; /* For partitioned execution */
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 */
void *hfi1_kregbase;
void *hfi1_piobase;

View File

@ -140,7 +140,7 @@ init_process(struct process *proc, struct process *parent)
#endif /* POSTK_DEBUG_ARCH_DEP_63 */
// 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->children_list);

View File

@ -485,7 +485,9 @@ long do_syscall(struct syscall_request *req, int cpu, int pid)
res.private_data &&
!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: "
"%s, private_data: 0x%lx\n",
__FUNCTION__, thread->proc->pid,
@ -3140,7 +3142,8 @@ SYSCALL_DECLARE(writev)
int fd = ihk_mc_syscall_arg0(ctx);
struct iovec *iovec = (struct iovec *)ihk_mc_syscall_arg1(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) {
return hfi1_aio_write(private_data, iovec, iovcnt);
}
@ -3182,7 +3185,7 @@ SYSCALL_DECLARE(ioctl)
struct process *proc = thread->proc;
struct mckfd *fdp;
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();
int sub_rc = 0;
@ -3342,7 +3345,7 @@ SYSCALL_DECLARE(close)
rc = syscall_generic_forwarding(__NR_close, ctx);
}
if (fd < 256) {
if (fd >= 0 && fd < MAX_FD_PRIV) {
thread->proc->fd_priv_table[fd] = NULL;
}