forked from intel/linux-sgx-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathisgx_compat_ioctl.c
173 lines (143 loc) · 4.5 KB
/
isgx_compat_ioctl.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
* (C) Copyright 2015 Intel Corporation
*
* Authors:
*
* Jarkko Sakkinen <[email protected]>
* Suresh Siddha <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License.
*/
#include "isgx.h"
#include <linux/acpi.h>
#include <linux/compat.h>
#include <linux/miscdevice.h>
#include <linux/module.h>
#include <linux/suspend.h>
#define ISGX32_IOCTL_ENCLAVE_CREATE _IOWR('p', 0x02, struct isgx_create_param32)
#define ISGX32_IOCTL_ENCLAVE_ADD_PAGE _IOW('p', 0x03, struct isgx_add_param32)
#define ISGX32_IOCTL_ENCLAVE_INIT _IOW('p', 0x04, struct isgx_init_param32)
#define ISGX32_IOCTL_ENCLAVE_DESTROY _IOW('p', 0x06, struct isgx_destroy_param32)
struct isgx_create_param32 {
u32 secs;
u32 addr;
};
static long enclave_create_compat(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct isgx_create_param32 create_param32;
struct isgx_create_param *create_param;
unsigned long addr;
int ret;
if (copy_from_user(&create_param32, (void *) arg,
sizeof(create_param32)))
return -EFAULT;
create_param = compat_alloc_user_space(sizeof(*create_param));
if (!create_param
|| __put_user((void __user *) (unsigned long) create_param32.secs,
&create_param->secs))
return -EFAULT;
ret = isgx_ioctl(filep, ISGX_IOCTL_ENCLAVE_CREATE,
(unsigned long) create_param);
if (ret)
return ret;
if (__get_user(addr, &create_param->addr))
return -EFAULT;
create_param32.addr = addr;
if (copy_to_user((void *) arg, &create_param32, sizeof(create_param32)))
return -EFAULT;
return 0;
}
struct isgx_add_param32 {
u32 addr;
u32 user_addr;
u32 secinfo;
u32 flags;
};
static long enclave_add_page_compat(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct isgx_add_param32 add_param32;
struct isgx_add_param *add_param;
if (copy_from_user(&add_param32, (void *) arg,
sizeof(add_param32)))
return -EFAULT;
add_param = compat_alloc_user_space(sizeof(*add_param));
if (!add_param)
return -EFAULT;
if (__put_user((unsigned long) add_param32.addr,
&add_param->addr) ||
__put_user((unsigned long) add_param32.user_addr,
&add_param->user_addr) ||
__put_user((unsigned long) add_param32.secinfo,
&add_param->secinfo) ||
__put_user((unsigned long) add_param32.flags,
&add_param->flags))
return -EFAULT;
return isgx_ioctl(filep, ISGX_IOCTL_ENCLAVE_ADD_PAGE,
(unsigned long) add_param);
}
struct isgx_init_param32 {
u32 addr;
u32 sigstruct;
u32 einittoken;
};
static long enclave_init_compat(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct isgx_init_param32 init_param32;
struct isgx_init_param *init_param;
if (copy_from_user(&init_param32, (void *) arg,
sizeof(init_param32)))
return -EFAULT;
init_param = compat_alloc_user_space(sizeof(*init_param));
if (!init_param)
return -EFAULT;
if (__put_user((void __user *) (unsigned long)init_param32.addr,
&init_param->addr) ||
__put_user((void __user *) (unsigned long)init_param32.sigstruct,
&init_param->sigstruct) ||
__put_user((void __user *) (unsigned long)init_param32.einittoken,
&init_param->einittoken))
return -EFAULT;
return isgx_ioctl(filep, ISGX_IOCTL_ENCLAVE_INIT,
(unsigned long) init_param);
}
struct isgx_destroy_param32 {
u32 addr;
};
static long enclave_destroy_compat(struct file *filep, unsigned int cmd,
unsigned long arg)
{
struct isgx_destroy_param32 destroy_param32;
struct isgx_destroy_param *destroy_param;
if (copy_from_user(&destroy_param32, (void *) arg,
sizeof(destroy_param32)))
return -EFAULT;
destroy_param = compat_alloc_user_space(sizeof(*destroy_param));
if (!destroy_param)
return -EFAULT;
if (__put_user((void __user *) (unsigned long) destroy_param32.addr,
&destroy_param->addr))
return -EFAULT;
return isgx_ioctl(filep, ISGX_IOCTL_ENCLAVE_DESTROY,
(unsigned long) destroy_param);
}
long isgx_compat_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
switch (cmd) {
case ISGX32_IOCTL_ENCLAVE_CREATE:
return enclave_create_compat(filep, cmd, arg);
case ISGX32_IOCTL_ENCLAVE_ADD_PAGE:
return enclave_add_page_compat(filep, cmd, arg);
case ISGX32_IOCTL_ENCLAVE_INIT:
return enclave_init_compat(filep, cmd, arg);
case ISGX32_IOCTL_ENCLAVE_DESTROY:
return enclave_destroy_compat(filep, cmd, arg);
default:
return -EINVAL;
}
}