cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

tls.c (7125B)


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