1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* |
3 | * This contains the io-permission bitmap code - written by obz, with changes |
4 | * by Linus. 32/64 bits code unification by Miguel Botón. |
5 | */ |
6 | #include <linux/capability.h> |
7 | #include <linux/security.h> |
8 | #include <linux/syscalls.h> |
9 | #include <linux/bitmap.h> |
10 | #include <linux/ioport.h> |
11 | #include <linux/sched.h> |
12 | #include <linux/slab.h> |
13 | |
14 | #include <asm/io_bitmap.h> |
15 | #include <asm/desc.h> |
16 | #include <asm/syscalls.h> |
17 | |
18 | #ifdef CONFIG_X86_IOPL_IOPERM |
19 | |
20 | static atomic64_t io_bitmap_sequence; |
21 | |
22 | void io_bitmap_share(struct task_struct *tsk) |
23 | { |
24 | /* Can be NULL when current->thread.iopl_emul == 3 */ |
25 | if (current->thread.io_bitmap) { |
26 | /* |
27 | * Take a refcount on current's bitmap. It can be used by |
28 | * both tasks as long as none of them changes the bitmap. |
29 | */ |
30 | refcount_inc(r: ¤t->thread.io_bitmap->refcnt); |
31 | tsk->thread.io_bitmap = current->thread.io_bitmap; |
32 | } |
33 | set_tsk_thread_flag(tsk, TIF_IO_BITMAP); |
34 | } |
35 | |
36 | static void task_update_io_bitmap(struct task_struct *tsk) |
37 | { |
38 | struct thread_struct *t = &tsk->thread; |
39 | |
40 | if (t->iopl_emul == 3 || t->io_bitmap) { |
41 | /* TSS update is handled on exit to user space */ |
42 | set_tsk_thread_flag(tsk, TIF_IO_BITMAP); |
43 | } else { |
44 | clear_tsk_thread_flag(tsk, TIF_IO_BITMAP); |
45 | /* Invalidate TSS */ |
46 | preempt_disable(); |
47 | tss_update_io_bitmap(); |
48 | preempt_enable(); |
49 | } |
50 | } |
51 | |
52 | void io_bitmap_exit(struct task_struct *tsk) |
53 | { |
54 | struct io_bitmap *iobm = tsk->thread.io_bitmap; |
55 | |
56 | tsk->thread.io_bitmap = NULL; |
57 | task_update_io_bitmap(tsk); |
58 | if (iobm && refcount_dec_and_test(r: &iobm->refcnt)) |
59 | kfree(objp: iobm); |
60 | } |
61 | |
62 | /* |
63 | * This changes the io permissions bitmap in the current task. |
64 | */ |
65 | long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) |
66 | { |
67 | struct thread_struct *t = ¤t->thread; |
68 | unsigned int i, max_long; |
69 | struct io_bitmap *iobm; |
70 | |
71 | if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) |
72 | return -EINVAL; |
73 | if (turn_on && (!capable(CAP_SYS_RAWIO) || |
74 | security_locked_down(what: LOCKDOWN_IOPORT))) |
75 | return -EPERM; |
76 | |
77 | /* |
78 | * If it's the first ioperm() call in this thread's lifetime, set the |
79 | * IO bitmap up. ioperm() is much less timing critical than clone(), |
80 | * this is why we delay this operation until now: |
81 | */ |
82 | iobm = t->io_bitmap; |
83 | if (!iobm) { |
84 | /* No point to allocate a bitmap just to clear permissions */ |
85 | if (!turn_on) |
86 | return 0; |
87 | iobm = kmalloc(size: sizeof(*iobm), GFP_KERNEL); |
88 | if (!iobm) |
89 | return -ENOMEM; |
90 | |
91 | memset(iobm->bitmap, 0xff, sizeof(iobm->bitmap)); |
92 | refcount_set(r: &iobm->refcnt, n: 1); |
93 | } |
94 | |
95 | /* |
96 | * If the bitmap is not shared, then nothing can take a refcount as |
97 | * current can obviously not fork at the same time. If it's shared |
98 | * duplicate it and drop the refcount on the original one. |
99 | */ |
100 | if (refcount_read(r: &iobm->refcnt) > 1) { |
101 | iobm = kmemdup(p: iobm, size: sizeof(*iobm), GFP_KERNEL); |
102 | if (!iobm) |
103 | return -ENOMEM; |
104 | refcount_set(r: &iobm->refcnt, n: 1); |
105 | io_bitmap_exit(current); |
106 | } |
107 | |
108 | /* |
109 | * Store the bitmap pointer (might be the same if the task already |
110 | * head one). Must be done here so freeing the bitmap when all |
111 | * permissions are dropped has the pointer set up. |
112 | */ |
113 | t->io_bitmap = iobm; |
114 | /* Mark it active for context switching and exit to user mode */ |
115 | set_thread_flag(TIF_IO_BITMAP); |
116 | |
117 | /* |
118 | * Update the tasks bitmap. The update of the TSS bitmap happens on |
119 | * exit to user mode. So this needs no protection. |
120 | */ |
121 | if (turn_on) |
122 | bitmap_clear(map: iobm->bitmap, start: from, nbits: num); |
123 | else |
124 | bitmap_set(map: iobm->bitmap, start: from, nbits: num); |
125 | |
126 | /* |
127 | * Search for a (possibly new) maximum. This is simple and stupid, |
128 | * to keep it obviously correct: |
129 | */ |
130 | max_long = UINT_MAX; |
131 | for (i = 0; i < IO_BITMAP_LONGS; i++) { |
132 | if (iobm->bitmap[i] != ~0UL) |
133 | max_long = i; |
134 | } |
135 | /* All permissions dropped? */ |
136 | if (max_long == UINT_MAX) { |
137 | io_bitmap_exit(current); |
138 | return 0; |
139 | } |
140 | |
141 | iobm->max = (max_long + 1) * sizeof(unsigned long); |
142 | |
143 | /* |
144 | * Update the sequence number to force a TSS update on return to |
145 | * user mode. |
146 | */ |
147 | iobm->sequence = atomic64_add_return(i: 1, v: &io_bitmap_sequence); |
148 | |
149 | return 0; |
150 | } |
151 | |
152 | SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on) |
153 | { |
154 | return ksys_ioperm(from, num, turn_on); |
155 | } |
156 | |
157 | /* |
158 | * The sys_iopl functionality depends on the level argument, which if |
159 | * granted for the task is used to enable access to all 65536 I/O ports. |
160 | * |
161 | * This does not use the IOPL mechanism provided by the CPU as that would |
162 | * also allow the user space task to use the CLI/STI instructions. |
163 | * |
164 | * Disabling interrupts in a user space task is dangerous as it might lock |
165 | * up the machine and the semantics vs. syscalls and exceptions is |
166 | * undefined. |
167 | * |
168 | * Setting IOPL to level 0-2 is disabling I/O permissions. Level 3 |
169 | * 3 enables them. |
170 | * |
171 | * IOPL is strictly per thread and inherited on fork. |
172 | */ |
173 | SYSCALL_DEFINE1(iopl, unsigned int, level) |
174 | { |
175 | struct thread_struct *t = ¤t->thread; |
176 | unsigned int old; |
177 | |
178 | if (level > 3) |
179 | return -EINVAL; |
180 | |
181 | old = t->iopl_emul; |
182 | |
183 | /* No point in going further if nothing changes */ |
184 | if (level == old) |
185 | return 0; |
186 | |
187 | /* Trying to gain more privileges? */ |
188 | if (level > old) { |
189 | if (!capable(CAP_SYS_RAWIO) || |
190 | security_locked_down(what: LOCKDOWN_IOPORT)) |
191 | return -EPERM; |
192 | } |
193 | |
194 | t->iopl_emul = level; |
195 | task_update_io_bitmap(current); |
196 | |
197 | return 0; |
198 | } |
199 | |
200 | #else /* CONFIG_X86_IOPL_IOPERM */ |
201 | |
202 | long ksys_ioperm(unsigned long from, unsigned long num, int turn_on) |
203 | { |
204 | return -ENOSYS; |
205 | } |
206 | SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on) |
207 | { |
208 | return -ENOSYS; |
209 | } |
210 | |
211 | SYSCALL_DEFINE1(iopl, unsigned int, level) |
212 | { |
213 | return -ENOSYS; |
214 | } |
215 | #endif |
216 | |