Linux Audio

Check our new training course

Loading...
v3.15
  1#include <linux/kernel.h>
  2#include <linux/errno.h>
  3#include <linux/sched.h>
  4#include <linux/user.h>
  5#include <linux/regset.h>
  6#include <linux/syscalls.h>
  7
  8#include <asm/uaccess.h>
  9#include <asm/desc.h>
 10#include <asm/ldt.h>
 11#include <asm/processor.h>
 12#include <asm/proto.h>
 13
 14#include "tls.h"
 15
 16/*
 17 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
 18 */
 19static int get_free_idx(void)
 20{
 21	struct thread_struct *t = &current->thread;
 22	int idx;
 23
 24	for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
 25		if (desc_empty(&t->tls_array[idx]))
 26			return idx + GDT_ENTRY_TLS_MIN;
 27	return -ESRCH;
 28}
 29
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 30static void set_tls_desc(struct task_struct *p, int idx,
 31			 const struct user_desc *info, int n)
 32{
 33	struct thread_struct *t = &p->thread;
 34	struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
 35	int cpu;
 36
 37	/*
 38	 * We must not get preempted while modifying the TLS.
 39	 */
 40	cpu = get_cpu();
 41
 42	while (n-- > 0) {
 43		if (LDT_empty(info))
 44			desc->a = desc->b = 0;
 45		else
 46			fill_ldt(desc, info);
 47		++info;
 48		++desc;
 49	}
 50
 51	if (t == &current->thread)
 52		load_TLS(t, cpu);
 53
 54	put_cpu();
 55}
 56
 57/*
 58 * Set a given TLS descriptor:
 59 */
 60int do_set_thread_area(struct task_struct *p, int idx,
 61		       struct user_desc __user *u_info,
 62		       int can_allocate)
 63{
 64	struct user_desc info;
 
 65
 66	if (copy_from_user(&info, u_info, sizeof(info)))
 67		return -EFAULT;
 68
 
 
 
 69	if (idx == -1)
 70		idx = info.entry_number;
 71
 72	/*
 73	 * index -1 means the kernel should try to find and
 74	 * allocate an empty descriptor:
 75	 */
 76	if (idx == -1 && can_allocate) {
 77		idx = get_free_idx();
 78		if (idx < 0)
 79			return idx;
 80		if (put_user(idx, &u_info->entry_number))
 81			return -EFAULT;
 82	}
 83
 84	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
 85		return -EINVAL;
 86
 87	set_tls_desc(p, idx, &info, 1);
 88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 89	return 0;
 90}
 91
 92SYSCALL_DEFINE1(set_thread_area, struct user_desc __user *, u_info)
 93{
 94	return do_set_thread_area(current, -1, u_info, 1);
 95}
 96
 97
 98/*
 99 * Get the current Thread-Local Storage area:
100 */
101
102static void fill_user_desc(struct user_desc *info, int idx,
103			   const struct desc_struct *desc)
104
105{
106	memset(info, 0, sizeof(*info));
107	info->entry_number = idx;
108	info->base_addr = get_desc_base(desc);
109	info->limit = get_desc_limit(desc);
110	info->seg_32bit = desc->d;
111	info->contents = desc->type >> 2;
112	info->read_exec_only = !(desc->type & 2);
113	info->limit_in_pages = desc->g;
114	info->seg_not_present = !desc->p;
115	info->useable = desc->avl;
116#ifdef CONFIG_X86_64
117	info->lm = desc->l;
118#endif
119}
120
121int do_get_thread_area(struct task_struct *p, int idx,
122		       struct user_desc __user *u_info)
123{
124	struct user_desc info;
125
126	if (idx == -1 && get_user(idx, &u_info->entry_number))
127		return -EFAULT;
128
129	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
130		return -EINVAL;
131
132	fill_user_desc(&info, idx,
133		       &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
134
135	if (copy_to_user(u_info, &info, sizeof(info)))
136		return -EFAULT;
137	return 0;
138}
139
140SYSCALL_DEFINE1(get_thread_area, struct user_desc __user *, u_info)
141{
142	return do_get_thread_area(current, -1, u_info);
143}
144
145int regset_tls_active(struct task_struct *target,
146		      const struct user_regset *regset)
147{
148	struct thread_struct *t = &target->thread;
149	int n = GDT_ENTRY_TLS_ENTRIES;
150	while (n > 0 && desc_empty(&t->tls_array[n - 1]))
151		--n;
152	return n;
153}
154
155int regset_tls_get(struct task_struct *target, const struct user_regset *regset,
156		   unsigned int pos, unsigned int count,
157		   void *kbuf, void __user *ubuf)
158{
159	const struct desc_struct *tls;
160
161	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
162	    (pos % sizeof(struct user_desc)) != 0 ||
163	    (count % sizeof(struct user_desc)) != 0)
164		return -EINVAL;
165
166	pos /= sizeof(struct user_desc);
167	count /= sizeof(struct user_desc);
168
169	tls = &target->thread.tls_array[pos];
170
171	if (kbuf) {
172		struct user_desc *info = kbuf;
173		while (count-- > 0)
174			fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
175				       tls++);
176	} else {
177		struct user_desc __user *u_info = ubuf;
178		while (count-- > 0) {
179			struct user_desc info;
180			fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
181			if (__copy_to_user(u_info++, &info, sizeof(info)))
182				return -EFAULT;
183		}
184	}
185
186	return 0;
187}
188
189int regset_tls_set(struct task_struct *target, const struct user_regset *regset,
190		   unsigned int pos, unsigned int count,
191		   const void *kbuf, const void __user *ubuf)
192{
193	struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
194	const struct user_desc *info;
 
195
196	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
197	    (pos % sizeof(struct user_desc)) != 0 ||
198	    (count % sizeof(struct user_desc)) != 0)
199		return -EINVAL;
200
201	if (kbuf)
202		info = kbuf;
203	else if (__copy_from_user(infobuf, ubuf, count))
204		return -EFAULT;
205	else
206		info = infobuf;
 
 
 
 
207
208	set_tls_desc(target,
209		     GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)),
210		     info, count / sizeof(struct user_desc));
211
212	return 0;
213}
v4.10.11
  1#include <linux/kernel.h>
  2#include <linux/errno.h>
  3#include <linux/sched.h>
  4#include <linux/user.h>
  5#include <linux/regset.h>
  6#include <linux/syscalls.h>
  7
  8#include <linux/uaccess.h>
  9#include <asm/desc.h>
 10#include <asm/ldt.h>
 11#include <asm/processor.h>
 12#include <asm/proto.h>
 13
 14#include "tls.h"
 15
 16/*
 17 * sys_alloc_thread_area: get a yet unused TLS descriptor index.
 18 */
 19static int get_free_idx(void)
 20{
 21	struct thread_struct *t = &current->thread;
 22	int idx;
 23
 24	for (idx = 0; idx < GDT_ENTRY_TLS_ENTRIES; idx++)
 25		if (desc_empty(&t->tls_array[idx]))
 26			return idx + GDT_ENTRY_TLS_MIN;
 27	return -ESRCH;
 28}
 29
 30static bool tls_desc_okay(const struct user_desc *info)
 31{
 32	/*
 33	 * For historical reasons (i.e. no one ever documented how any
 34	 * of the segmentation APIs work), user programs can and do
 35	 * assume that a struct user_desc that's all zeros except for
 36	 * entry_number means "no segment at all".  This never actually
 37	 * worked.  In fact, up to Linux 3.19, a struct user_desc like
 38	 * this would create a 16-bit read-write segment with base and
 39	 * limit both equal to zero.
 40	 *
 41	 * That was close enough to "no segment at all" until we
 42	 * hardened this function to disallow 16-bit TLS segments.  Fix
 43	 * it up by interpreting these zeroed segments the way that they
 44	 * were almost certainly intended to be interpreted.
 45	 *
 46	 * The correct way to ask for "no segment at all" is to specify
 47	 * a user_desc that satisfies LDT_empty.  To keep everything
 48	 * working, we accept both.
 49	 *
 50	 * Note that there's a similar kludge in modify_ldt -- look at
 51	 * the distinction between modes 1 and 0x11.
 52	 */
 53	if (LDT_empty(info) || LDT_zero(info))
 54		return true;
 55
 56	/*
 57	 * espfix is required for 16-bit data segments, but espfix
 58	 * only works for LDT segments.
 59	 */
 60	if (!info->seg_32bit)
 61		return false;
 62
 63	/* Only allow data segments in the TLS array. */
 64	if (info->contents > 1)
 65		return false;
 66
 67	/*
 68	 * Non-present segments with DPL 3 present an interesting attack
 69	 * surface.  The kernel should handle such segments correctly,
 70	 * but TLS is very difficult to protect in a sandbox, so prevent
 71	 * such segments from being created.
 72	 *
 73	 * If userspace needs to remove a TLS entry, it can still delete
 74	 * it outright.
 75	 */
 76	if (info->seg_not_present)
 77		return false;
 78
 79	return true;
 80}
 81
 82static void set_tls_desc(struct task_struct *p, int idx,
 83			 const struct user_desc *info, int n)
 84{
 85	struct thread_struct *t = &p->thread;
 86	struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
 87	int cpu;
 88
 89	/*
 90	 * We must not get preempted while modifying the TLS.
 91	 */
 92	cpu = get_cpu();
 93
 94	while (n-- > 0) {
 95		if (LDT_empty(info) || LDT_zero(info))
 96			desc->a = desc->b = 0;
 97		else
 98			fill_ldt(desc, info);
 99		++info;
100		++desc;
101	}
102
103	if (t == &current->thread)
104		load_TLS(t, cpu);
105
106	put_cpu();
107}
108
109/*
110 * Set a given TLS descriptor:
111 */
112int do_set_thread_area(struct task_struct *p, int idx,
113		       struct user_desc __user *u_info,
114		       int can_allocate)
115{
116	struct user_desc info;
117	unsigned short __maybe_unused sel, modified_sel;
118
119	if (copy_from_user(&info, u_info, sizeof(info)))
120		return -EFAULT;
121
122	if (!tls_desc_okay(&info))
123		return -EINVAL;
124
125	if (idx == -1)
126		idx = info.entry_number;
127
128	/*
129	 * index -1 means the kernel should try to find and
130	 * allocate an empty descriptor:
131	 */
132	if (idx == -1 && can_allocate) {
133		idx = get_free_idx();
134		if (idx < 0)
135			return idx;
136		if (put_user(idx, &u_info->entry_number))
137			return -EFAULT;
138	}
139
140	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
141		return -EINVAL;
142
143	set_tls_desc(p, idx, &info, 1);
144
145	/*
146	 * If DS, ES, FS, or GS points to the modified segment, forcibly
147	 * refresh it.  Only needed on x86_64 because x86_32 reloads them
148	 * on return to user mode.
149	 */
150	modified_sel = (idx << 3) | 3;
151
152	if (p == current) {
153#ifdef CONFIG_X86_64
154		savesegment(ds, sel);
155		if (sel == modified_sel)
156			loadsegment(ds, sel);
157
158		savesegment(es, sel);
159		if (sel == modified_sel)
160			loadsegment(es, sel);
161
162		savesegment(fs, sel);
163		if (sel == modified_sel)
164			loadsegment(fs, sel);
165
166		savesegment(gs, sel);
167		if (sel == modified_sel)
168			load_gs_index(sel);
169#endif
170
171#ifdef CONFIG_X86_32_LAZY_GS
172		savesegment(gs, sel);
173		if (sel == modified_sel)
174			loadsegment(gs, sel);
175#endif
176	} else {
177#ifdef CONFIG_X86_64
178		if (p->thread.fsindex == modified_sel)
179			p->thread.fsbase = info.base_addr;
180
181		if (p->thread.gsindex == modified_sel)
182			p->thread.gsbase = info.base_addr;
183#endif
184	}
185
186	return 0;
187}
188
189SYSCALL_DEFINE1(set_thread_area, struct user_desc __user *, u_info)
190{
191	return do_set_thread_area(current, -1, u_info, 1);
192}
193
194
195/*
196 * Get the current Thread-Local Storage area:
197 */
198
199static void fill_user_desc(struct user_desc *info, int idx,
200			   const struct desc_struct *desc)
201
202{
203	memset(info, 0, sizeof(*info));
204	info->entry_number = idx;
205	info->base_addr = get_desc_base(desc);
206	info->limit = get_desc_limit(desc);
207	info->seg_32bit = desc->d;
208	info->contents = desc->type >> 2;
209	info->read_exec_only = !(desc->type & 2);
210	info->limit_in_pages = desc->g;
211	info->seg_not_present = !desc->p;
212	info->useable = desc->avl;
213#ifdef CONFIG_X86_64
214	info->lm = desc->l;
215#endif
216}
217
218int do_get_thread_area(struct task_struct *p, int idx,
219		       struct user_desc __user *u_info)
220{
221	struct user_desc info;
222
223	if (idx == -1 && get_user(idx, &u_info->entry_number))
224		return -EFAULT;
225
226	if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
227		return -EINVAL;
228
229	fill_user_desc(&info, idx,
230		       &p->thread.tls_array[idx - GDT_ENTRY_TLS_MIN]);
231
232	if (copy_to_user(u_info, &info, sizeof(info)))
233		return -EFAULT;
234	return 0;
235}
236
237SYSCALL_DEFINE1(get_thread_area, struct user_desc __user *, u_info)
238{
239	return do_get_thread_area(current, -1, u_info);
240}
241
242int regset_tls_active(struct task_struct *target,
243		      const struct user_regset *regset)
244{
245	struct thread_struct *t = &target->thread;
246	int n = GDT_ENTRY_TLS_ENTRIES;
247	while (n > 0 && desc_empty(&t->tls_array[n - 1]))
248		--n;
249	return n;
250}
251
252int regset_tls_get(struct task_struct *target, const struct user_regset *regset,
253		   unsigned int pos, unsigned int count,
254		   void *kbuf, void __user *ubuf)
255{
256	const struct desc_struct *tls;
257
258	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
259	    (pos % sizeof(struct user_desc)) != 0 ||
260	    (count % sizeof(struct user_desc)) != 0)
261		return -EINVAL;
262
263	pos /= sizeof(struct user_desc);
264	count /= sizeof(struct user_desc);
265
266	tls = &target->thread.tls_array[pos];
267
268	if (kbuf) {
269		struct user_desc *info = kbuf;
270		while (count-- > 0)
271			fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
272				       tls++);
273	} else {
274		struct user_desc __user *u_info = ubuf;
275		while (count-- > 0) {
276			struct user_desc info;
277			fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
278			if (__copy_to_user(u_info++, &info, sizeof(info)))
279				return -EFAULT;
280		}
281	}
282
283	return 0;
284}
285
286int regset_tls_set(struct task_struct *target, const struct user_regset *regset,
287		   unsigned int pos, unsigned int count,
288		   const void *kbuf, const void __user *ubuf)
289{
290	struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
291	const struct user_desc *info;
292	int i;
293
294	if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
295	    (pos % sizeof(struct user_desc)) != 0 ||
296	    (count % sizeof(struct user_desc)) != 0)
297		return -EINVAL;
298
299	if (kbuf)
300		info = kbuf;
301	else if (__copy_from_user(infobuf, ubuf, count))
302		return -EFAULT;
303	else
304		info = infobuf;
305
306	for (i = 0; i < count / sizeof(struct user_desc); i++)
307		if (!tls_desc_okay(info + i))
308			return -EINVAL;
309
310	set_tls_desc(target,
311		     GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)),
312		     info, count / sizeof(struct user_desc));
313
314	return 0;
315}