diff options
Diffstat (limited to 'include/linux/cred.h')
-rw-r--r-- | include/linux/cred.h | 65 |
1 files changed, 64 insertions, 1 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h index b3c76e815d66..85439abdbc80 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h | |||
@@ -114,6 +114,13 @@ struct thread_group_cred { | |||
114 | */ | 114 | */ |
115 | struct cred { | 115 | struct cred { |
116 | atomic_t usage; | 116 | atomic_t usage; |
117 | #ifdef CONFIG_DEBUG_CREDENTIALS | ||
118 | atomic_t subscribers; /* number of processes subscribed */ | ||
119 | void *put_addr; | ||
120 | unsigned magic; | ||
121 | #define CRED_MAGIC 0x43736564 | ||
122 | #define CRED_MAGIC_DEAD 0x44656144 | ||
123 | #endif | ||
117 | uid_t uid; /* real UID of the task */ | 124 | uid_t uid; /* real UID of the task */ |
118 | gid_t gid; /* real GID of the task */ | 125 | gid_t gid; /* real GID of the task */ |
119 | uid_t suid; /* saved UID of the task */ | 126 | uid_t suid; /* saved UID of the task */ |
@@ -143,6 +150,7 @@ struct cred { | |||
143 | }; | 150 | }; |
144 | 151 | ||
145 | extern void __put_cred(struct cred *); | 152 | extern void __put_cred(struct cred *); |
153 | extern void exit_creds(struct task_struct *); | ||
146 | extern int copy_creds(struct task_struct *, unsigned long); | 154 | extern int copy_creds(struct task_struct *, unsigned long); |
147 | extern struct cred *prepare_creds(void); | 155 | extern struct cred *prepare_creds(void); |
148 | extern struct cred *prepare_exec_creds(void); | 156 | extern struct cred *prepare_exec_creds(void); |
@@ -158,6 +166,60 @@ extern int set_security_override_from_ctx(struct cred *, const char *); | |||
158 | extern int set_create_files_as(struct cred *, struct inode *); | 166 | extern int set_create_files_as(struct cred *, struct inode *); |
159 | extern void __init cred_init(void); | 167 | extern void __init cred_init(void); |
160 | 168 | ||
169 | /* | ||
170 | * check for validity of credentials | ||
171 | */ | ||
172 | #ifdef CONFIG_DEBUG_CREDENTIALS | ||
173 | extern void __invalid_creds(const struct cred *, const char *, unsigned); | ||
174 | extern void __validate_process_creds(struct task_struct *, | ||
175 | const char *, unsigned); | ||
176 | |||
177 | static inline bool creds_are_invalid(const struct cred *cred) | ||
178 | { | ||
179 | if (cred->magic != CRED_MAGIC) | ||
180 | return true; | ||
181 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
182 | return true; | ||
183 | #ifdef CONFIG_SECURITY_SELINUX | ||
184 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
185 | return true; | ||
186 | if ((*(u32*)cred->security & 0xffffff00) == | ||
187 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
188 | return true; | ||
189 | #endif | ||
190 | return false; | ||
191 | } | ||
192 | |||
193 | static inline void __validate_creds(const struct cred *cred, | ||
194 | const char *file, unsigned line) | ||
195 | { | ||
196 | if (unlikely(creds_are_invalid(cred))) | ||
197 | __invalid_creds(cred, file, line); | ||
198 | } | ||
199 | |||
200 | #define validate_creds(cred) \ | ||
201 | do { \ | ||
202 | __validate_creds((cred), __FILE__, __LINE__); \ | ||
203 | } while(0) | ||
204 | |||
205 | #define validate_process_creds() \ | ||
206 | do { \ | ||
207 | __validate_process_creds(current, __FILE__, __LINE__); \ | ||
208 | } while(0) | ||
209 | |||
210 | extern void validate_creds_for_do_exit(struct task_struct *); | ||
211 | #else | ||
212 | static inline void validate_creds(const struct cred *cred) | ||
213 | { | ||
214 | } | ||
215 | static inline void validate_creds_for_do_exit(struct task_struct *tsk) | ||
216 | { | ||
217 | } | ||
218 | static inline void validate_process_creds(void) | ||
219 | { | ||
220 | } | ||
221 | #endif | ||
222 | |||
161 | /** | 223 | /** |
162 | * get_new_cred - Get a reference on a new set of credentials | 224 | * get_new_cred - Get a reference on a new set of credentials |
163 | * @cred: The new credentials to reference | 225 | * @cred: The new credentials to reference |
@@ -187,6 +249,7 @@ static inline struct cred *get_new_cred(struct cred *cred) | |||
187 | static inline const struct cred *get_cred(const struct cred *cred) | 249 | static inline const struct cred *get_cred(const struct cred *cred) |
188 | { | 250 | { |
189 | struct cred *nonconst_cred = (struct cred *) cred; | 251 | struct cred *nonconst_cred = (struct cred *) cred; |
252 | validate_creds(cred); | ||
190 | return get_new_cred(nonconst_cred); | 253 | return get_new_cred(nonconst_cred); |
191 | } | 254 | } |
192 | 255 | ||
@@ -205,7 +268,7 @@ static inline void put_cred(const struct cred *_cred) | |||
205 | { | 268 | { |
206 | struct cred *cred = (struct cred *) _cred; | 269 | struct cred *cred = (struct cred *) _cred; |
207 | 270 | ||
208 | BUG_ON(atomic_read(&(cred)->usage) <= 0); | 271 | validate_creds(cred); |
209 | if (atomic_dec_and_test(&(cred)->usage)) | 272 | if (atomic_dec_and_test(&(cred)->usage)) |
210 | __put_cred(cred); | 273 | __put_cred(cred); |
211 | } | 274 | } |