x86/ioperm: Extend IOPL config to control ioperm() as well
If iopl() is disabled, then providing ioperm() does not make much sense. Rename the config option and disable/enable both syscalls with it. Guard the code with #ifdefs where appropriate. Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Родитель
a24ca99768
Коммит
111e7b15cf
|
@ -1254,10 +1254,13 @@ config X86_VSYSCALL_EMULATION
|
|||
Disabling this option saves about 7K of kernel size and
|
||||
possibly 4K of additional runtime pagetable memory.
|
||||
|
||||
config X86_IOPL_EMULATION
|
||||
bool "IOPL Emulation"
|
||||
config X86_IOPL_IOPERM
|
||||
bool "IOPERM and IOPL Emulation"
|
||||
default y
|
||||
---help---
|
||||
This enables the ioperm() and iopl() syscalls which are necessary
|
||||
for legacy applications.
|
||||
|
||||
Legacy IOPL support is an overbroad mechanism which allows user
|
||||
space aside of accessing all 65536 I/O ports also to disable
|
||||
interrupts. To gain this access the caller needs CAP_SYS_RAWIO
|
||||
|
|
|
@ -15,9 +15,15 @@ struct io_bitmap {
|
|||
|
||||
struct task_struct;
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
void io_bitmap_share(struct task_struct *tsk);
|
||||
void io_bitmap_exit(void);
|
||||
|
||||
void tss_update_io_bitmap(void);
|
||||
#else
|
||||
static inline void io_bitmap_share(struct task_struct *tsk) { }
|
||||
static inline void io_bitmap_exit(void) { }
|
||||
static inline void tss_update_io_bitmap(void) { }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -340,13 +340,18 @@ struct x86_hw_tss {
|
|||
(offsetof(struct tss_struct, io_bitmap.mapall) - \
|
||||
offsetof(struct tss_struct, x86_tss))
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
/*
|
||||
* sizeof(unsigned long) coming from an extra "long" at the end of the
|
||||
* iobitmap. The limit is inclusive, i.e. the last valid byte.
|
||||
*/
|
||||
#define __KERNEL_TSS_LIMIT \
|
||||
# define __KERNEL_TSS_LIMIT \
|
||||
(IO_BITMAP_OFFSET_VALID_ALL + IO_BITMAP_BYTES + \
|
||||
sizeof(unsigned long) - 1)
|
||||
#else
|
||||
# define __KERNEL_TSS_LIMIT \
|
||||
(offsetof(struct tss_struct, x86_tss) + sizeof(struct x86_hw_tss) - 1)
|
||||
#endif
|
||||
|
||||
/* Base offset outside of TSS_LIMIT so unpriviledged IO causes #GP */
|
||||
#define IO_BITMAP_OFFSET_INVALID (__KERNEL_TSS_LIMIT + 1)
|
||||
|
@ -398,7 +403,9 @@ struct tss_struct {
|
|||
*/
|
||||
struct x86_hw_tss x86_tss;
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
struct x86_io_bitmap io_bitmap;
|
||||
#endif
|
||||
} __aligned(PAGE_SIZE);
|
||||
|
||||
DECLARE_PER_CPU_PAGE_ALIGNED(struct tss_struct, cpu_tss_rw);
|
||||
|
|
|
@ -156,8 +156,13 @@ struct thread_info {
|
|||
# define _TIF_WORK_CTXSW (_TIF_WORK_CTXSW_BASE)
|
||||
#endif
|
||||
|
||||
#define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY | \
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
# define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY | \
|
||||
_TIF_IO_BITMAP)
|
||||
#else
|
||||
# define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW| _TIF_USER_RETURN_NOTIFY)
|
||||
#endif
|
||||
|
||||
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW)
|
||||
|
||||
#define STACK_WARN (THREAD_SIZE/8)
|
||||
|
|
|
@ -1804,6 +1804,22 @@ static inline void gdt_setup_doublefault_tss(int cpu)
|
|||
}
|
||||
#endif /* !CONFIG_X86_64 */
|
||||
|
||||
static inline void tss_setup_io_bitmap(struct tss_struct *tss)
|
||||
{
|
||||
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
tss->io_bitmap.prev_max = 0;
|
||||
tss->io_bitmap.prev_sequence = 0;
|
||||
memset(tss->io_bitmap.bitmap, 0xff, sizeof(tss->io_bitmap.bitmap));
|
||||
/*
|
||||
* Invalidate the extra array entry past the end of the all
|
||||
* permission bitmap as required by the hardware.
|
||||
*/
|
||||
tss->io_bitmap.mapall[IO_BITMAP_LONGS] = ~0UL;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* cpu_init() initializes state that is per-CPU. Some data is already
|
||||
* initialized (naturally) in the bootstrap process, such as the GDT
|
||||
|
@ -1860,15 +1876,7 @@ void cpu_init(void)
|
|||
|
||||
/* Initialize the TSS. */
|
||||
tss_setup_ist(tss);
|
||||
tss->x86_tss.io_bitmap_base = IO_BITMAP_OFFSET_INVALID;
|
||||
tss->io_bitmap.prev_max = 0;
|
||||
tss->io_bitmap.prev_sequence = 0;
|
||||
memset(tss->io_bitmap.bitmap, 0xff, sizeof(tss->io_bitmap.bitmap));
|
||||
/*
|
||||
* Invalidate the extra array entry past the end of the all
|
||||
* permission bitmap as required by the hardware.
|
||||
*/
|
||||
tss->io_bitmap.mapall[IO_BITMAP_LONGS] = ~0UL;
|
||||
tss_setup_io_bitmap(tss);
|
||||
set_tss_desc(cpu, &get_cpu_entry_area(cpu)->tss.x86_tss);
|
||||
|
||||
load_TR_desc();
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include <asm/io_bitmap.h>
|
||||
#include <asm/desc.h>
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
|
||||
static atomic64_t io_bitmap_sequence;
|
||||
|
||||
void io_bitmap_share(struct task_struct *tsk)
|
||||
|
@ -172,13 +174,6 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
|
|||
struct thread_struct *t = ¤t->thread;
|
||||
unsigned int old;
|
||||
|
||||
/*
|
||||
* Careful: the IOPL bits in regs->flags are undefined under Xen PV
|
||||
* and changing them has no effect.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_X86_IOPL_NONE))
|
||||
return -ENOSYS;
|
||||
|
||||
if (level > 3)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -200,3 +195,20 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* CONFIG_X86_IOPL_IOPERM */
|
||||
|
||||
long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE1(iopl, unsigned int, level)
|
||||
{
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -322,6 +322,7 @@ void arch_setup_new_exec(void)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_IOPL_IOPERM
|
||||
static inline void tss_invalidate_io_bitmap(struct tss_struct *tss)
|
||||
{
|
||||
/*
|
||||
|
@ -409,6 +410,9 @@ void tss_update_io_bitmap(void)
|
|||
tss_invalidate_io_bitmap(tss);
|
||||
}
|
||||
}
|
||||
#else /* CONFIG_X86_IOPL_IOPERM */
|
||||
static inline void switch_to_bitmap(unsigned long tifp) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче