diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2009-09-14 14:26:05 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2009-09-14 14:26:05 -0400 |
commit | ac8d513a6801c8636922ccf4f30211810c9a56ce (patch) | |
tree | 83ba584487a6a612c8fcf2563c28c0263df35ba2 /include/linux/cred.h | |
parent | bf992fa2bc1ad1bb2aeb0bdfadb43f236b9297fd (diff) | |
parent | 99bc47067910f7070e65ee318a6dd79a2371f1e5 (diff) |
Merge branch 'master' into for-linus
Diffstat (limited to 'include/linux/cred.h')
-rw-r--r-- | include/linux/cred.h | 69 |
1 files changed, 67 insertions, 2 deletions
diff --git a/include/linux/cred.h b/include/linux/cred.h index 4fa999696310..24520a539c6f 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,7 +150,9 @@ 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); |
155 | extern struct cred *cred_alloc_blank(void); | ||
147 | extern struct cred *prepare_creds(void); | 156 | extern struct cred *prepare_creds(void); |
148 | extern struct cred *prepare_exec_creds(void); | 157 | extern struct cred *prepare_exec_creds(void); |
149 | extern struct cred *prepare_usermodehelper_creds(void); | 158 | extern struct cred *prepare_usermodehelper_creds(void); |
@@ -158,6 +167,60 @@ extern int set_security_override_from_ctx(struct cred *, const char *); | |||
158 | extern int set_create_files_as(struct cred *, struct inode *); | 167 | extern int set_create_files_as(struct cred *, struct inode *); |
159 | extern void __init cred_init(void); | 168 | extern void __init cred_init(void); |
160 | 169 | ||
170 | /* | ||
171 | * check for validity of credentials | ||
172 | */ | ||
173 | #ifdef CONFIG_DEBUG_CREDENTIALS | ||
174 | extern void __invalid_creds(const struct cred *, const char *, unsigned); | ||
175 | extern void __validate_process_creds(struct task_struct *, | ||
176 | const char *, unsigned); | ||
177 | |||
178 | static inline bool creds_are_invalid(const struct cred *cred) | ||
179 | { | ||
180 | if (cred->magic != CRED_MAGIC) | ||
181 | return true; | ||
182 | if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) | ||
183 | return true; | ||
184 | #ifdef CONFIG_SECURITY_SELINUX | ||
185 | if ((unsigned long) cred->security < PAGE_SIZE) | ||
186 | return true; | ||
187 | if ((*(u32*)cred->security & 0xffffff00) == | ||
188 | (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) | ||
189 | return true; | ||
190 | #endif | ||
191 | return false; | ||
192 | } | ||
193 | |||
194 | static inline void __validate_creds(const struct cred *cred, | ||
195 | const char *file, unsigned line) | ||
196 | { | ||
197 | if (unlikely(creds_are_invalid(cred))) | ||
198 | __invalid_creds(cred, file, line); | ||
199 | } | ||
200 | |||
201 | #define validate_creds(cred) \ | ||
202 | do { \ | ||
203 | __validate_creds((cred), __FILE__, __LINE__); \ | ||
204 | } while(0) | ||
205 | |||
206 | #define validate_process_creds() \ | ||
207 | do { \ | ||
208 | __validate_process_creds(current, __FILE__, __LINE__); \ | ||
209 | } while(0) | ||
210 | |||
211 | extern void validate_creds_for_do_exit(struct task_struct *); | ||
212 | #else | ||
213 | static inline void validate_creds(const struct cred *cred) | ||
214 | { | ||
215 | } | ||
216 | static inline void validate_creds_for_do_exit(struct task_struct *tsk) | ||
217 | { | ||
218 | } | ||
219 | static inline void validate_process_creds(void) | ||
220 | { | ||
221 | } | ||
222 | #endif | ||
223 | |||
161 | /** | 224 | /** |
162 | * get_new_cred - Get a reference on a new set of credentials | 225 | * get_new_cred - Get a reference on a new set of credentials |
163 | * @cred: The new credentials to reference | 226 | * @cred: The new credentials to reference |
@@ -186,7 +249,9 @@ static inline struct cred *get_new_cred(struct cred *cred) | |||
186 | */ | 249 | */ |
187 | static inline const struct cred *get_cred(const struct cred *cred) | 250 | static inline const struct cred *get_cred(const struct cred *cred) |
188 | { | 251 | { |
189 | return get_new_cred((struct cred *) cred); | 252 | struct cred *nonconst_cred = (struct cred *) cred; |
253 | validate_creds(cred); | ||
254 | return get_new_cred(nonconst_cred); | ||
190 | } | 255 | } |
191 | 256 | ||
192 | /** | 257 | /** |
@@ -204,7 +269,7 @@ static inline void put_cred(const struct cred *_cred) | |||
204 | { | 269 | { |
205 | struct cred *cred = (struct cred *) _cred; | 270 | struct cred *cred = (struct cred *) _cred; |
206 | 271 | ||
207 | BUG_ON(atomic_read(&(cred)->usage) <= 0); | 272 | validate_creds(cred); |
208 | if (atomic_dec_and_test(&(cred)->usage)) | 273 | if (atomic_dec_and_test(&(cred)->usage)) |
209 | __put_cred(cred); | 274 | __put_cred(cred); |
210 | } | 275 | } |