tss: block userspace access to all I/O ports.
A userspace process (CPL=3) can access an i/o port if the bit corresponding to the port is set to 0 in the I/O permission bitmap. Configure the I/O permission bitmap address beyond the last valid byte in the TSS so access to all i/o ports is blocked. Signed-off-by: Liu Hua <sdu.liu@huawei.com> Change-Id: I3df76980c3735491db768f7210e71703f86bb989 PiperOrigin-RevId: 257336518
This commit is contained in:
parent
7965b1272b
commit
7581e84cb6
|
@ -70,6 +70,14 @@ func (c *CPU) init() {
|
|||
c.tss.ist1Lo = uint32(stackAddr)
|
||||
c.tss.ist1Hi = uint32(stackAddr >> 32)
|
||||
|
||||
// Set the I/O bitmap base address beyond the last byte in the TSS
|
||||
// to block access to the entire I/O address range.
|
||||
//
|
||||
// From section 18.5.2 "I/O Permission Bit Map" from Intel SDM vol1:
|
||||
// I/O addresses not spanned by the map are treated as if they had set
|
||||
// bits in the map.
|
||||
c.tss.ioPerm = tssLimit + 1
|
||||
|
||||
// Permanently set the kernel segments.
|
||||
c.registers.Cs = uint64(Kcode)
|
||||
c.registers.Ds = uint64(Kdata)
|
||||
|
|
|
@ -56,6 +56,26 @@ void inline Int3Normal() { asm(".byte 0xcd, 0x03\r\n"); }
|
|||
|
||||
void inline Int3Compact() { asm(".byte 0xcc\r\n"); }
|
||||
|
||||
void InIOHelper(int width, int value) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
switch (width) {
|
||||
case 1:
|
||||
asm volatile("inb %%dx, %%al" ::"d"(value) : "%eax");
|
||||
break;
|
||||
case 2:
|
||||
asm volatile("inw %%dx, %%ax" ::"d"(value) : "%eax");
|
||||
break;
|
||||
case 4:
|
||||
asm volatile("inl %%dx, %%eax" ::"d"(value) : "%eax");
|
||||
break;
|
||||
default:
|
||||
FAIL() << "invalid input width, only 1, 2 or 4 is allowed";
|
||||
}
|
||||
},
|
||||
::testing::KilledBySignal(SIGSEGV), "");
|
||||
}
|
||||
|
||||
TEST(ExceptionTest, Halt) {
|
||||
// In order to prevent the regular handler from messing with things (and
|
||||
// perhaps refaulting until some other signal occurs), we reset the handler to
|
||||
|
@ -87,6 +107,20 @@ TEST(ExceptionTest, DivideByZero) {
|
|||
::testing::KilledBySignal(SIGFPE), "");
|
||||
}
|
||||
|
||||
TEST(ExceptionTest, IOAccessFault) {
|
||||
// See above.
|
||||
struct sigaction sa = {};
|
||||
sa.sa_handler = SIG_DFL;
|
||||
auto const cleanup = ASSERT_NO_ERRNO_AND_VALUE(ScopedSigaction(SIGSEGV, sa));
|
||||
|
||||
InIOHelper(1, 0x0);
|
||||
InIOHelper(2, 0x7);
|
||||
InIOHelper(4, 0x6);
|
||||
InIOHelper(1, 0xffff);
|
||||
InIOHelper(2, 0xffff);
|
||||
InIOHelper(4, 0xfffd);
|
||||
}
|
||||
|
||||
TEST(ExceptionTest, Alignment) {
|
||||
SetAlignmentCheck();
|
||||
ClearAlignmentCheck();
|
||||
|
|
Loading…
Reference in New Issue