From d64d3805b8fed58f561caac73c40fa8f8be03d1b Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 16 Nov 2011 09:00:26 -0800 Subject: [PATCH] kernel - Handle degenerate cases for fill_*regs*() * These routines can be called with the lwp in various states of disrepair so check for NULL and return EINVAL if required pieces are missing. --- sys/platform/pc32/i386/machdep.c | 32 +++++++++++++----------- sys/platform/pc64/x86_64/machdep.c | 30 ++++++++++++---------- sys/platform/vkernel/i386/cpu_regs.c | 5 +++- sys/platform/vkernel64/x86_64/cpu_regs.c | 5 +++- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/sys/platform/pc32/i386/machdep.c b/sys/platform/pc32/i386/machdep.c index cb866eb145..5f52b84294 100644 --- a/sys/platform/pc32/i386/machdep.c +++ b/sys/platform/pc32/i386/machdep.c @@ -2260,7 +2260,8 @@ fill_regs(struct lwp *lp, struct reg *regs) { struct trapframe *tp; - tp = lp->lwp_md.md_regs; + if ((tp = lp->lwp_md.md_regs) == NULL) + return EINVAL; regs->r_gs = tp->tf_gs; regs->r_fs = tp->tf_fs; regs->r_es = tp->tf_es; @@ -2357,6 +2358,8 @@ set_fpregs_xmm(struct save87 *sv_87, struct savexmm *sv_xmm) int fill_fpregs(struct lwp *lp, struct fpreg *fpregs) { + if (lp->lwp_thread == NULL || lp->lwp_thread->td_pcb == NULL) + return EINVAL; #ifndef CPU_DISABLE_SSE if (cpu_fxsr) { fill_fpregs_xmm(&lp->lwp_thread->td_pcb->pcb_save.sv_xmm, @@ -2385,6 +2388,8 @@ set_fpregs(struct lwp *lp, struct fpreg *fpregs) int fill_dbregs(struct lwp *lp, struct dbreg *dbregs) { + struct pcb *pcb; + if (lp == NULL) { dbregs->dr0 = rdr0(); dbregs->dr1 = rdr1(); @@ -2394,19 +2399,18 @@ fill_dbregs(struct lwp *lp, struct dbreg *dbregs) dbregs->dr5 = rdr5(); dbregs->dr6 = rdr6(); dbregs->dr7 = rdr7(); - } else { - struct pcb *pcb; - - pcb = lp->lwp_thread->td_pcb; - dbregs->dr0 = pcb->pcb_dr0; - dbregs->dr1 = pcb->pcb_dr1; - dbregs->dr2 = pcb->pcb_dr2; - dbregs->dr3 = pcb->pcb_dr3; - dbregs->dr4 = 0; - dbregs->dr5 = 0; - dbregs->dr6 = pcb->pcb_dr6; - dbregs->dr7 = pcb->pcb_dr7; - } + return (0); + } + if (lp->lwp_thread == NULL || (pcb = lp->lwp_thread->td_pcb) == NULL) + return EINVAL; + dbregs->dr0 = pcb->pcb_dr0; + dbregs->dr1 = pcb->pcb_dr1; + dbregs->dr2 = pcb->pcb_dr2; + dbregs->dr3 = pcb->pcb_dr3; + dbregs->dr4 = 0; + dbregs->dr5 = 0; + dbregs->dr6 = pcb->pcb_dr6; + dbregs->dr7 = pcb->pcb_dr7; return (0); } diff --git a/sys/platform/pc64/x86_64/machdep.c b/sys/platform/pc64/x86_64/machdep.c index adceb132ff..74bbd53534 100644 --- a/sys/platform/pc64/x86_64/machdep.c +++ b/sys/platform/pc64/x86_64/machdep.c @@ -2011,7 +2011,8 @@ fill_regs(struct lwp *lp, struct reg *regs) { struct trapframe *tp; - tp = lp->lwp_md.md_regs; + if ((tp = lp->lwp_md.md_regs) == NULL) + return EINVAL; bcopy(&tp->tf_rdi, ®s->r_rdi, sizeof(*regs)); return (0); } @@ -2079,6 +2080,8 @@ set_fpregs_xmm(struct save87 *sv_87, struct savexmm *sv_xmm) int fill_fpregs(struct lwp *lp, struct fpreg *fpregs) { + if (lp->lwp_thread == NULL || lp->lwp_thread->td_pcb == NULL) + return EINVAL; #ifndef CPU_DISABLE_SSE if (cpu_fxsr) { fill_fpregs_xmm(&lp->lwp_thread->td_pcb->pcb_save.sv_xmm, @@ -2107,6 +2110,8 @@ set_fpregs(struct lwp *lp, struct fpreg *fpregs) int fill_dbregs(struct lwp *lp, struct dbreg *dbregs) { + struct pcb *pcb; + if (lp == NULL) { dbregs->dr[0] = rdr0(); dbregs->dr[1] = rdr1(); @@ -2116,19 +2121,18 @@ fill_dbregs(struct lwp *lp, struct dbreg *dbregs) dbregs->dr[5] = rdr5(); dbregs->dr[6] = rdr6(); dbregs->dr[7] = rdr7(); - } else { - struct pcb *pcb; - - pcb = lp->lwp_thread->td_pcb; - dbregs->dr[0] = pcb->pcb_dr0; - dbregs->dr[1] = pcb->pcb_dr1; - dbregs->dr[2] = pcb->pcb_dr2; - dbregs->dr[3] = pcb->pcb_dr3; - dbregs->dr[4] = 0; - dbregs->dr[5] = 0; - dbregs->dr[6] = pcb->pcb_dr6; - dbregs->dr[7] = pcb->pcb_dr7; + return (0); } + if (lp->lwp_thread == NULL || (pcb = lp->lwp_thread->td_pcb) == NULL) + return EINVAL; + dbregs->dr[0] = pcb->pcb_dr0; + dbregs->dr[1] = pcb->pcb_dr1; + dbregs->dr[2] = pcb->pcb_dr2; + dbregs->dr[3] = pcb->pcb_dr3; + dbregs->dr[4] = 0; + dbregs->dr[5] = 0; + dbregs->dr[6] = pcb->pcb_dr6; + dbregs->dr[7] = pcb->pcb_dr7; return (0); } diff --git a/sys/platform/vkernel/i386/cpu_regs.c b/sys/platform/vkernel/i386/cpu_regs.c index 10aceb017b..b700d40506 100644 --- a/sys/platform/vkernel/i386/cpu_regs.c +++ b/sys/platform/vkernel/i386/cpu_regs.c @@ -918,7 +918,8 @@ fill_regs(struct lwp *lp, struct reg *regs) { struct trapframe *tp; - tp = lp->lwp_md.md_regs; + if ((tp = lp->lwp_md.md_regs) == NULL) + return EINVAL; regs->r_gs = tp->tf_gs; regs->r_fs = tp->tf_fs; regs->r_es = tp->tf_es; @@ -1015,6 +1016,8 @@ set_fpregs_xmm(struct save87 *sv_87, struct savexmm *sv_xmm) int fill_fpregs(struct lwp *lp, struct fpreg *fpregs) { + if (lp->lwp_thread == NULL || lp->lwp_thread->td_pcb == NULL) + return EINVAL; #ifndef CPU_DISABLE_SSE if (cpu_fxsr) { fill_fpregs_xmm(&lp->lwp_thread->td_pcb->pcb_save.sv_xmm, diff --git a/sys/platform/vkernel64/x86_64/cpu_regs.c b/sys/platform/vkernel64/x86_64/cpu_regs.c index a517088d44..d077eb7f97 100644 --- a/sys/platform/vkernel64/x86_64/cpu_regs.c +++ b/sys/platform/vkernel64/x86_64/cpu_regs.c @@ -919,7 +919,8 @@ fill_regs(struct lwp *lp, struct reg *regs) { struct trapframe *tp; - tp = lp->lwp_md.md_regs; + if ((tp = lp->lwp_md.md_regs) == NULL) + return EINVAL; bcopy(&tp->tf_rdi, ®s->r_rdi, sizeof(*regs)); return (0); } @@ -986,6 +987,8 @@ set_fpregs_xmm(struct save87 *sv_87, struct savexmm *sv_xmm) int fill_fpregs(struct lwp *lp, struct fpreg *fpregs) { + if (lp->lwp_thread == NULL || lp->lwp_thread->td_pcb == NULL) + return EINVAL; #ifndef CPU_DISABLE_SSE if (cpu_fxsr) { fill_fpregs_xmm(&lp->lwp_thread->td_pcb->pcb_save.sv_xmm, -- 2.41.0