Commit 111e7b15 authored by Thomas Gleixner's avatar Thomas Gleixner
Browse files

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: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent a24ca997
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -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
+8 −1
Original line number Diff line number Diff line
@@ -340,6 +340,7 @@ 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.
@@ -347,6 +348,10 @@ struct x86_hw_tss {
# 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);
+6 −1
Original line number Diff line number Diff line
@@ -156,8 +156,13 @@ struct thread_info {
# define _TIF_WORK_CTXSW	(_TIF_WORK_CTXSW_BASE)
#endif

#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)
+17 −9
Original line number Diff line number Diff line
@@ -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();
Loading