0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/sched.h>
0012 #include <linux/uaccess.h>
0013 #include <linux/syscalls.h>
0014 #include <linux/rseq.h>
0015 #include <linux/types.h>
0016 #include <asm/ptrace.h>
0017
0018 #define CREATE_TRACE_POINTS
0019 #include <trace/events/rseq.h>
0020
0021 #define RSEQ_CS_NO_RESTART_FLAGS (RSEQ_CS_FLAG_NO_RESTART_ON_PREEMPT | \
0022 RSEQ_CS_FLAG_NO_RESTART_ON_SIGNAL | \
0023 RSEQ_CS_FLAG_NO_RESTART_ON_MIGRATE)
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085 static int rseq_update_cpu_id(struct task_struct *t)
0086 {
0087 u32 cpu_id = raw_smp_processor_id();
0088 struct rseq __user *rseq = t->rseq;
0089
0090 if (!user_write_access_begin(rseq, sizeof(*rseq)))
0091 goto efault;
0092 unsafe_put_user(cpu_id, &rseq->cpu_id_start, efault_end);
0093 unsafe_put_user(cpu_id, &rseq->cpu_id, efault_end);
0094 user_write_access_end();
0095 trace_rseq_update(t);
0096 return 0;
0097
0098 efault_end:
0099 user_write_access_end();
0100 efault:
0101 return -EFAULT;
0102 }
0103
0104 static int rseq_reset_rseq_cpu_id(struct task_struct *t)
0105 {
0106 u32 cpu_id_start = 0, cpu_id = RSEQ_CPU_ID_UNINITIALIZED;
0107
0108
0109
0110
0111 if (put_user(cpu_id_start, &t->rseq->cpu_id_start))
0112 return -EFAULT;
0113
0114
0115
0116
0117
0118 if (put_user(cpu_id, &t->rseq->cpu_id))
0119 return -EFAULT;
0120 return 0;
0121 }
0122
0123 static int rseq_get_rseq_cs(struct task_struct *t, struct rseq_cs *rseq_cs)
0124 {
0125 struct rseq_cs __user *urseq_cs;
0126 u64 ptr;
0127 u32 __user *usig;
0128 u32 sig;
0129 int ret;
0130
0131 #ifdef CONFIG_64BIT
0132 if (get_user(ptr, &t->rseq->rseq_cs))
0133 return -EFAULT;
0134 #else
0135 if (copy_from_user(&ptr, &t->rseq->rseq_cs, sizeof(ptr)))
0136 return -EFAULT;
0137 #endif
0138 if (!ptr) {
0139 memset(rseq_cs, 0, sizeof(*rseq_cs));
0140 return 0;
0141 }
0142 if (ptr >= TASK_SIZE)
0143 return -EINVAL;
0144 urseq_cs = (struct rseq_cs __user *)(unsigned long)ptr;
0145 if (copy_from_user(rseq_cs, urseq_cs, sizeof(*rseq_cs)))
0146 return -EFAULT;
0147
0148 if (rseq_cs->start_ip >= TASK_SIZE ||
0149 rseq_cs->start_ip + rseq_cs->post_commit_offset >= TASK_SIZE ||
0150 rseq_cs->abort_ip >= TASK_SIZE ||
0151 rseq_cs->version > 0)
0152 return -EINVAL;
0153
0154 if (rseq_cs->start_ip + rseq_cs->post_commit_offset < rseq_cs->start_ip)
0155 return -EINVAL;
0156
0157 if (rseq_cs->abort_ip - rseq_cs->start_ip < rseq_cs->post_commit_offset)
0158 return -EINVAL;
0159
0160 usig = (u32 __user *)(unsigned long)(rseq_cs->abort_ip - sizeof(u32));
0161 ret = get_user(sig, usig);
0162 if (ret)
0163 return ret;
0164
0165 if (current->rseq_sig != sig) {
0166 printk_ratelimited(KERN_WARNING
0167 "Possible attack attempt. Unexpected rseq signature 0x%x, expecting 0x%x (pid=%d, addr=%p).\n",
0168 sig, current->rseq_sig, current->pid, usig);
0169 return -EINVAL;
0170 }
0171 return 0;
0172 }
0173
0174 static int rseq_need_restart(struct task_struct *t, u32 cs_flags)
0175 {
0176 u32 flags, event_mask;
0177 int ret;
0178
0179 if (WARN_ON_ONCE(cs_flags & RSEQ_CS_NO_RESTART_FLAGS) || cs_flags)
0180 return -EINVAL;
0181
0182
0183 ret = get_user(flags, &t->rseq->flags);
0184 if (ret)
0185 return ret;
0186
0187 if (WARN_ON_ONCE(flags & RSEQ_CS_NO_RESTART_FLAGS) || flags)
0188 return -EINVAL;
0189
0190
0191
0192
0193
0194 preempt_disable();
0195 event_mask = t->rseq_event_mask;
0196 t->rseq_event_mask = 0;
0197 preempt_enable();
0198
0199 return !!event_mask;
0200 }
0201
0202 static int clear_rseq_cs(struct task_struct *t)
0203 {
0204
0205
0206
0207
0208
0209
0210
0211
0212 #ifdef CONFIG_64BIT
0213 return put_user(0UL, &t->rseq->rseq_cs);
0214 #else
0215 if (clear_user(&t->rseq->rseq_cs, sizeof(t->rseq->rseq_cs)))
0216 return -EFAULT;
0217 return 0;
0218 #endif
0219 }
0220
0221
0222
0223
0224
0225 static bool in_rseq_cs(unsigned long ip, struct rseq_cs *rseq_cs)
0226 {
0227 return ip - rseq_cs->start_ip < rseq_cs->post_commit_offset;
0228 }
0229
0230 static int rseq_ip_fixup(struct pt_regs *regs)
0231 {
0232 unsigned long ip = instruction_pointer(regs);
0233 struct task_struct *t = current;
0234 struct rseq_cs rseq_cs;
0235 int ret;
0236
0237 ret = rseq_get_rseq_cs(t, &rseq_cs);
0238 if (ret)
0239 return ret;
0240
0241
0242
0243
0244
0245
0246 if (!in_rseq_cs(ip, &rseq_cs))
0247 return clear_rseq_cs(t);
0248 ret = rseq_need_restart(t, rseq_cs.flags);
0249 if (ret <= 0)
0250 return ret;
0251 ret = clear_rseq_cs(t);
0252 if (ret)
0253 return ret;
0254 trace_rseq_ip_fixup(ip, rseq_cs.start_ip, rseq_cs.post_commit_offset,
0255 rseq_cs.abort_ip);
0256 instruction_pointer_set(regs, (unsigned long)rseq_cs.abort_ip);
0257 return 0;
0258 }
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271 void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
0272 {
0273 struct task_struct *t = current;
0274 int ret, sig;
0275
0276 if (unlikely(t->flags & PF_EXITING))
0277 return;
0278
0279
0280
0281
0282
0283
0284 if (regs) {
0285 ret = rseq_ip_fixup(regs);
0286 if (unlikely(ret < 0))
0287 goto error;
0288 }
0289 if (unlikely(rseq_update_cpu_id(t)))
0290 goto error;
0291 return;
0292
0293 error:
0294 sig = ksig ? ksig->sig : 0;
0295 force_sigsegv(sig);
0296 }
0297
0298 #ifdef CONFIG_DEBUG_RSEQ
0299
0300
0301
0302
0303
0304 void rseq_syscall(struct pt_regs *regs)
0305 {
0306 unsigned long ip = instruction_pointer(regs);
0307 struct task_struct *t = current;
0308 struct rseq_cs rseq_cs;
0309
0310 if (!t->rseq)
0311 return;
0312 if (rseq_get_rseq_cs(t, &rseq_cs) || in_rseq_cs(ip, &rseq_cs))
0313 force_sig(SIGSEGV);
0314 }
0315
0316 #endif
0317
0318
0319
0320
0321 SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len,
0322 int, flags, u32, sig)
0323 {
0324 int ret;
0325
0326 if (flags & RSEQ_FLAG_UNREGISTER) {
0327 if (flags & ~RSEQ_FLAG_UNREGISTER)
0328 return -EINVAL;
0329
0330 if (current->rseq != rseq || !current->rseq)
0331 return -EINVAL;
0332 if (rseq_len != sizeof(*rseq))
0333 return -EINVAL;
0334 if (current->rseq_sig != sig)
0335 return -EPERM;
0336 ret = rseq_reset_rseq_cpu_id(current);
0337 if (ret)
0338 return ret;
0339 current->rseq = NULL;
0340 current->rseq_sig = 0;
0341 return 0;
0342 }
0343
0344 if (unlikely(flags))
0345 return -EINVAL;
0346
0347 if (current->rseq) {
0348
0349
0350
0351
0352
0353 if (current->rseq != rseq || rseq_len != sizeof(*rseq))
0354 return -EINVAL;
0355 if (current->rseq_sig != sig)
0356 return -EPERM;
0357
0358 return -EBUSY;
0359 }
0360
0361
0362
0363
0364
0365 if (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) ||
0366 rseq_len != sizeof(*rseq))
0367 return -EINVAL;
0368 if (!access_ok(rseq, rseq_len))
0369 return -EFAULT;
0370 current->rseq = rseq;
0371 current->rseq_sig = sig;
0372
0373
0374
0375
0376
0377 rseq_set_notify_resume(current);
0378
0379 return 0;
0380 }