Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * This contains the io-permission bitmap code - written by obz, with changes
0004  * by Linus. 32/64 bits code unification by Miguel Botón.
0005  */
0006 #include <linux/capability.h>
0007 #include <linux/security.h>
0008 #include <linux/syscalls.h>
0009 #include <linux/bitmap.h>
0010 #include <linux/ioport.h>
0011 #include <linux/sched.h>
0012 #include <linux/slab.h>
0013 
0014 #include <asm/io_bitmap.h>
0015 #include <asm/desc.h>
0016 #include <asm/syscalls.h>
0017 
0018 #ifdef CONFIG_X86_IOPL_IOPERM
0019 
0020 static atomic64_t io_bitmap_sequence;
0021 
0022 void io_bitmap_share(struct task_struct *tsk)
0023 {
0024     /* Can be NULL when current->thread.iopl_emul == 3 */
0025     if (current->thread.io_bitmap) {
0026         /*
0027          * Take a refcount on current's bitmap. It can be used by
0028          * both tasks as long as none of them changes the bitmap.
0029          */
0030         refcount_inc(&current->thread.io_bitmap->refcnt);
0031         tsk->thread.io_bitmap = current->thread.io_bitmap;
0032     }
0033     set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
0034 }
0035 
0036 static void task_update_io_bitmap(struct task_struct *tsk)
0037 {
0038     struct thread_struct *t = &tsk->thread;
0039 
0040     if (t->iopl_emul == 3 || t->io_bitmap) {
0041         /* TSS update is handled on exit to user space */
0042         set_tsk_thread_flag(tsk, TIF_IO_BITMAP);
0043     } else {
0044         clear_tsk_thread_flag(tsk, TIF_IO_BITMAP);
0045         /* Invalidate TSS */
0046         preempt_disable();
0047         tss_update_io_bitmap();
0048         preempt_enable();
0049     }
0050 }
0051 
0052 void io_bitmap_exit(struct task_struct *tsk)
0053 {
0054     struct io_bitmap *iobm = tsk->thread.io_bitmap;
0055 
0056     tsk->thread.io_bitmap = NULL;
0057     task_update_io_bitmap(tsk);
0058     if (iobm && refcount_dec_and_test(&iobm->refcnt))
0059         kfree(iobm);
0060 }
0061 
0062 /*
0063  * This changes the io permissions bitmap in the current task.
0064  */
0065 long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
0066 {
0067     struct thread_struct *t = &current->thread;
0068     unsigned int i, max_long;
0069     struct io_bitmap *iobm;
0070 
0071     if ((from + num <= from) || (from + num > IO_BITMAP_BITS))
0072         return -EINVAL;
0073     if (turn_on && (!capable(CAP_SYS_RAWIO) ||
0074             security_locked_down(LOCKDOWN_IOPORT)))
0075         return -EPERM;
0076 
0077     /*
0078      * If it's the first ioperm() call in this thread's lifetime, set the
0079      * IO bitmap up. ioperm() is much less timing critical than clone(),
0080      * this is why we delay this operation until now:
0081      */
0082     iobm = t->io_bitmap;
0083     if (!iobm) {
0084         /* No point to allocate a bitmap just to clear permissions */
0085         if (!turn_on)
0086             return 0;
0087         iobm = kmalloc(sizeof(*iobm), GFP_KERNEL);
0088         if (!iobm)
0089             return -ENOMEM;
0090 
0091         memset(iobm->bitmap, 0xff, sizeof(iobm->bitmap));
0092         refcount_set(&iobm->refcnt, 1);
0093     }
0094 
0095     /*
0096      * If the bitmap is not shared, then nothing can take a refcount as
0097      * current can obviously not fork at the same time. If it's shared
0098      * duplicate it and drop the refcount on the original one.
0099      */
0100     if (refcount_read(&iobm->refcnt) > 1) {
0101         iobm = kmemdup(iobm, sizeof(*iobm), GFP_KERNEL);
0102         if (!iobm)
0103             return -ENOMEM;
0104         refcount_set(&iobm->refcnt, 1);
0105         io_bitmap_exit(current);
0106     }
0107 
0108     /*
0109      * Store the bitmap pointer (might be the same if the task already
0110      * head one). Must be done here so freeing the bitmap when all
0111      * permissions are dropped has the pointer set up.
0112      */
0113     t->io_bitmap = iobm;
0114     /* Mark it active for context switching and exit to user mode */
0115     set_thread_flag(TIF_IO_BITMAP);
0116 
0117     /*
0118      * Update the tasks bitmap. The update of the TSS bitmap happens on
0119      * exit to user mode. So this needs no protection.
0120      */
0121     if (turn_on)
0122         bitmap_clear(iobm->bitmap, from, num);
0123     else
0124         bitmap_set(iobm->bitmap, from, num);
0125 
0126     /*
0127      * Search for a (possibly new) maximum. This is simple and stupid,
0128      * to keep it obviously correct:
0129      */
0130     max_long = UINT_MAX;
0131     for (i = 0; i < IO_BITMAP_LONGS; i++) {
0132         if (iobm->bitmap[i] != ~0UL)
0133             max_long = i;
0134     }
0135     /* All permissions dropped? */
0136     if (max_long == UINT_MAX) {
0137         io_bitmap_exit(current);
0138         return 0;
0139     }
0140 
0141     iobm->max = (max_long + 1) * sizeof(unsigned long);
0142 
0143     /*
0144      * Update the sequence number to force a TSS update on return to
0145      * user mode.
0146      */
0147     iobm->sequence = atomic64_add_return(1, &io_bitmap_sequence);
0148 
0149     return 0;
0150 }
0151 
0152 SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
0153 {
0154     return ksys_ioperm(from, num, turn_on);
0155 }
0156 
0157 /*
0158  * The sys_iopl functionality depends on the level argument, which if
0159  * granted for the task is used to enable access to all 65536 I/O ports.
0160  *
0161  * This does not use the IOPL mechanism provided by the CPU as that would
0162  * also allow the user space task to use the CLI/STI instructions.
0163  *
0164  * Disabling interrupts in a user space task is dangerous as it might lock
0165  * up the machine and the semantics vs. syscalls and exceptions is
0166  * undefined.
0167  *
0168  * Setting IOPL to level 0-2 is disabling I/O permissions. Level 3
0169  * 3 enables them.
0170  *
0171  * IOPL is strictly per thread and inherited on fork.
0172  */
0173 SYSCALL_DEFINE1(iopl, unsigned int, level)
0174 {
0175     struct thread_struct *t = &current->thread;
0176     unsigned int old;
0177 
0178     if (level > 3)
0179         return -EINVAL;
0180 
0181     old = t->iopl_emul;
0182 
0183     /* No point in going further if nothing changes */
0184     if (level == old)
0185         return 0;
0186 
0187     /* Trying to gain more privileges? */
0188     if (level > old) {
0189         if (!capable(CAP_SYS_RAWIO) ||
0190             security_locked_down(LOCKDOWN_IOPORT))
0191             return -EPERM;
0192     }
0193 
0194     t->iopl_emul = level;
0195     task_update_io_bitmap(current);
0196 
0197     return 0;
0198 }
0199 
0200 #else /* CONFIG_X86_IOPL_IOPERM */
0201 
0202 long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
0203 {
0204     return -ENOSYS;
0205 }
0206 SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
0207 {
0208     return -ENOSYS;
0209 }
0210 
0211 SYSCALL_DEFINE1(iopl, unsigned int, level)
0212 {
0213     return -ENOSYS;
0214 }
0215 #endif