1 /* 2 * Yama Linux Security Module 3 * 4 * Author: Kees Cook <keescook@chromium.org> 5 * 6 * Copyright (C) 2010 Canonical, Ltd. 7 * Copyright (C) 2011 The Chromium OS Authors. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2, as 11 * published by the Free Software Foundation. 12 * 13 */ 14 15 #include <linux/security.h> 16 #include <linux/sysctl.h> 17 #include <linux/ptrace.h> 18 #include <linux/prctl.h> 19 #include <linux/ratelimit.h> 20 21 static int ptrace_scope = 1; 22 23 /* describe a ptrace relationship for potential exception */ 24 struct ptrace_relation { 25 struct task_struct *tracer; 26 struct task_struct *tracee; 27 struct list_head node; 28 }; 29 30 static LIST_HEAD(ptracer_relations); 31 static DEFINE_SPINLOCK(ptracer_relations_lock); 32 33 /** 34 * yama_ptracer_add - add/replace an exception for this tracer/tracee pair 35 * @tracer: the task_struct of the process doing the ptrace 36 * @tracee: the task_struct of the process to be ptraced 37 * 38 * Each tracee can have, at most, one tracer registered. Each time this 39 * is called, the prior registered tracer will be replaced for the tracee. 40 * 41 * Returns 0 if relationship was added, -ve on error. 42 */ 43 static int yama_ptracer_add(struct task_struct *tracer, 44 struct task_struct *tracee) 45 { 46 int rc = 0; 47 struct ptrace_relation *added; 48 struct ptrace_relation *entry, *relation = NULL; 49 50 added = kmalloc(sizeof(*added), GFP_KERNEL); 51 if (!added) 52 return -ENOMEM; 53 54 spin_lock_bh(&ptracer_relations_lock); 55 list_for_each_entry(entry, &ptracer_relations, node) 56 if (entry->tracee == tracee) { 57 relation = entry; 58 break; 59 } 60 if (!relation) { 61 relation = added; 62 relation->tracee = tracee; 63 list_add(&relation->node, &ptracer_relations); 64 } 65 relation->tracer = tracer; 66 67 spin_unlock_bh(&ptracer_relations_lock); 68 if (added != relation) 69 kfree(added); 70 71 return rc; 72 } 73 74 /** 75 * yama_ptracer_del - remove exceptions related to the given tasks 76 * @tracer: remove any relation where tracer task matches 77 * @tracee: remove any relation where tracee task matches 78 */ 79 static void yama_ptracer_del(struct task_struct *tracer, 80 struct task_struct *tracee) 81 { 82 struct ptrace_relation *relation, *safe; 83 84 spin_lock_bh(&ptracer_relations_lock); 85 list_for_each_entry_safe(relation, safe, &ptracer_relations, node) 86 if (relation->tracee == tracee || 87 (tracer && relation->tracer == tracer)) { 88 list_del(&relation->node); 89 kfree(relation); 90 } 91 spin_unlock_bh(&ptracer_relations_lock); 92 } 93 94 /** 95 * yama_task_free - check for task_pid to remove from exception list 96 * @task: task being removed 97 */ 98 static void yama_task_free(struct task_struct *task) 99 { 100 yama_ptracer_del(task, task); 101 } 102 103 /** 104 * yama_task_prctl - check for Yama-specific prctl operations 105 * @option: operation 106 * @arg2: argument 107 * @arg3: argument 108 * @arg4: argument 109 * @arg5: argument 110 * 111 * Return 0 on success, -ve on error. -ENOSYS is returned when Yama 112 * does not handle the given option. 113 */ 114 static int yama_task_prctl(int option, unsigned long arg2, unsigned long arg3, 115 unsigned long arg4, unsigned long arg5) 116 { 117 int rc; 118 struct task_struct *myself = current; 119 120 rc = cap_task_prctl(option, arg2, arg3, arg4, arg5); 121 if (rc != -ENOSYS) 122 return rc; 123 124 switch (option) { 125 case PR_SET_PTRACER: 126 /* Since a thread can call prctl(), find the group leader 127 * before calling _add() or _del() on it, since we want 128 * process-level granularity of control. The tracer group 129 * leader checking is handled later when walking the ancestry 130 * at the time of PTRACE_ATTACH check. 131 */ 132 rcu_read_lock(); 133 if (!thread_group_leader(myself)) 134 myself = rcu_dereference(myself->group_leader); 135 get_task_struct(myself); 136 rcu_read_unlock(); 137 138 if (arg2 == 0) { 139 yama_ptracer_del(NULL, myself); 140 rc = 0; 141 } else if (arg2 == PR_SET_PTRACER_ANY) { 142 rc = yama_ptracer_add(NULL, myself); 143 } else { 144 struct task_struct *tracer; 145 146 rcu_read_lock(); 147 tracer = find_task_by_vpid(arg2); 148 if (tracer) 149 get_task_struct(tracer); 150 else 151 rc = -EINVAL; 152 rcu_read_unlock(); 153 154 if (tracer) { 155 rc = yama_ptracer_add(tracer, myself); 156 put_task_struct(tracer); 157 } 158 } 159 160 put_task_struct(myself); 161 break; 162 } 163 164 return rc; 165 } 166 167 /** 168 * task_is_descendant - walk up a process family tree looking for a match 169 * @parent: the process to compare against while walking up from child 170 * @child: the process to start from while looking upwards for parent 171 * 172 * Returns 1 if child is a descendant of parent, 0 if not. 173 */ 174 static int task_is_descendant(struct task_struct *parent, 175 struct task_struct *child) 176 { 177 int rc = 0; 178 struct task_struct *walker = child; 179 180 if (!parent || !child) 181 return 0; 182 183 rcu_read_lock(); 184 if (!thread_group_leader(parent)) 185 parent = rcu_dereference(parent->group_leader); 186 while (walker->pid > 0) { 187 if (!thread_group_leader(walker)) 188 walker = rcu_dereference(walker->group_leader); 189 if (walker == parent) { 190 rc = 1; 191 break; 192 } 193 walker = rcu_dereference(walker->real_parent); 194 } 195 rcu_read_unlock(); 196 197 return rc; 198 } 199 200 /** 201 * ptracer_exception_found - tracer registered as exception for this tracee 202 * @tracer: the task_struct of the process attempting ptrace 203 * @tracee: the task_struct of the process to be ptraced 204 * 205 * Returns 1 if tracer has is ptracer exception ancestor for tracee. 206 */ 207 static int ptracer_exception_found(struct task_struct *tracer, 208 struct task_struct *tracee) 209 { 210 int rc = 0; 211 struct ptrace_relation *relation; 212 struct task_struct *parent = NULL; 213 bool found = false; 214 215 spin_lock_bh(&ptracer_relations_lock); 216 rcu_read_lock(); 217 if (!thread_group_leader(tracee)) 218 tracee = rcu_dereference(tracee->group_leader); 219 list_for_each_entry(relation, &ptracer_relations, node) 220 if (relation->tracee == tracee) { 221 parent = relation->tracer; 222 found = true; 223 break; 224 } 225 226 if (found && (parent == NULL || task_is_descendant(parent, tracer))) 227 rc = 1; 228 rcu_read_unlock(); 229 spin_unlock_bh(&ptracer_relations_lock); 230 231 return rc; 232 } 233 234 /** 235 * yama_ptrace_access_check - validate PTRACE_ATTACH calls 236 * @child: task that current task is attempting to ptrace 237 * @mode: ptrace attach mode 238 * 239 * Returns 0 if following the ptrace is allowed, -ve on error. 240 */ 241 static int yama_ptrace_access_check(struct task_struct *child, 242 unsigned int mode) 243 { 244 int rc; 245 246 /* If standard caps disallows it, so does Yama. We should 247 * only tighten restrictions further. 248 */ 249 rc = cap_ptrace_access_check(child, mode); 250 if (rc) 251 return rc; 252 253 /* require ptrace target be a child of ptracer on attach */ 254 if (mode == PTRACE_MODE_ATTACH && 255 ptrace_scope && 256 !task_is_descendant(current, child) && 257 !ptracer_exception_found(current, child) && 258 !capable(CAP_SYS_PTRACE)) 259 rc = -EPERM; 260 261 if (rc) { 262 char name[sizeof(current->comm)]; 263 printk_ratelimited(KERN_NOTICE "ptrace of non-child" 264 " pid %d was attempted by: %s (pid %d)\n", 265 child->pid, 266 get_task_comm(name, current), 267 current->pid); 268 } 269 270 return rc; 271 } 272 273 static struct security_operations yama_ops = { 274 .name = "yama", 275 276 .ptrace_access_check = yama_ptrace_access_check, 277 .task_prctl = yama_task_prctl, 278 .task_free = yama_task_free, 279 }; 280 281 #ifdef CONFIG_SYSCTL 282 static int zero; 283 static int one = 1; 284 285 struct ctl_path yama_sysctl_path[] = { 286 { .procname = "kernel", }, 287 { .procname = "yama", }, 288 { } 289 }; 290 291 static struct ctl_table yama_sysctl_table[] = { 292 { 293 .procname = "ptrace_scope", 294 .data = &ptrace_scope, 295 .maxlen = sizeof(int), 296 .mode = 0644, 297 .proc_handler = proc_dointvec_minmax, 298 .extra1 = &zero, 299 .extra2 = &one, 300 }, 301 { } 302 }; 303 #endif /* CONFIG_SYSCTL */ 304 305 static __init int yama_init(void) 306 { 307 if (!security_module_enable(&yama_ops)) 308 return 0; 309 310 printk(KERN_INFO "Yama: becoming mindful.\n"); 311 312 if (register_security(&yama_ops)) 313 panic("Yama: kernel registration failed.\n"); 314 315 #ifdef CONFIG_SYSCTL 316 if (!register_sysctl_paths(yama_sysctl_path, yama_sysctl_table)) 317 panic("Yama: sysctl registration failed.\n"); 318 #endif 319 320 return 0; 321 } 322 323 security_initcall(yama_init); 324