aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2008-11-13 18:39:16 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 18:39:16 -0500
commitb6dff3ec5e116e3af6f537d4caedcad6b9e5082a (patch)
tree9e76f972eb7ce9b84e0146c8e4126a3f86acb428 /include
parent15a2460ed0af7538ca8e6c610fe607a2cd9da142 (diff)
CRED: Separate task security context from task_struct
Separate the task security context from task_struct. At this point, the security data is temporarily embedded in the task_struct with two pointers pointing to it. Note that the Alpha arch is altered as it refers to (E)UID and (E)GID in entry.S via asm-offsets. With comment fixes Signed-off-by: Marc Dionne <marc.c.dionne@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Acked-by: James Morris <jmorris@namei.org> Acked-by: Serge Hallyn <serue@us.ibm.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/cred.h155
-rw-r--r--include/linux/init_task.h24
-rw-r--r--include/linux/sched.h52
-rw-r--r--include/linux/securebits.h2
4 files changed, 155 insertions, 78 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h
index b69222cc1fd2..3e65587a72e5 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -12,39 +12,150 @@
12#ifndef _LINUX_CRED_H 12#ifndef _LINUX_CRED_H
13#define _LINUX_CRED_H 13#define _LINUX_CRED_H
14 14
15#define get_current_user() (get_uid(current->user)) 15#include <linux/capability.h>
16 16#include <linux/key.h>
17#define task_uid(task) ((task)->uid) 17#include <asm/atomic.h>
18#define task_gid(task) ((task)->gid) 18
19#define task_euid(task) ((task)->euid) 19struct user_struct;
20#define task_egid(task) ((task)->egid) 20struct cred;
21 21
22#define current_uid() (current->uid) 22/*
23#define current_gid() (current->gid) 23 * COW Supplementary groups list
24#define current_euid() (current->euid) 24 */
25#define current_egid() (current->egid) 25#define NGROUPS_SMALL 32
26#define current_suid() (current->suid) 26#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
27#define current_sgid() (current->sgid) 27
28#define current_fsuid() (current->fsuid) 28struct group_info {
29#define current_fsgid() (current->fsgid) 29 atomic_t usage;
30#define current_cap() (current->cap_effective) 30 int ngroups;
31 int nblocks;
32 gid_t small_block[NGROUPS_SMALL];
33 gid_t *blocks[0];
34};
35
36/**
37 * get_group_info - Get a reference to a group info structure
38 * @group_info: The group info to reference
39 *
40 * This must be called with the owning task locked (via task_lock()) when task
41 * != current. The reason being that the vast majority of callers are looking
42 * at current->group_info, which can not be changed except by the current task.
43 * Changing current->group_info requires the task lock, too.
44 */
45#define get_group_info(group_info) \
46do { \
47 atomic_inc(&(group_info)->usage); \
48} while (0)
49
50/**
51 * put_group_info - Release a reference to a group info structure
52 * @group_info: The group info to release
53 */
54#define put_group_info(group_info) \
55do { \
56 if (atomic_dec_and_test(&(group_info)->usage)) \
57 groups_free(group_info); \
58} while (0)
59
60extern struct group_info *groups_alloc(int);
61extern void groups_free(struct group_info *);
62extern int set_current_groups(struct group_info *);
63extern int set_groups(struct cred *, struct group_info *);
64extern int groups_search(struct group_info *, gid_t);
65
66/* access the groups "array" with this macro */
67#define GROUP_AT(gi, i) \
68 ((gi)->blocks[(i) / NGROUPS_PER_BLOCK][(i) % NGROUPS_PER_BLOCK])
69
70extern int in_group_p(gid_t);
71extern int in_egroup_p(gid_t);
72
73/*
74 * The security context of a task
75 *
76 * The parts of the context break down into two categories:
77 *
78 * (1) The objective context of a task. These parts are used when some other
79 * task is attempting to affect this one.
80 *
81 * (2) The subjective context. These details are used when the task is acting
82 * upon another object, be that a file, a task, a key or whatever.
83 *
84 * Note that some members of this structure belong to both categories - the
85 * LSM security pointer for instance.
86 *
87 * A task has two security pointers. task->real_cred points to the objective
88 * context that defines that task's actual details. The objective part of this
89 * context is used whenever that task is acted upon.
90 *
91 * task->cred points to the subjective context that defines the details of how
92 * that task is going to act upon another object. This may be overridden
93 * temporarily to point to another security context, but normally points to the
94 * same context as task->real_cred.
95 */
96struct cred {
97 atomic_t usage;
98 uid_t uid; /* real UID of the task */
99 gid_t gid; /* real GID of the task */
100 uid_t suid; /* saved UID of the task */
101 gid_t sgid; /* saved GID of the task */
102 uid_t euid; /* effective UID of the task */
103 gid_t egid; /* effective GID of the task */
104 uid_t fsuid; /* UID for VFS ops */
105 gid_t fsgid; /* GID for VFS ops */
106 unsigned securebits; /* SUID-less security management */
107 kernel_cap_t cap_inheritable; /* caps our children can inherit */
108 kernel_cap_t cap_permitted; /* caps we're permitted */
109 kernel_cap_t cap_effective; /* caps we can actually use */
110 kernel_cap_t cap_bset; /* capability bounding set */
111#ifdef CONFIG_KEYS
112 unsigned char jit_keyring; /* default keyring to attach requested
113 * keys to */
114 struct key *thread_keyring; /* keyring private to this thread */
115 struct key *request_key_auth; /* assumed request_key authority */
116#endif
117#ifdef CONFIG_SECURITY
118 void *security; /* subjective LSM security */
119#endif
120 struct user_struct *user; /* real user ID subscription */
121 struct group_info *group_info; /* supplementary groups for euid/fsgid */
122 struct rcu_head rcu; /* RCU deletion hook */
123 spinlock_t lock; /* lock for pointer changes */
124};
125
126#define get_current_user() (get_uid(current->cred->user))
127
128#define task_uid(task) ((task)->cred->uid)
129#define task_gid(task) ((task)->cred->gid)
130#define task_euid(task) ((task)->cred->euid)
131#define task_egid(task) ((task)->cred->egid)
132
133#define current_uid() (current->cred->uid)
134#define current_gid() (current->cred->gid)
135#define current_euid() (current->cred->euid)
136#define current_egid() (current->cred->egid)
137#define current_suid() (current->cred->suid)
138#define current_sgid() (current->cred->sgid)
139#define current_fsuid() (current->cred->fsuid)
140#define current_fsgid() (current->cred->fsgid)
141#define current_cap() (current->cred->cap_effective)
31 142
32#define current_uid_gid(_uid, _gid) \ 143#define current_uid_gid(_uid, _gid) \
33do { \ 144do { \
34 *(_uid) = current->uid; \ 145 *(_uid) = current->cred->uid; \
35 *(_gid) = current->gid; \ 146 *(_gid) = current->cred->gid; \
36} while(0) 147} while(0)
37 148
38#define current_euid_egid(_uid, _gid) \ 149#define current_euid_egid(_uid, _gid) \
39do { \ 150do { \
40 *(_uid) = current->euid; \ 151 *(_uid) = current->cred->euid; \
41 *(_gid) = current->egid; \ 152 *(_gid) = current->cred->egid; \
42} while(0) 153} while(0)
43 154
44#define current_fsuid_fsgid(_uid, _gid) \ 155#define current_fsuid_fsgid(_uid, _gid) \
45do { \ 156do { \
46 *(_uid) = current->fsuid; \ 157 *(_uid) = current->cred->fsuid; \
47 *(_gid) = current->fsgid; \ 158 *(_gid) = current->cred->fsgid; \
48} while(0) 159} while(0)
49 160
50#endif /* _LINUX_CRED_H */ 161#endif /* _LINUX_CRED_H */
diff --git a/include/linux/init_task.h b/include/linux/init_task.h
index 23fd8909b9e5..9de41ccd67b5 100644
--- a/include/linux/init_task.h
+++ b/include/linux/init_task.h
@@ -113,6 +113,21 @@ extern struct group_info init_groups;
113# define CAP_INIT_BSET CAP_INIT_EFF_SET 113# define CAP_INIT_BSET CAP_INIT_EFF_SET
114#endif 114#endif
115 115
116extern struct cred init_cred;
117
118#define INIT_CRED(p) \
119{ \
120 .usage = ATOMIC_INIT(3), \
121 .securebits = SECUREBITS_DEFAULT, \
122 .cap_inheritable = CAP_INIT_INH_SET, \
123 .cap_permitted = CAP_FULL_SET, \
124 .cap_effective = CAP_INIT_EFF_SET, \
125 .cap_bset = CAP_INIT_BSET, \
126 .user = INIT_USER, \
127 .group_info = &init_groups, \
128 .lock = __SPIN_LOCK_UNLOCKED(p.lock), \
129}
130
116/* 131/*
117 * INIT_TASK is used to set up the first task table, touch at 132 * INIT_TASK is used to set up the first task table, touch at
118 * your own risk!. Base=0, limit=0x1fffff (=2MB) 133 * your own risk!. Base=0, limit=0x1fffff (=2MB)
@@ -147,13 +162,8 @@ extern struct group_info init_groups;
147 .children = LIST_HEAD_INIT(tsk.children), \ 162 .children = LIST_HEAD_INIT(tsk.children), \
148 .sibling = LIST_HEAD_INIT(tsk.sibling), \ 163 .sibling = LIST_HEAD_INIT(tsk.sibling), \
149 .group_leader = &tsk, \ 164 .group_leader = &tsk, \
150 .group_info = &init_groups, \ 165 .__temp_cred = INIT_CRED(tsk.__temp_cred), \
151 .cap_effective = CAP_INIT_EFF_SET, \ 166 .cred = &tsk.__temp_cred, \
152 .cap_inheritable = CAP_INIT_INH_SET, \
153 .cap_permitted = CAP_FULL_SET, \
154 .cap_bset = CAP_INIT_BSET, \
155 .securebits = SECUREBITS_DEFAULT, \
156 .user = INIT_USER, \
157 .comm = "swapper", \ 167 .comm = "swapper", \
158 .thread = INIT_THREAD, \ 168 .thread = INIT_THREAD, \
159 .fs = &init_fs, \ 169 .fs = &init_fs, \
diff --git a/include/linux/sched.h b/include/linux/sched.h
index b483f39a7112..c8b92502354d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -660,6 +660,7 @@ extern struct user_struct *find_user(uid_t);
660extern struct user_struct root_user; 660extern struct user_struct root_user;
661#define INIT_USER (&root_user) 661#define INIT_USER (&root_user)
662 662
663
663struct backing_dev_info; 664struct backing_dev_info;
664struct reclaim_state; 665struct reclaim_state;
665 666
@@ -883,38 +884,7 @@ partition_sched_domains(int ndoms_new, cpumask_t *doms_new,
883#endif /* !CONFIG_SMP */ 884#endif /* !CONFIG_SMP */
884 885
885struct io_context; /* See blkdev.h */ 886struct io_context; /* See blkdev.h */
886#define NGROUPS_SMALL 32
887#define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t)))
888struct group_info {
889 int ngroups;
890 atomic_t usage;
891 gid_t small_block[NGROUPS_SMALL];
892 int nblocks;
893 gid_t *blocks[0];
894};
895
896/*
897 * get_group_info() must be called with the owning task locked (via task_lock())
898 * when task != current. The reason being that the vast majority of callers are
899 * looking at current->group_info, which can not be changed except by the
900 * current task. Changing current->group_info requires the task lock, too.
901 */
902#define get_group_info(group_info) do { \
903 atomic_inc(&(group_info)->usage); \
904} while (0)
905 887
906#define put_group_info(group_info) do { \
907 if (atomic_dec_and_test(&(group_info)->usage)) \
908 groups_free(group_info); \
909} while (0)
910
911extern struct group_info *groups_alloc(int gidsetsize);
912extern void groups_free(struct group_info *group_info);
913extern int set_current_groups(struct group_info *group_info);
914extern int groups_search(struct group_info *group_info, gid_t grp);
915/* access the groups "array" with this macro */
916#define GROUP_AT(gi, i) \
917 ((gi)->blocks[(i)/NGROUPS_PER_BLOCK][(i)%NGROUPS_PER_BLOCK])
918 888
919#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK 889#ifdef ARCH_HAS_PREFETCH_SWITCH_STACK
920extern void prefetch_stack(struct task_struct *t); 890extern void prefetch_stack(struct task_struct *t);
@@ -1181,17 +1151,9 @@ struct task_struct {
1181 struct list_head cpu_timers[3]; 1151 struct list_head cpu_timers[3];
1182 1152
1183/* process credentials */ 1153/* process credentials */
1184 uid_t uid,euid,suid,fsuid; 1154 struct cred __temp_cred __deprecated; /* temporary credentials to be removed */
1185 gid_t gid,egid,sgid,fsgid; 1155 struct cred *cred; /* actual/objective task credentials */
1186 struct group_info *group_info; 1156
1187 kernel_cap_t cap_effective, cap_inheritable, cap_permitted, cap_bset;
1188 struct user_struct *user;
1189 unsigned securebits;
1190#ifdef CONFIG_KEYS
1191 unsigned char jit_keyring; /* default keyring to attach requested keys to */
1192 struct key *request_key_auth; /* assumed request_key authority */
1193 struct key *thread_keyring; /* keyring private to this thread */
1194#endif
1195 char comm[TASK_COMM_LEN]; /* executable name excluding path 1157 char comm[TASK_COMM_LEN]; /* executable name excluding path
1196 - access with [gs]et_task_comm (which lock 1158 - access with [gs]et_task_comm (which lock
1197 it with task_lock()) 1159 it with task_lock())
@@ -1228,9 +1190,6 @@ struct task_struct {
1228 int (*notifier)(void *priv); 1190 int (*notifier)(void *priv);
1229 void *notifier_data; 1191 void *notifier_data;
1230 sigset_t *notifier_mask; 1192 sigset_t *notifier_mask;
1231#ifdef CONFIG_SECURITY
1232 void *security;
1233#endif
1234 struct audit_context *audit_context; 1193 struct audit_context *audit_context;
1235#ifdef CONFIG_AUDITSYSCALL 1194#ifdef CONFIG_AUDITSYSCALL
1236 uid_t loginuid; 1195 uid_t loginuid;
@@ -1787,9 +1746,6 @@ extern void wake_up_new_task(struct task_struct *tsk,
1787extern void sched_fork(struct task_struct *p, int clone_flags); 1746extern void sched_fork(struct task_struct *p, int clone_flags);
1788extern void sched_dead(struct task_struct *p); 1747extern void sched_dead(struct task_struct *p);
1789 1748
1790extern int in_group_p(gid_t);
1791extern int in_egroup_p(gid_t);
1792
1793extern void proc_caches_init(void); 1749extern void proc_caches_init(void);
1794extern void flush_signals(struct task_struct *); 1750extern void flush_signals(struct task_struct *);
1795extern void ignore_signals(struct task_struct *); 1751extern void ignore_signals(struct task_struct *);
diff --git a/include/linux/securebits.h b/include/linux/securebits.h
index 92f09bdf1175..6d389491bfa2 100644
--- a/include/linux/securebits.h
+++ b/include/linux/securebits.h
@@ -32,7 +32,7 @@
32 setting is locked or not. A setting which is locked cannot be 32 setting is locked or not. A setting which is locked cannot be
33 changed from user-level. */ 33 changed from user-level. */
34#define issecure_mask(X) (1 << (X)) 34#define issecure_mask(X) (1 << (X))
35#define issecure(X) (issecure_mask(X) & current->securebits) 35#define issecure(X) (issecure_mask(X) & current->cred->securebits)
36 36
37#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ 37#define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \
38 issecure_mask(SECURE_NO_SETUID_FIXUP) | \ 38 issecure_mask(SECURE_NO_SETUID_FIXUP) | \