diff options
| -rw-r--r-- | fs/proc/array.c | 2 | ||||
| -rw-r--r-- | include/linux/cred.h | 21 | ||||
| -rw-r--r-- | kernel/cred.c | 25 |
3 files changed, 27 insertions, 21 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index 9b58d38bc911..fff6572676ae 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
| @@ -176,7 +176,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, | |||
| 176 | if (tracer) | 176 | if (tracer) |
| 177 | tpid = task_pid_nr_ns(tracer, ns); | 177 | tpid = task_pid_nr_ns(tracer, ns); |
| 178 | } | 178 | } |
| 179 | cred = get_cred((struct cred *) __task_cred(p)); | 179 | cred = get_task_cred(p); |
| 180 | seq_printf(m, | 180 | seq_printf(m, |
| 181 | "State:\t%s\n" | 181 | "State:\t%s\n" |
| 182 | "Tgid:\t%d\n" | 182 | "Tgid:\t%d\n" |
diff --git a/include/linux/cred.h b/include/linux/cred.h index 75c0fa881308..ce40cbc791e2 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
| @@ -153,6 +153,7 @@ struct cred { | |||
| 153 | extern void __put_cred(struct cred *); | 153 | extern void __put_cred(struct cred *); |
| 154 | extern void exit_creds(struct task_struct *); | 154 | extern void exit_creds(struct task_struct *); |
| 155 | extern int copy_creds(struct task_struct *, unsigned long); | 155 | extern int copy_creds(struct task_struct *, unsigned long); |
| 156 | extern const struct cred *get_task_cred(struct task_struct *); | ||
| 156 | extern struct cred *cred_alloc_blank(void); | 157 | extern struct cred *cred_alloc_blank(void); |
| 157 | extern struct cred *prepare_creds(void); | 158 | extern struct cred *prepare_creds(void); |
| 158 | extern struct cred *prepare_exec_creds(void); | 159 | extern struct cred *prepare_exec_creds(void); |
| @@ -282,26 +283,6 @@ static inline void put_cred(const struct cred *_cred) | |||
| 282 | ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_tasklist_lock_is_held()))) | 283 | ((const struct cred *)(rcu_dereference_check((task)->real_cred, rcu_read_lock_held() || lockdep_tasklist_lock_is_held()))) |
| 283 | 284 | ||
| 284 | /** | 285 | /** |
| 285 | * get_task_cred - Get another task's objective credentials | ||
| 286 | * @task: The task to query | ||
| 287 | * | ||
| 288 | * Get the objective credentials of a task, pinning them so that they can't go | ||
| 289 | * away. Accessing a task's credentials directly is not permitted. | ||
| 290 | * | ||
| 291 | * The caller must make sure task doesn't go away, either by holding a ref on | ||
| 292 | * task or by holding tasklist_lock to prevent it from being unlinked. | ||
| 293 | */ | ||
| 294 | #define get_task_cred(task) \ | ||
| 295 | ({ \ | ||
| 296 | struct cred *__cred; \ | ||
| 297 | rcu_read_lock(); \ | ||
| 298 | __cred = (struct cred *) __task_cred((task)); \ | ||
| 299 | get_cred(__cred); \ | ||
| 300 | rcu_read_unlock(); \ | ||
| 301 | __cred; \ | ||
| 302 | }) | ||
| 303 | |||
| 304 | /** | ||
| 305 | * get_current_cred - Get the current task's subjective credentials | 286 | * get_current_cred - Get the current task's subjective credentials |
| 306 | * | 287 | * |
| 307 | * Get the subjective credentials of the current task, pinning them so that | 288 | * Get the subjective credentials of the current task, pinning them so that |
diff --git a/kernel/cred.c b/kernel/cred.c index a2d5504fbcc2..60bc8b1e32e6 100644 --- a/kernel/cred.c +++ b/kernel/cred.c | |||
| @@ -209,6 +209,31 @@ void exit_creds(struct task_struct *tsk) | |||
| 209 | } | 209 | } |
| 210 | } | 210 | } |
| 211 | 211 | ||
| 212 | /** | ||
| 213 | * get_task_cred - Get another task's objective credentials | ||
| 214 | * @task: The task to query | ||
| 215 | * | ||
| 216 | * Get the objective credentials of a task, pinning them so that they can't go | ||
| 217 | * away. Accessing a task's credentials directly is not permitted. | ||
| 218 | * | ||
| 219 | * The caller must also make sure task doesn't get deleted, either by holding a | ||
| 220 | * ref on task or by holding tasklist_lock to prevent it from being unlinked. | ||
| 221 | */ | ||
| 222 | const struct cred *get_task_cred(struct task_struct *task) | ||
| 223 | { | ||
| 224 | const struct cred *cred; | ||
| 225 | |||
| 226 | rcu_read_lock(); | ||
| 227 | |||
| 228 | do { | ||
| 229 | cred = __task_cred((task)); | ||
| 230 | BUG_ON(!cred); | ||
| 231 | } while (!atomic_inc_not_zero(&((struct cred *)cred)->usage)); | ||
| 232 | |||
| 233 | rcu_read_unlock(); | ||
| 234 | return cred; | ||
| 235 | } | ||
| 236 | |||
| 212 | /* | 237 | /* |
| 213 | * Allocate blank credentials, such that the credentials can be filled in at a | 238 | * Allocate blank credentials, such that the credentials can be filled in at a |
| 214 | * later date without risk of ENOMEM. | 239 | * later date without risk of ENOMEM. |
