Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

CRED: Add some configurable debugging [try #6]

Add a config option (CONFIG_DEBUG_CREDENTIALS) to turn on some debug checking
for credential management. The additional code keeps track of the number of
pointers from task_structs to any given cred struct, and checks to see that
this number never exceeds the usage count of the cred struct (which includes
all references, not just those from task_structs).

Furthermore, if SELinux is enabled, the code also checks that the security
pointer in the cred struct is never seen to be invalid.

This attempts to catch the bug whereby inode_has_perm() faults in an nfsd
kernel thread on seeing cred->security be a NULL pointer (it appears that the
credential struct has been previously released):

http://www.kerneloops.org/oops.php?number=252883

Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: James Morris <jmorris@namei.org>

authored by

David Howells and committed by
James Morris
e0e81739 ed6d76e4

+346 -12
+4
fs/nfsd/auth.c
··· 34 34 int flags = nfsexp_flags(rqstp, exp); 35 35 int ret; 36 36 37 + validate_process_creds(); 38 + 37 39 /* discard any old override before preparing the new set */ 38 40 revert_creds(get_cred(current->real_cred)); 39 41 new = prepare_creds(); ··· 88 86 else 89 87 new->cap_effective = cap_raise_nfsd_set(new->cap_effective, 90 88 new->cap_permitted); 89 + validate_process_creds(); 91 90 put_cred(override_creds(new)); 92 91 put_cred(new); 92 + validate_process_creds(); 93 93 return 0; 94 94 95 95 oom:
+2
fs/nfsd/nfssvc.c
··· 496 496 /* Lock the export hash tables for reading. */ 497 497 exp_readlock(); 498 498 499 + validate_process_creds(); 499 500 svc_process(rqstp); 501 + validate_process_creds(); 500 502 501 503 /* Unlock export hash tables */ 502 504 exp_readunlock();
+3
fs/nfsd/vfs.c
··· 684 684 __be32 err; 685 685 int host_err; 686 686 687 + validate_process_creds(); 688 + 687 689 /* 688 690 * If we get here, then the client has already done an "open", 689 691 * and (hopefully) checked permission - so allow OWNER_OVERRIDE ··· 742 740 out_nfserr: 743 741 err = nfserrno(host_err); 744 742 out: 743 + validate_process_creds(); 745 744 return err; 746 745 } 747 746
+2
fs/open.c
··· 959 959 int error; 960 960 struct file *f; 961 961 962 + validate_creds(cred); 963 + 962 964 /* 963 965 * We must always pass in a valid mount pointer. Historically 964 966 * callers got away with not passing it, but we must enforce this at
+64 -1
include/linux/cred.h
··· 114 114 */ 115 115 struct cred { 116 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 124 uid_t uid; /* real UID of the task */ 118 125 gid_t gid; /* real GID of the task */ 119 126 uid_t suid; /* saved UID of the task */ ··· 150 143 }; 151 144 152 145 extern void __put_cred(struct cred *); 146 + extern void exit_creds(struct task_struct *); 153 147 extern int copy_creds(struct task_struct *, unsigned long); 154 148 extern struct cred *prepare_creds(void); 155 149 extern struct cred *prepare_exec_creds(void); ··· 165 157 extern int set_security_override_from_ctx(struct cred *, const char *); 166 158 extern int set_create_files_as(struct cred *, struct inode *); 167 159 extern void __init cred_init(void); 160 + 161 + /* 162 + * check for validity of credentials 163 + */ 164 + #ifdef CONFIG_DEBUG_CREDENTIALS 165 + extern void __invalid_creds(const struct cred *, const char *, unsigned); 166 + extern void __validate_process_creds(struct task_struct *, 167 + const char *, unsigned); 168 + 169 + static inline bool creds_are_invalid(const struct cred *cred) 170 + { 171 + if (cred->magic != CRED_MAGIC) 172 + return true; 173 + if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) 174 + return true; 175 + #ifdef CONFIG_SECURITY_SELINUX 176 + if ((unsigned long) cred->security < PAGE_SIZE) 177 + return true; 178 + if ((*(u32*)cred->security & 0xffffff00) == 179 + (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) 180 + return true; 181 + #endif 182 + return false; 183 + } 184 + 185 + static inline void __validate_creds(const struct cred *cred, 186 + const char *file, unsigned line) 187 + { 188 + if (unlikely(creds_are_invalid(cred))) 189 + __invalid_creds(cred, file, line); 190 + } 191 + 192 + #define validate_creds(cred) \ 193 + do { \ 194 + __validate_creds((cred), __FILE__, __LINE__); \ 195 + } while(0) 196 + 197 + #define validate_process_creds() \ 198 + do { \ 199 + __validate_process_creds(current, __FILE__, __LINE__); \ 200 + } while(0) 201 + 202 + extern void validate_creds_for_do_exit(struct task_struct *); 203 + #else 204 + static inline void validate_creds(const struct cred *cred) 205 + { 206 + } 207 + static inline void validate_creds_for_do_exit(struct task_struct *tsk) 208 + { 209 + } 210 + static inline void validate_process_creds(void) 211 + { 212 + } 213 + #endif 168 214 169 215 /** 170 216 * get_new_cred - Get a reference on a new set of credentials ··· 249 187 static inline const struct cred *get_cred(const struct cred *cred) 250 188 { 251 189 struct cred *nonconst_cred = (struct cred *) cred; 190 + validate_creds(cred); 252 191 return get_new_cred(nonconst_cred); 253 192 } 254 193 ··· 268 205 { 269 206 struct cred *cred = (struct cred *) _cred; 270 207 271 - BUG_ON(atomic_read(&(cred)->usage) <= 0); 208 + validate_creds(cred); 272 209 if (atomic_dec_and_test(&(cred)->usage)) 273 210 __put_cred(cred); 274 211 }
+244 -6
kernel/cred.c
··· 18 18 #include <linux/cn_proc.h> 19 19 #include "cred-internals.h" 20 20 21 + #if 0 22 + #define kdebug(FMT, ...) \ 23 + printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__) 24 + #else 25 + static inline __attribute__((format(printf, 1, 2))) 26 + void no_printk(const char *fmt, ...) 27 + { 28 + } 29 + #define kdebug(FMT, ...) \ 30 + no_printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__) 31 + #endif 32 + 21 33 static struct kmem_cache *cred_jar; 22 34 23 35 /* ··· 48 36 */ 49 37 struct cred init_cred = { 50 38 .usage = ATOMIC_INIT(4), 39 + #ifdef CONFIG_DEBUG_CREDENTIALS 40 + .subscribers = ATOMIC_INIT(2), 41 + .magic = CRED_MAGIC, 42 + #endif 51 43 .securebits = SECUREBITS_DEFAULT, 52 44 .cap_inheritable = CAP_INIT_INH_SET, 53 45 .cap_permitted = CAP_FULL_SET, ··· 63 47 .tgcred = &init_tgcred, 64 48 #endif 65 49 }; 50 + 51 + static inline void set_cred_subscribers(struct cred *cred, int n) 52 + { 53 + #ifdef CONFIG_DEBUG_CREDENTIALS 54 + atomic_set(&cred->subscribers, n); 55 + #endif 56 + } 57 + 58 + static inline int read_cred_subscribers(const struct cred *cred) 59 + { 60 + #ifdef CONFIG_DEBUG_CREDENTIALS 61 + return atomic_read(&cred->subscribers); 62 + #else 63 + return 0; 64 + #endif 65 + } 66 + 67 + static inline void alter_cred_subscribers(const struct cred *_cred, int n) 68 + { 69 + #ifdef CONFIG_DEBUG_CREDENTIALS 70 + struct cred *cred = (struct cred *) _cred; 71 + 72 + atomic_add(n, &cred->subscribers); 73 + #endif 74 + } 66 75 67 76 /* 68 77 * Dispose of the shared task group credentials ··· 126 85 { 127 86 struct cred *cred = container_of(rcu, struct cred, rcu); 128 87 88 + kdebug("put_cred_rcu(%p)", cred); 89 + 90 + #ifdef CONFIG_DEBUG_CREDENTIALS 91 + if (cred->magic != CRED_MAGIC_DEAD || 92 + atomic_read(&cred->usage) != 0 || 93 + read_cred_subscribers(cred) != 0) 94 + panic("CRED: put_cred_rcu() sees %p with" 95 + " mag %x, put %p, usage %d, subscr %d\n", 96 + cred, cred->magic, cred->put_addr, 97 + atomic_read(&cred->usage), 98 + read_cred_subscribers(cred)); 99 + #else 129 100 if (atomic_read(&cred->usage) != 0) 130 101 panic("CRED: put_cred_rcu() sees %p with usage %d\n", 131 102 cred, atomic_read(&cred->usage)); 103 + #endif 132 104 133 105 security_cred_free(cred); 134 106 key_put(cred->thread_keyring); ··· 160 106 */ 161 107 void __put_cred(struct cred *cred) 162 108 { 109 + kdebug("__put_cred(%p{%d,%d})", cred, 110 + atomic_read(&cred->usage), 111 + read_cred_subscribers(cred)); 112 + 163 113 BUG_ON(atomic_read(&cred->usage) != 0); 114 + #ifdef CONFIG_DEBUG_CREDENTIALS 115 + BUG_ON(read_cred_subscribers(cred) != 0); 116 + cred->magic = CRED_MAGIC_DEAD; 117 + cred->put_addr = __builtin_return_address(0); 118 + #endif 119 + BUG_ON(cred == current->cred); 120 + BUG_ON(cred == current->real_cred); 164 121 165 122 call_rcu(&cred->rcu, put_cred_rcu); 166 123 } 167 124 EXPORT_SYMBOL(__put_cred); 125 + 126 + /* 127 + * Clean up a task's credentials when it exits 128 + */ 129 + void exit_creds(struct task_struct *tsk) 130 + { 131 + struct cred *cred; 132 + 133 + kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, 134 + atomic_read(&tsk->cred->usage), 135 + read_cred_subscribers(tsk->cred)); 136 + 137 + cred = (struct cred *) tsk->real_cred; 138 + tsk->real_cred = NULL; 139 + validate_creds(cred); 140 + alter_cred_subscribers(cred, -1); 141 + put_cred(cred); 142 + 143 + cred = (struct cred *) tsk->cred; 144 + tsk->cred = NULL; 145 + validate_creds(cred); 146 + alter_cred_subscribers(cred, -1); 147 + put_cred(cred); 148 + } 168 149 169 150 /** 170 151 * prepare_creds - Prepare a new set of credentials for modification ··· 221 132 const struct cred *old; 222 133 struct cred *new; 223 134 224 - BUG_ON(atomic_read(&task->real_cred->usage) < 1); 135 + validate_process_creds(); 225 136 226 137 new = kmem_cache_alloc(cred_jar, GFP_KERNEL); 227 138 if (!new) 228 139 return NULL; 229 140 141 + kdebug("prepare_creds() alloc %p", new); 142 + 230 143 old = task->cred; 231 144 memcpy(new, old, sizeof(struct cred)); 232 145 233 146 atomic_set(&new->usage, 1); 147 + set_cred_subscribers(new, 0); 234 148 get_group_info(new->group_info); 235 149 get_uid(new->user); 236 150 ··· 249 157 250 158 if (security_prepare_creds(new, old, GFP_KERNEL) < 0) 251 159 goto error; 160 + validate_creds(new); 252 161 return new; 253 162 254 163 error: ··· 322 229 if (!new) 323 230 return NULL; 324 231 232 + kdebug("prepare_usermodehelper_creds() alloc %p", new); 233 + 325 234 memcpy(new, &init_cred, sizeof(struct cred)); 326 235 327 236 atomic_set(&new->usage, 1); 237 + set_cred_subscribers(new, 0); 328 238 get_group_info(new->group_info); 329 239 get_uid(new->user); 330 240 ··· 346 250 #endif 347 251 if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0) 348 252 goto error; 253 + validate_creds(new); 349 254 350 255 BUG_ON(atomic_read(&new->usage) != 1); 351 256 return new; ··· 383 286 ) { 384 287 p->real_cred = get_cred(p->cred); 385 288 get_cred(p->cred); 289 + alter_cred_subscribers(p->cred, 2); 290 + kdebug("share_creds(%p{%d,%d})", 291 + p->cred, atomic_read(&p->cred->usage), 292 + read_cred_subscribers(p->cred)); 386 293 atomic_inc(&p->cred->user->processes); 387 294 return 0; 388 295 } ··· 432 331 433 332 atomic_inc(&new->user->processes); 434 333 p->cred = p->real_cred = get_cred(new); 334 + alter_cred_subscribers(new, 2); 335 + validate_creds(new); 435 336 return 0; 436 337 437 338 error_put: ··· 458 355 int commit_creds(struct cred *new) 459 356 { 460 357 struct task_struct *task = current; 461 - const struct cred *old; 358 + const struct cred *old = task->real_cred; 462 359 463 - BUG_ON(task->cred != task->real_cred); 464 - BUG_ON(atomic_read(&task->real_cred->usage) < 2); 360 + kdebug("commit_creds(%p{%d,%d})", new, 361 + atomic_read(&new->usage), 362 + read_cred_subscribers(new)); 363 + 364 + BUG_ON(task->cred != old); 365 + #ifdef CONFIG_DEBUG_CREDENTIALS 366 + BUG_ON(read_cred_subscribers(old) < 2); 367 + validate_creds(old); 368 + validate_creds(new); 369 + #endif 465 370 BUG_ON(atomic_read(&new->usage) < 1); 466 371 467 - old = task->real_cred; 468 372 security_commit_creds(new, old); 469 373 470 374 get_cred(new); /* we will require a ref for the subj creds too */ ··· 500 390 * cheaply with the new uid cache, so if it matters 501 391 * we should be checking for it. -DaveM 502 392 */ 393 + alter_cred_subscribers(new, 2); 503 394 if (new->user != old->user) 504 395 atomic_inc(&new->user->processes); 505 396 rcu_assign_pointer(task->real_cred, new); 506 397 rcu_assign_pointer(task->cred, new); 507 398 if (new->user != old->user) 508 399 atomic_dec(&old->user->processes); 400 + alter_cred_subscribers(old, -2); 509 401 510 402 sched_switch_user(task); 511 403 ··· 540 428 */ 541 429 void abort_creds(struct cred *new) 542 430 { 431 + kdebug("abort_creds(%p{%d,%d})", new, 432 + atomic_read(&new->usage), 433 + read_cred_subscribers(new)); 434 + 435 + #ifdef CONFIG_DEBUG_CREDENTIALS 436 + BUG_ON(read_cred_subscribers(new) != 0); 437 + #endif 543 438 BUG_ON(atomic_read(&new->usage) < 1); 544 439 put_cred(new); 545 440 } ··· 563 444 { 564 445 const struct cred *old = current->cred; 565 446 566 - rcu_assign_pointer(current->cred, get_cred(new)); 447 + kdebug("override_creds(%p{%d,%d})", new, 448 + atomic_read(&new->usage), 449 + read_cred_subscribers(new)); 450 + 451 + validate_creds(old); 452 + validate_creds(new); 453 + get_cred(new); 454 + alter_cred_subscribers(new, 1); 455 + rcu_assign_pointer(current->cred, new); 456 + alter_cred_subscribers(old, -1); 457 + 458 + kdebug("override_creds() = %p{%d,%d}", old, 459 + atomic_read(&old->usage), 460 + read_cred_subscribers(old)); 567 461 return old; 568 462 } 569 463 EXPORT_SYMBOL(override_creds); ··· 592 460 { 593 461 const struct cred *override = current->cred; 594 462 463 + kdebug("revert_creds(%p{%d,%d})", old, 464 + atomic_read(&old->usage), 465 + read_cred_subscribers(old)); 466 + 467 + validate_creds(old); 468 + validate_creds(override); 469 + alter_cred_subscribers(old, 1); 595 470 rcu_assign_pointer(current->cred, old); 471 + alter_cred_subscribers(override, -1); 596 472 put_cred(override); 597 473 } 598 474 EXPORT_SYMBOL(revert_creds); ··· 642 502 if (!new) 643 503 return NULL; 644 504 505 + kdebug("prepare_kernel_cred() alloc %p", new); 506 + 645 507 if (daemon) 646 508 old = get_task_cred(daemon); 647 509 else 648 510 old = get_cred(&init_cred); 511 + 512 + validate_creds(old); 649 513 650 514 *new = *old; 651 515 get_uid(new->user); ··· 670 526 goto error; 671 527 672 528 atomic_set(&new->usage, 1); 529 + set_cred_subscribers(new, 0); 673 530 put_cred(old); 531 + validate_creds(new); 674 532 return new; 675 533 676 534 error: ··· 735 589 return security_kernel_create_files_as(new, inode); 736 590 } 737 591 EXPORT_SYMBOL(set_create_files_as); 592 + 593 + #ifdef CONFIG_DEBUG_CREDENTIALS 594 + 595 + /* 596 + * dump invalid credentials 597 + */ 598 + static void dump_invalid_creds(const struct cred *cred, const char *label, 599 + const struct task_struct *tsk) 600 + { 601 + printk(KERN_ERR "CRED: %s credentials: %p %s%s%s\n", 602 + label, cred, 603 + cred == &init_cred ? "[init]" : "", 604 + cred == tsk->real_cred ? "[real]" : "", 605 + cred == tsk->cred ? "[eff]" : ""); 606 + printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n", 607 + cred->magic, cred->put_addr); 608 + printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n", 609 + atomic_read(&cred->usage), 610 + read_cred_subscribers(cred)); 611 + printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", 612 + cred->uid, cred->euid, cred->suid, cred->fsuid); 613 + printk(KERN_ERR "CRED: ->*gid = { %d,%d,%d,%d }\n", 614 + cred->gid, cred->egid, cred->sgid, cred->fsgid); 615 + #ifdef CONFIG_SECURITY 616 + printk(KERN_ERR "CRED: ->security is %p\n", cred->security); 617 + if ((unsigned long) cred->security >= PAGE_SIZE && 618 + (((unsigned long) cred->security & 0xffffff00) != 619 + (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))) 620 + printk(KERN_ERR "CRED: ->security {%x, %x}\n", 621 + ((u32*)cred->security)[0], 622 + ((u32*)cred->security)[1]); 623 + #endif 624 + } 625 + 626 + /* 627 + * report use of invalid credentials 628 + */ 629 + void __invalid_creds(const struct cred *cred, const char *file, unsigned line) 630 + { 631 + printk(KERN_ERR "CRED: Invalid credentials\n"); 632 + printk(KERN_ERR "CRED: At %s:%u\n", file, line); 633 + dump_invalid_creds(cred, "Specified", current); 634 + BUG(); 635 + } 636 + EXPORT_SYMBOL(__invalid_creds); 637 + 638 + /* 639 + * check the credentials on a process 640 + */ 641 + void __validate_process_creds(struct task_struct *tsk, 642 + const char *file, unsigned line) 643 + { 644 + if (tsk->cred == tsk->real_cred) { 645 + if (unlikely(read_cred_subscribers(tsk->cred) < 2 || 646 + creds_are_invalid(tsk->cred))) 647 + goto invalid_creds; 648 + } else { 649 + if (unlikely(read_cred_subscribers(tsk->real_cred) < 1 || 650 + read_cred_subscribers(tsk->cred) < 1 || 651 + creds_are_invalid(tsk->real_cred) || 652 + creds_are_invalid(tsk->cred))) 653 + goto invalid_creds; 654 + } 655 + return; 656 + 657 + invalid_creds: 658 + printk(KERN_ERR "CRED: Invalid process credentials\n"); 659 + printk(KERN_ERR "CRED: At %s:%u\n", file, line); 660 + 661 + dump_invalid_creds(tsk->real_cred, "Real", tsk); 662 + if (tsk->cred != tsk->real_cred) 663 + dump_invalid_creds(tsk->cred, "Effective", tsk); 664 + else 665 + printk(KERN_ERR "CRED: Effective creds == Real creds\n"); 666 + BUG(); 667 + } 668 + EXPORT_SYMBOL(__validate_process_creds); 669 + 670 + /* 671 + * check creds for do_exit() 672 + */ 673 + void validate_creds_for_do_exit(struct task_struct *tsk) 674 + { 675 + kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", 676 + tsk->real_cred, tsk->cred, 677 + atomic_read(&tsk->cred->usage), 678 + read_cred_subscribers(tsk->cred)); 679 + 680 + __validate_process_creds(tsk, __FILE__, __LINE__); 681 + } 682 + 683 + #endif /* CONFIG_DEBUG_CREDENTIALS */
+4
kernel/exit.c
··· 901 901 902 902 tracehook_report_exit(&code); 903 903 904 + validate_creds_for_do_exit(tsk); 905 + 904 906 /* 905 907 * We're taking recursive faults here in do_exit. Safest is to just 906 908 * leave this task alone and wait for reboot. ··· 1010 1008 1011 1009 if (tsk->splice_pipe) 1012 1010 __free_pipe_info(tsk->splice_pipe); 1011 + 1012 + validate_creds_for_do_exit(tsk); 1013 1013 1014 1014 preempt_disable(); 1015 1015 /* causes final put_task_struct in finish_task_switch(). */
+2 -4
kernel/fork.c
··· 152 152 WARN_ON(atomic_read(&tsk->usage)); 153 153 WARN_ON(tsk == current); 154 154 155 - put_cred(tsk->real_cred); 156 - put_cred(tsk->cred); 155 + exit_creds(tsk); 157 156 delayacct_tsk_free(tsk); 158 157 159 158 if (!profile_handoff_task(tsk)) ··· 1306 1307 module_put(task_thread_info(p)->exec_domain->module); 1307 1308 bad_fork_cleanup_count: 1308 1309 atomic_dec(&p->cred->user->processes); 1309 - put_cred(p->real_cred); 1310 - put_cred(p->cred); 1310 + exit_creds(p); 1311 1311 bad_fork_free: 1312 1312 free_task(p); 1313 1313 fork_out:
+1
kernel/kmod.c
··· 466 466 int retval = 0; 467 467 468 468 BUG_ON(atomic_read(&sub_info->cred->usage) != 1); 469 + validate_creds(sub_info->cred); 469 470 470 471 helper_lock(); 471 472 if (sub_info->path[0] == '\0')
+15
lib/Kconfig.debug
··· 653 653 This is a relatively cheap check but if you care about maximum 654 654 performance, say N. 655 655 656 + config DEBUG_CREDENTIALS 657 + bool "Debug credential management" 658 + depends on DEBUG_KERNEL 659 + help 660 + Enable this to turn on some debug checking for credential 661 + management. The additional code keeps track of the number of 662 + pointers from task_structs to any given cred struct, and checks to 663 + see that this number never exceeds the usage count of the cred 664 + struct. 665 + 666 + Furthermore, if SELinux is enabled, this also checks that the 667 + security pointer in the cred struct is never seen to be invalid. 668 + 669 + If unsure, say N. 670 + 656 671 # 657 672 # Select this config option from the architecture Kconfig, if it 658 673 # it is preferred to always offer frame pointers as a config
+5 -1
security/selinux/hooks.c
··· 1531 1531 struct common_audit_data ad; 1532 1532 u32 sid; 1533 1533 1534 + validate_creds(cred); 1535 + 1534 1536 if (unlikely(IS_PRIVATE(inode))) 1535 1537 return 0; 1536 1538 ··· 3238 3236 static void selinux_cred_free(struct cred *cred) 3239 3237 { 3240 3238 struct task_security_struct *tsec = cred->security; 3241 - cred->security = NULL; 3239 + 3240 + BUG_ON((unsigned long) cred->security < PAGE_SIZE); 3241 + cred->security = (void *) 0x7UL; 3242 3242 kfree(tsec); 3243 3243 } 3244 3244