aboutsummaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
Diffstat (limited to 'i386')
-rw-r--r--i386/i386/seg.h1
-rw-r--r--i386/i386/user_ldt.c7
2 files changed, 5 insertions, 3 deletions
diff --git a/i386/i386/seg.h b/i386/i386/seg.h
index 9427d854..ad7a0f59 100644
--- a/i386/i386/seg.h
+++ b/i386/i386/seg.h
@@ -62,6 +62,7 @@ struct real_gate {
#endif /* !__ASSEMBLER__ */
+#define SZ_64 0x2 /* 64-bit segment */
#define SZ_32 0x4 /* 32-bit segment */
#define SZ_16 0x0 /* 16-bit segment */
#define SZ_G 0x8 /* 4K limit field */
diff --git a/i386/i386/user_ldt.c b/i386/i386/user_ldt.c
index f1b5f6b4..7646c351 100644
--- a/i386/i386/user_ldt.c
+++ b/i386/i386/user_ldt.c
@@ -83,10 +83,10 @@ boolean_t selector_check(thread, sel, type)
access = ldt->ldt[sel_idx(sel)].access;
- if ((access & (ACC_P|ACC_PL|ACC_TYPE_USER))
+ if ((access & (ACC_P|ACC_PL|ACC_TYPE_USER|SZ_64))
!= (ACC_P|ACC_PL_U|ACC_TYPE_USER))
return FALSE;
- /* present, pl == pl.user, not system */
+ /* present, pl == pl.user, not system, not 64bits */
return acc_type[(access & 0xe)>>1][type];
}
@@ -432,7 +432,8 @@ i386_set_gdt (thread_t thread, int *selector, struct real_descriptor desc)
if ((desc.access & ACC_P) == 0)
memset (&thread->pcb->ims.user_gdt[idx], 0,
sizeof thread->pcb->ims.user_gdt[idx]);
- else if ((desc.access & (ACC_TYPE_USER|ACC_PL)) != (ACC_TYPE_USER|ACC_PL_U))
+ else if ((desc.access & (ACC_TYPE_USER|ACC_PL)) != (ACC_TYPE_USER|ACC_PL_U) || (desc.granularity & SZ_64))
+
return KERN_INVALID_ARGUMENT;
else
thread->pcb->ims.user_gdt[idx] = desc;