From caf1376852b7f6a117052b620ff06e494cd4bb92 Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Sat, 5 Sep 2009 20:22:36 -0700 Subject: [PATCH] --- yaml --- r: 157359 b: refs/heads/master c: 3793d2fc3eac7da11ca44df125cbcedd0b5315d0 h: refs/heads/master i: 157357: 5dcf1e394a216384b6ac31a6661c3a76dbb73c6b 157355: 5af93215159d4e2e3c9fd4efcce803c2b80cae64 157351: cdfe764577bd0e419e646543fc4edb978a87ff2b 157343: 39d973eceff62b72f950e28d75f2b568790271a4 v: v3 --- [refs] | 2 +- trunk/Documentation/keys.txt | 39 +-- trunk/Makefile | 2 +- trunk/arch/alpha/include/asm/thread_info.h | 5 +- trunk/arch/alpha/kernel/signal.c | 8 - trunk/arch/arm/include/asm/thread_info.h | 3 - trunk/arch/arm/kernel/entry-common.S | 2 +- trunk/arch/arm/kernel/signal.c | 8 - trunk/arch/avr32/include/asm/thread_info.h | 6 +- trunk/arch/avr32/kernel/entry-avr32b.S | 2 +- trunk/arch/avr32/kernel/signal.c | 8 - trunk/arch/cris/kernel/ptrace.c | 8 - trunk/arch/frv/kernel/signal.c | 2 - trunk/arch/h8300/include/asm/thread_info.h | 2 - trunk/arch/h8300/kernel/signal.c | 8 - trunk/arch/ia64/kernel/process.c | 2 - trunk/arch/m32r/include/asm/thread_info.h | 2 - trunk/arch/m32r/kernel/signal.c | 8 - trunk/arch/mips/include/asm/thread_info.h | 2 - trunk/arch/mips/kernel/signal.c | 8 - trunk/arch/mn10300/kernel/signal.c | 2 - trunk/arch/parisc/include/asm/thread_info.h | 4 +- trunk/arch/parisc/kernel/entry.S | 2 +- trunk/arch/parisc/kernel/signal.c | 8 - trunk/arch/s390/kernel/signal.c | 2 - trunk/arch/sh/kernel/signal_32.c | 2 - trunk/arch/sh/kernel/signal_64.c | 2 - trunk/arch/sparc/kernel/signal_32.c | 2 - trunk/arch/sparc/kernel/signal_64.c | 3 - trunk/arch/x86/kernel/signal.c | 2 - trunk/drivers/block/aoe/aoe.h | 2 +- trunk/drivers/block/aoe/aoeblk.c | 12 +- trunk/drivers/block/aoe/aoedev.c | 1 - trunk/drivers/char/agp/intel-agp.c | 8 +- trunk/drivers/char/tpm/tpm_tis.c | 12 +- trunk/drivers/gpu/drm/i915/i915_gem.c | 19 +- trunk/drivers/gpu/drm/i915/intel_display.c | 16 +- trunk/drivers/gpu/drm/i915/intel_dp.c | 2 +- trunk/drivers/gpu/drm/i915/intel_drv.h | 1 - trunk/drivers/gpu/drm/i915/intel_tv.c | 1 - trunk/drivers/gpu/drm/radeon/r300.c | 2 +- trunk/drivers/gpu/drm/radeon/radeon_asic.h | 6 +- trunk/drivers/gpu/drm/radeon/rs600.c | 65 ---- trunk/drivers/gpu/drm/radeon/rs690.c | 64 ++++ trunk/drivers/gpu/drm/radeon/rv515.c | 2 +- trunk/drivers/ide/ide-cs.c | 1 - .../infiniband/hw/cxgb3/iwch_provider.c | 2 + trunk/drivers/md/dm-log-userspace-base.c | 2 +- trunk/drivers/net/gianfar.c | 2 +- trunk/drivers/net/tun.c | 22 +- trunk/drivers/staging/comedi/comedi_fops.c | 8 +- trunk/fs/binfmt_elf.c | 28 +- trunk/fs/ext2/acl.c | 8 +- trunk/fs/ext2/acl.h | 4 +- trunk/fs/ext2/file.c | 2 +- trunk/fs/ext2/namei.c | 4 +- trunk/fs/ext3/acl.c | 8 +- trunk/fs/ext3/acl.h | 4 +- trunk/fs/ext3/file.c | 2 +- trunk/fs/ext3/namei.c | 4 +- trunk/fs/ext4/acl.c | 8 +- trunk/fs/ext4/acl.h | 4 +- trunk/fs/ext4/file.c | 2 +- trunk/fs/ext4/namei.c | 4 +- trunk/fs/jffs2/acl.c | 7 +- trunk/fs/jffs2/acl.h | 4 +- trunk/fs/jffs2/dir.c | 2 +- trunk/fs/jffs2/file.c | 2 +- trunk/fs/jffs2/symlink.c | 2 +- trunk/fs/jfs/acl.c | 7 +- trunk/fs/jfs/file.c | 2 +- trunk/fs/jfs/jfs_acl.h | 2 +- trunk/fs/jfs/namei.c | 2 +- trunk/fs/locks.c | 2 +- trunk/fs/namei.c | 110 +++--- trunk/fs/nfsd/auth.c | 4 - trunk/fs/nfsd/nfssvc.c | 2 - trunk/fs/nfsd/vfs.c | 3 - trunk/fs/open.c | 12 +- trunk/fs/sysfs/dir.c | 1 - trunk/fs/sysfs/inode.c | 134 ++------ trunk/fs/sysfs/symlink.c | 2 - trunk/fs/sysfs/sysfs.h | 12 +- trunk/fs/xattr.c | 55 +-- trunk/fs/xfs/linux-2.6/xfs_iops.c | 16 +- trunk/include/linux/cred.h | 69 +--- trunk/include/linux/fs.h | 1 - trunk/include/linux/key.h | 8 +- trunk/include/linux/keyctl.h | 1 - trunk/include/linux/lsm_audit.h | 12 +- trunk/include/linux/sched.h | 3 +- trunk/include/linux/security.h | 154 +-------- trunk/include/linux/shmem_fs.h | 2 +- trunk/include/linux/xattr.h | 1 - trunk/kernel/acct.c | 8 +- trunk/kernel/cred.c | 293 +--------------- trunk/kernel/exit.c | 4 - trunk/kernel/fork.c | 6 +- trunk/kernel/kmod.c | 5 - trunk/kernel/ptrace.c | 2 +- trunk/kernel/sysctl.c | 1 + trunk/lib/Kconfig.debug | 15 - trunk/lib/is_single_threaded.c | 61 ++-- trunk/mm/shmem.c | 6 +- trunk/mm/shmem_acl.c | 11 +- trunk/net/core/dev.c | 2 +- trunk/net/ipv4/tcp_cong.c | 4 +- trunk/security/Makefile | 4 +- trunk/security/capability.c | 63 +--- trunk/security/commoncap.c | 4 +- trunk/security/integrity/ima/ima_main.c | 6 +- trunk/security/keys/Makefile | 1 - trunk/security/keys/compat.c | 3 - trunk/security/keys/gc.c | 194 ----------- trunk/security/keys/internal.h | 10 +- trunk/security/keys/key.c | 24 +- trunk/security/keys/keyctl.c | 161 ++------- trunk/security/keys/keyring.c | 85 ----- trunk/security/keys/proc.c | 93 ++--- trunk/security/keys/process_keys.c | 69 +--- trunk/security/keys/sysctl.c | 28 +- trunk/security/lsm_audit.c | 2 - trunk/security/security.c | 62 +--- trunk/security/selinux/avc.c | 205 ++++++++--- trunk/security/selinux/hooks.c | 318 +++++------------- trunk/security/selinux/include/av_inherit.h | 1 - .../selinux/include/av_perm_to_string.h | 1 - .../security/selinux/include/av_permissions.h | 23 -- trunk/security/selinux/include/avc.h | 55 ++- .../selinux/include/class_to_string.h | 1 - trunk/security/selinux/include/flask.h | 1 - trunk/security/selinux/include/netlabel.h | 4 +- trunk/security/selinux/include/xfrm.h | 8 +- trunk/security/selinux/netlabel.c | 2 +- trunk/security/selinux/ss/services.c | 142 ++------ trunk/security/selinux/xfrm.c | 4 +- trunk/security/smack/smack.h | 2 +- trunk/security/smack/smack_access.c | 11 +- trunk/security/smack/smack_lsm.c | 65 +--- trunk/security/tomoyo/common.c | 30 -- trunk/security/tomoyo/common.h | 2 + trunk/security/tomoyo/domain.c | 42 ++- trunk/security/tomoyo/tomoyo.c | 27 +- trunk/security/tomoyo/tomoyo.h | 3 +- 144 files changed, 831 insertions(+), 2465 deletions(-) delete mode 100644 trunk/security/keys/gc.c diff --git a/[refs] b/[refs] index 6ae3212b810b..9d68c107553f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: f6f79190866d5b2d06a2114d673f91f54e7c7ce4 +refs/heads/master: 3793d2fc3eac7da11ca44df125cbcedd0b5315d0 diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index e4dbbdb1bd96..b56aacc1fff8 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -26,7 +26,7 @@ This document has the following sections: - Notes on accessing payload contents - Defining a key type - Request-key callback service - - Garbage collection + - Key access filesystem ============ @@ -113,9 +113,6 @@ Each key has a number of attributes: (*) Dead. The key's type was unregistered, and so the key is now useless. -Keys in the last three states are subject to garbage collection. See the -section on "Garbage collection". - ==================== KEY SERVICE OVERVIEW @@ -757,26 +754,6 @@ The keyctl syscall functions are: successful. - (*) Install the calling process's session keyring on its parent. - - long keyctl(KEYCTL_SESSION_TO_PARENT); - - This functions attempts to install the calling process's session keyring - on to the calling process's parent, replacing the parent's current session - keyring. - - The calling process must have the same ownership as its parent, the - keyring must have the same ownership as the calling process, the calling - process must have LINK permission on the keyring and the active LSM module - mustn't deny permission, otherwise error EPERM will be returned. - - Error ENOMEM will be returned if there was insufficient memory to complete - the operation, otherwise 0 will be returned to indicate success. - - The keyring will be replaced next time the parent process leaves the - kernel and resumes executing userspace. - - =============== KERNEL SERVICES =============== @@ -1254,17 +1231,3 @@ by executing: In this case, the program isn't required to actually attach the key to a ring; the rings are provided for reference. - - -================== -GARBAGE COLLECTION -================== - -Dead keys (for which the type has been removed) will be automatically unlinked -from those keyrings that point to them and deleted as soon as possible by a -background garbage collector. - -Similarly, revoked and expired keys will be garbage collected, but only after a -certain amount of time has passed. This time is set as a number of seconds in: - - /proc/sys/kernel/keys/gc_delay diff --git a/trunk/Makefile b/trunk/Makefile index 60de4ef31254..7d3415c0709c 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 31 -EXTRAVERSION = +EXTRAVERSION = -rc9 NAME = Man-Eating Seals of Antiquity # *DOCUMENTATION* diff --git a/trunk/arch/alpha/include/asm/thread_info.h b/trunk/arch/alpha/include/asm/thread_info.h index 5076a8860b18..60c83abfde70 100644 --- a/trunk/arch/alpha/include/asm/thread_info.h +++ b/trunk/arch/alpha/include/asm/thread_info.h @@ -75,7 +75,6 @@ register struct thread_info *__current_thread_info __asm__("$8"); #define TIF_UAC_SIGBUS 7 #define TIF_MEMDIE 8 #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal */ -#define TIF_NOTIFY_RESUME 10 /* callback before returning to user */ #define TIF_FREEZE 16 /* is freezing for suspend */ #define _TIF_SYSCALL_TRACE (1< #include #include -#include #include #include @@ -684,11 +683,4 @@ do_notify_resume(struct pt_regs *regs, struct switch_stack *sw, { if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, sw, r0, r19); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/arm/include/asm/thread_info.h b/trunk/arch/arm/include/asm/thread_info.h index d3a39b1e6c0f..73394e50cbca 100644 --- a/trunk/arch/arm/include/asm/thread_info.h +++ b/trunk/arch/arm/include/asm/thread_info.h @@ -130,13 +130,11 @@ extern void vfp_sync_state(struct thread_info *thread); * TIF_SYSCALL_TRACE - syscall trace active * TIF_SIGPENDING - signal pending * TIF_NEED_RESCHED - rescheduling necessary - * TIF_NOTIFY_RESUME - callback before returning to user * TIF_USEDFPU - FPU was used by this task this quantum (SMP) * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED */ #define TIF_SIGPENDING 0 #define TIF_NEED_RESCHED 1 -#define TIF_NOTIFY_RESUME 2 /* callback before returning to user */ #define TIF_SYSCALL_TRACE 8 #define TIF_POLLING_NRFLAG 16 #define TIF_USING_IWMMXT 17 @@ -145,7 +143,6 @@ extern void vfp_sync_state(struct thread_info *thread); #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_USING_IWMMXT (1 << TIF_USING_IWMMXT) diff --git a/trunk/arch/arm/kernel/entry-common.S b/trunk/arch/arm/kernel/entry-common.S index 7813ab782fda..8c3de1a350b5 100644 --- a/trunk/arch/arm/kernel/entry-common.S +++ b/trunk/arch/arm/kernel/entry-common.S @@ -51,7 +51,7 @@ fast_work_pending: work_pending: tst r1, #_TIF_NEED_RESCHED bne work_resched - tst r1, #_TIF_SIGPENDING|_TIF_NOTIFY_RESUME + tst r1, #_TIF_SIGPENDING beq no_work_pending mov r0, sp @ 'regs' mov r2, why @ 'syscall' diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index b76fe06d92e7..f6bc5d442782 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include @@ -708,11 +707,4 @@ do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall) { if (thread_flags & _TIF_SIGPENDING) do_signal(¤t->blocked, regs, syscall); - - if (thread_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/avr32/include/asm/thread_info.h b/trunk/arch/avr32/include/asm/thread_info.h index fd0c5d7e9337..fc42de5ca209 100644 --- a/trunk/arch/avr32/include/asm/thread_info.h +++ b/trunk/arch/avr32/include/asm/thread_info.h @@ -84,7 +84,6 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 6 #define TIF_RESTORE_SIGMASK 7 /* restore signal mask in do_signal */ #define TIF_CPU_GOING_TO_SLEEP 8 /* CPU is entering sleep 0 mode */ -#define TIF_NOTIFY_RESUME 9 /* callback before returning to user */ #define TIF_FREEZE 29 #define TIF_DEBUG 30 /* debugging enabled */ #define TIF_USERSPACE 31 /* true if FS sets userspace */ @@ -97,7 +96,6 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_CPU_GOING_TO_SLEEP (1 << TIF_CPU_GOING_TO_SLEEP) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) #define _TIF_FREEZE (1 << TIF_FREEZE) /* Note: The masks below must never span more than 16 bits! */ @@ -105,15 +103,13 @@ static inline struct thread_info *current_thread_info(void) /* work to do on interrupt/exception return */ #define _TIF_WORK_MASK \ ((1 << TIF_SIGPENDING) \ - | _TIF_NOTIFY_RESUME \ | (1 << TIF_NEED_RESCHED) \ | (1 << TIF_POLLING_NRFLAG) \ | (1 << TIF_BREAKPOINT) \ | (1 << TIF_RESTORE_SIGMASK)) /* work to do on any return to userspace */ -#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE) | \ - _TIF_NOTIFY_RESUME) +#define _TIF_ALLWORK_MASK (_TIF_WORK_MASK | (1 << TIF_SYSCALL_TRACE)) /* work to do on return from debug mode */ #define _TIF_DBGWORK_MASK (_TIF_WORK_MASK & ~(1 << TIF_BREAKPOINT)) diff --git a/trunk/arch/avr32/kernel/entry-avr32b.S b/trunk/arch/avr32/kernel/entry-avr32b.S index 169268c40ae2..009a80155d67 100644 --- a/trunk/arch/avr32/kernel/entry-avr32b.S +++ b/trunk/arch/avr32/kernel/entry-avr32b.S @@ -281,7 +281,7 @@ syscall_exit_work: ld.w r1, r0[TI_flags] rjmp 1b -2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NOTIFY_RESUME +2: mov r2, _TIF_SIGPENDING | _TIF_RESTORE_SIGMASK tst r1, r2 breq 3f unmask_interrupts diff --git a/trunk/arch/avr32/kernel/signal.c b/trunk/arch/avr32/kernel/signal.c index 64f886fac2ef..27227561bad6 100644 --- a/trunk/arch/avr32/kernel/signal.c +++ b/trunk/arch/avr32/kernel/signal.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -323,11 +322,4 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, struct thread_info *ti) if (ti->flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, ¤t->blocked, syscall); - - if (ti->flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/cris/kernel/ptrace.c b/trunk/arch/cris/kernel/ptrace.c index 48b0f3912632..b326023baab2 100644 --- a/trunk/arch/cris/kernel/ptrace.c +++ b/trunk/arch/cris/kernel/ptrace.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include @@ -37,11 +36,4 @@ void do_notify_resume(int canrestart, struct pt_regs *regs, /* deal with pending signal delivery */ if (thread_info_flags & _TIF_SIGPENDING) do_signal(canrestart,regs); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/frv/kernel/signal.c b/trunk/arch/frv/kernel/signal.c index 6b0a2b6fed6a..4a7a62c6e783 100644 --- a/trunk/arch/frv/kernel/signal.c +++ b/trunk/arch/frv/kernel/signal.c @@ -572,8 +572,6 @@ asmlinkage void do_notify_resume(__u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(__frame); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } /* end do_notify_resume() */ diff --git a/trunk/arch/h8300/include/asm/thread_info.h b/trunk/arch/h8300/include/asm/thread_info.h index 70e67e47d020..8bbc8b0ee45d 100644 --- a/trunk/arch/h8300/include/asm/thread_info.h +++ b/trunk/arch/h8300/include/asm/thread_info.h @@ -89,7 +89,6 @@ static inline struct thread_info *current_thread_info(void) TIF_NEED_RESCHED */ #define TIF_MEMDIE 4 #define TIF_RESTORE_SIGMASK 5 /* restore signal mask in do_signal() */ -#define TIF_NOTIFY_RESUME 6 /* callback before returning to user */ #define TIF_FREEZE 16 /* is freezing for suspend */ /* as above, but as bit values */ @@ -98,7 +97,6 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NEED_RESCHED (1< #include #include -#include #include #include @@ -553,11 +552,4 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) { if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs, NULL); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/ia64/kernel/process.c b/trunk/arch/ia64/kernel/process.c index 89969e950045..5d7c0e5b9e76 100644 --- a/trunk/arch/ia64/kernel/process.c +++ b/trunk/arch/ia64/kernel/process.c @@ -192,8 +192,6 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall) if (test_thread_flag(TIF_NOTIFY_RESUME)) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(&scr->pt); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } /* copy user rbs to kernel rbs */ diff --git a/trunk/arch/m32r/include/asm/thread_info.h b/trunk/arch/m32r/include/asm/thread_info.h index 71578151a403..07bb5bd00e2a 100644 --- a/trunk/arch/m32r/include/asm/thread_info.h +++ b/trunk/arch/m32r/include/asm/thread_info.h @@ -149,7 +149,6 @@ static inline unsigned int get_thread_fault_code(void) #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_SINGLESTEP 3 /* restore singlestep on return to user mode */ #define TIF_IRET 4 /* return with iret */ -#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_RESTORE_SIGMASK 8 /* restore signal mask in do_signal() */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ @@ -161,7 +160,6 @@ static inline unsigned int get_thread_fault_code(void) #define _TIF_NEED_RESCHED (1< #include #include -#include #include #include #include @@ -409,12 +408,5 @@ void do_notify_resume(struct pt_regs *regs, sigset_t *oldset, if (thread_info_flags & _TIF_SIGPENDING) do_signal(regs,oldset); - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } - clear_thread_flag(TIF_IRET); } diff --git a/trunk/arch/mips/include/asm/thread_info.h b/trunk/arch/mips/include/asm/thread_info.h index 01cc1630b66c..f9df720d2e40 100644 --- a/trunk/arch/mips/include/asm/thread_info.h +++ b/trunk/arch/mips/include/asm/thread_info.h @@ -115,7 +115,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define TIF_NEED_RESCHED 2 /* rescheduling necessary */ #define TIF_SYSCALL_AUDIT 3 /* syscall auditing active */ #define TIF_SECCOMP 4 /* secure computing */ -#define TIF_NOTIFY_RESUME 5 /* callback before returning to user */ #define TIF_RESTORE_SIGMASK 9 /* restore signal mask in do_signal() */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ @@ -140,7 +139,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); #define _TIF_NEED_RESCHED (1< #include #include -#include #include #include @@ -701,11 +700,4 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused, /* deal with pending signal delivery */ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK)) do_signal(regs); - - if (thread_info_flags & _TIF_NOTIFY_RESUME) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/mn10300/kernel/signal.c b/trunk/arch/mn10300/kernel/signal.c index a21f43bc68e2..feb2f2e810db 100644 --- a/trunk/arch/mn10300/kernel/signal.c +++ b/trunk/arch/mn10300/kernel/signal.c @@ -568,7 +568,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(__frame); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/parisc/include/asm/thread_info.h b/trunk/arch/parisc/include/asm/thread_info.h index ac775a76bff7..4ce0edfbe969 100644 --- a/trunk/arch/parisc/include/asm/thread_info.h +++ b/trunk/arch/parisc/include/asm/thread_info.h @@ -59,7 +59,6 @@ struct thread_info { #define TIF_MEMDIE 5 #define TIF_RESTORE_SIGMASK 6 /* restore saved signal mask */ #define TIF_FREEZE 7 /* is freezing for suspend */ -#define TIF_NOTIFY_RESUME 8 /* callback before returning to user */ #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -68,9 +67,8 @@ struct thread_info { #define _TIF_32BIT (1 << TIF_32BIT) #define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #define _TIF_FREEZE (1 << TIF_FREEZE) -#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | \ +#define _TIF_USER_WORK_MASK (_TIF_SIGPENDING | \ _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) #endif /* __KERNEL__ */ diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index 8c4712b74dc1..e552e547cb93 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -948,7 +948,7 @@ intr_check_sig: /* As above */ mfctl %cr30,%r1 LDREG TI_FLAGS(%r1),%r19 - ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK|_TIF_NOTIFY_RESUME), %r20 + ldi (_TIF_SIGPENDING|_TIF_RESTORE_SIGMASK), %r20 and,COND(<>) %r19, %r20, %r0 b,n intr_restore /* skip past if we've nothing to do */ diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index 8eb3c63c407a..f82544225e8e 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -646,11 +645,4 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall) if (test_thread_flag(TIF_SIGPENDING) || test_thread_flag(TIF_RESTORE_SIGMASK)) do_signal(regs, in_syscall); - - if (test_thread_flag(TIF_NOTIFY_RESUME)) { - clear_thread_flag(TIF_NOTIFY_RESUME); - tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); - } } diff --git a/trunk/arch/s390/kernel/signal.c b/trunk/arch/s390/kernel/signal.c index 6b4fef877f9d..062bd64e65fa 100644 --- a/trunk/arch/s390/kernel/signal.c +++ b/trunk/arch/s390/kernel/signal.c @@ -536,6 +536,4 @@ void do_notify_resume(struct pt_regs *regs) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } diff --git a/trunk/arch/sh/kernel/signal_32.c b/trunk/arch/sh/kernel/signal_32.c index 04a21883f327..b5afbec1db59 100644 --- a/trunk/arch/sh/kernel/signal_32.c +++ b/trunk/arch/sh/kernel/signal_32.c @@ -640,7 +640,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0, if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/sh/kernel/signal_64.c b/trunk/arch/sh/kernel/signal_64.c index 9e5c9b1d7e98..0663a0ee6021 100644 --- a/trunk/arch/sh/kernel/signal_64.c +++ b/trunk/arch/sh/kernel/signal_64.c @@ -772,7 +772,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/sparc/kernel/signal_32.c b/trunk/arch/sparc/kernel/signal_32.c index 7ce1a1005b1d..181d069a2d44 100644 --- a/trunk/arch/sparc/kernel/signal_32.c +++ b/trunk/arch/sparc/kernel/signal_32.c @@ -590,8 +590,6 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } diff --git a/trunk/arch/sparc/kernel/signal_64.c b/trunk/arch/sparc/kernel/signal_64.c index 647afbda7ae1..ec82d76dc6f2 100644 --- a/trunk/arch/sparc/kernel/signal_64.c +++ b/trunk/arch/sparc/kernel/signal_64.c @@ -613,8 +613,5 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } } - diff --git a/trunk/arch/x86/kernel/signal.c b/trunk/arch/x86/kernel/signal.c index 81e58238c4ce..4c578751e94e 100644 --- a/trunk/arch/x86/kernel/signal.c +++ b/trunk/arch/x86/kernel/signal.c @@ -869,8 +869,6 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) if (thread_info_flags & _TIF_NOTIFY_RESUME) { clear_thread_flag(TIF_NOTIFY_RESUME); tracehook_notify_resume(regs); - if (current->replacement_session_keyring) - key_replace_session_keyring(); } #ifdef CONFIG_X86_32 diff --git a/trunk/drivers/block/aoe/aoe.h b/trunk/drivers/block/aoe/aoe.h index db195abad698..5e41e6dd657b 100644 --- a/trunk/drivers/block/aoe/aoe.h +++ b/trunk/drivers/block/aoe/aoe.h @@ -155,7 +155,7 @@ struct aoedev { u16 fw_ver; /* version of blade's firmware */ struct work_struct work;/* disk create work struct */ struct gendisk *gd; - struct request_queue *blkq; + struct request_queue blkq; struct hd_geometry geo; sector_t ssize; struct timer_list timer; diff --git a/trunk/drivers/block/aoe/aoeblk.c b/trunk/drivers/block/aoe/aoeblk.c index 1e15889c4b98..2307a271bdc9 100644 --- a/trunk/drivers/block/aoe/aoeblk.c +++ b/trunk/drivers/block/aoe/aoeblk.c @@ -264,12 +264,9 @@ aoeblk_gdalloc(void *vp) goto err_disk; } - d->blkq = blk_alloc_queue(GFP_KERNEL); - if (!d->blkq) + blk_queue_make_request(&d->blkq, aoeblk_make_request); + if (bdi_init(&d->blkq.backing_dev_info)) goto err_mempool; - blk_queue_make_request(d->blkq, aoeblk_make_request); - if (bdi_init(&d->blkq->backing_dev_info)) - goto err_blkq; spin_lock_irqsave(&d->lock, flags); gd->major = AOE_MAJOR; gd->first_minor = d->sysminor * AOE_PARTITIONS; @@ -279,7 +276,7 @@ aoeblk_gdalloc(void *vp) snprintf(gd->disk_name, sizeof gd->disk_name, "etherd/e%ld.%d", d->aoemajor, d->aoeminor); - gd->queue = d->blkq; + gd->queue = &d->blkq; d->gd = gd; d->flags &= ~DEVFL_GDALLOC; d->flags |= DEVFL_UP; @@ -290,9 +287,6 @@ aoeblk_gdalloc(void *vp) aoedisk_add_sysfs(d); return; -err_blkq: - blk_cleanup_queue(d->blkq); - d->blkq = NULL; err_mempool: mempool_destroy(d->bufpool); err_disk: diff --git a/trunk/drivers/block/aoe/aoedev.c b/trunk/drivers/block/aoe/aoedev.c index fa67027789aa..eeea477d9601 100644 --- a/trunk/drivers/block/aoe/aoedev.c +++ b/trunk/drivers/block/aoe/aoedev.c @@ -113,7 +113,6 @@ aoedev_freedev(struct aoedev *d) if (d->bufpool) mempool_destroy(d->bufpool); skbpoolfree(d); - blk_cleanup_queue(d->blkq); kfree(d); } diff --git a/trunk/drivers/char/agp/intel-agp.c b/trunk/drivers/char/agp/intel-agp.c index c58557790585..8c9d50db5c3a 100644 --- a/trunk/drivers/char/agp/intel-agp.c +++ b/trunk/drivers/char/agp/intel-agp.c @@ -49,7 +49,6 @@ #define PCI_DEVICE_ID_INTEL_IGDNG_D_HB 0x0040 #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 -#define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 /* cover 915 and 945 variants */ @@ -82,8 +81,7 @@ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_GM45_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G41_HB || \ agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ - agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) + agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB) extern int agp_memory_reserved; @@ -1218,7 +1216,6 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) case PCI_DEVICE_ID_INTEL_G41_HB: case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: - case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: *gtt_offset = *gtt_size = MB(2); break; default: @@ -2198,8 +2195,6 @@ static const struct intel_driver_description { "IGDNG/D", NULL, &intel_i965_driver }, { PCI_DEVICE_ID_INTEL_IGDNG_M_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, "IGDNG/M", NULL, &intel_i965_driver }, - { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, - "IGDNG/MA", NULL, &intel_i965_driver }, { 0, 0, 0, NULL, NULL, NULL } }; @@ -2403,7 +2398,6 @@ static struct pci_device_id agp_intel_pci_table[] = { ID(PCI_DEVICE_ID_INTEL_G41_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), - ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), { } }; diff --git a/trunk/drivers/char/tpm/tpm_tis.c b/trunk/drivers/char/tpm/tpm_tis.c index 0b73e4ec1add..aec1931608aa 100644 --- a/trunk/drivers/char/tpm/tpm_tis.c +++ b/trunk/drivers/char/tpm/tpm_tis.c @@ -450,12 +450,6 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, goto out_err; } - /* Default timeouts */ - chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); - chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); - chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); - chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); - if (request_locality(chip, 0) != 0) { rc = -ENODEV; goto out_err; @@ -463,6 +457,12 @@ static int tpm_tis_init(struct device *dev, resource_size_t start, vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0)); + /* Default timeouts */ + chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); + chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); + chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); + chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); + dev_info(dev, "1.2 TPM (device-id 0x%X, rev-id %d)\n", vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); diff --git a/trunk/drivers/gpu/drm/i915/i915_gem.c b/trunk/drivers/gpu/drm/i915/i915_gem.c index 80e5ba490dc2..0c07a755b3a3 100644 --- a/trunk/drivers/gpu/drm/i915/i915_gem.c +++ b/trunk/drivers/gpu/drm/i915/i915_gem.c @@ -2267,6 +2267,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) fence_list) { old_obj = old_obj_priv->obj; + reg = &dev_priv->fence_regs[old_obj_priv->fence_reg]; + if (old_obj_priv->pin_count) continue; @@ -2288,11 +2290,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) */ i915_gem_object_flush_gpu_write_domain(old_obj); ret = i915_gem_object_wait_rendering(old_obj); - if (ret != 0) { - drm_gem_object_unreference(old_obj); + if (ret != 0) return ret; - } - break; } @@ -2300,14 +2299,10 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj) * Zap this virtual mapping so we can set up a fence again * for this object next time we need it. */ - i915_gem_release_mmap(old_obj); - + i915_gem_release_mmap(reg->obj); i = old_obj_priv->fence_reg; - reg = &dev_priv->fence_regs[i]; - old_obj_priv->fence_reg = I915_FENCE_REG_NONE; list_del_init(&old_obj_priv->fence_list); - drm_gem_object_unreference(old_obj); } @@ -4232,11 +4227,15 @@ int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + int ret; + if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; + ret = i915_gem_idle(dev); drm_irq_uninstall(dev); - return i915_gem_idle(dev); + + return ret; } void diff --git a/trunk/drivers/gpu/drm/i915/intel_display.c b/trunk/drivers/gpu/drm/i915/intel_display.c index 748ed50c55ca..3fadb5358858 100644 --- a/trunk/drivers/gpu/drm/i915/intel_display.c +++ b/trunk/drivers/gpu/drm/i915/intel_display.c @@ -2005,21 +2005,7 @@ static void igd_enable_cxsr(struct drm_device *dev, unsigned long clock, return; } -/* - * Latency for FIFO fetches is dependent on several factors: - * - memory configuration (speed, channels) - * - chipset - * - current MCH state - * It can be fairly high in some situations, so here we assume a fairly - * pessimal value. It's a tradeoff between extra memory fetches (if we - * set this value too high, the FIFO will fetch frequently to stay full) - * and power consumption (set it too low to save power and we might see - * FIFO underruns and display "flicker"). - * - * A value of 5us seems to be a good balance; safe for very low end - * platforms but not overly aggressive on lower latency configs. - */ -const static int latency_ns = 5000; +const static int latency_ns = 3000; /* default for non-igd platforms */ static int intel_get_fifo_size(struct drm_device *dev, int plane) { diff --git a/trunk/drivers/gpu/drm/i915/intel_dp.c b/trunk/drivers/gpu/drm/i915/intel_dp.c index 2b914d732076..f2afc4af4bc9 100644 --- a/trunk/drivers/gpu/drm/i915/intel_dp.c +++ b/trunk/drivers/gpu/drm/i915/intel_dp.c @@ -1263,7 +1263,7 @@ intel_dp_init(struct drm_device *dev, int output_reg) if (IS_eDP(intel_output)) { intel_output->crtc_mask = (1 << 1); - intel_output->clone_mask = (1 << INTEL_EDP_CLONE_BIT); + intel_output->clone_mask = (1 << INTEL_OUTPUT_EDP); } else intel_output->crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = true; diff --git a/trunk/drivers/gpu/drm/i915/intel_drv.h b/trunk/drivers/gpu/drm/i915/intel_drv.h index 26a6227c15fe..25aa6facc12d 100644 --- a/trunk/drivers/gpu/drm/i915/intel_drv.h +++ b/trunk/drivers/gpu/drm/i915/intel_drv.h @@ -74,7 +74,6 @@ #define INTEL_LVDS_CLONE_BIT 14 #define INTEL_DVO_TMDS_CLONE_BIT 15 #define INTEL_DVO_LVDS_CLONE_BIT 16 -#define INTEL_EDP_CLONE_BIT 17 #define INTEL_DVO_CHIP_NONE 0 #define INTEL_DVO_CHIP_LVDS 1 diff --git a/trunk/drivers/gpu/drm/i915/intel_tv.c b/trunk/drivers/gpu/drm/i915/intel_tv.c index 5b1c9e9fdba0..2fbe13a0de81 100644 --- a/trunk/drivers/gpu/drm/i915/intel_tv.c +++ b/trunk/drivers/gpu/drm/i915/intel_tv.c @@ -1730,7 +1730,6 @@ intel_tv_init(struct drm_device *dev) drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc); tv_priv = (struct intel_tv_priv *)(intel_output + 1); intel_output->type = INTEL_OUTPUT_TVOUT; - intel_output->crtc_mask = (1 << 0) | (1 << 1); intel_output->clone_mask = (1 << INTEL_TV_CLONE_BIT); intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1)); intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT); diff --git a/trunk/drivers/gpu/drm/radeon/r300.c b/trunk/drivers/gpu/drm/radeon/r300.c index 051bca6e3a4f..053f4ec397f7 100644 --- a/trunk/drivers/gpu/drm/radeon/r300.c +++ b/trunk/drivers/gpu/drm/radeon/r300.c @@ -995,7 +995,7 @@ static const unsigned r300_reg_safe_bm[159] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, + 0x0003FC01, 0xFFFFFFF8, 0xFE800B19, }; static int r300_packet0_check(struct radeon_cs_parser *p, diff --git a/trunk/drivers/gpu/drm/radeon/radeon_asic.h b/trunk/drivers/gpu/drm/radeon/radeon_asic.h index 93d8f8889302..7ca6c13569b5 100644 --- a/trunk/drivers/gpu/drm/radeon/radeon_asic.h +++ b/trunk/drivers/gpu/drm/radeon/radeon_asic.h @@ -266,7 +266,6 @@ static struct radeon_asic rs400_asic = { /* * rs600. */ -int rs600_init(struct radeon_device *dev); void rs600_errata(struct radeon_device *rdev); void rs600_vram_info(struct radeon_device *rdev); int rs600_mc_init(struct radeon_device *rdev); @@ -282,7 +281,7 @@ uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg); void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void rs600_bandwidth_update(struct radeon_device *rdev); static struct radeon_asic rs600_asic = { - .init = &rs600_init, + .init = &r300_init, .errata = &rs600_errata, .vram_info = &rs600_vram_info, .gpu_reset = &r300_gpu_reset, @@ -317,6 +316,7 @@ static struct radeon_asic rs600_asic = { /* * rs690,rs740 */ +int rs690_init(struct radeon_device *rdev); void rs690_errata(struct radeon_device *rdev); void rs690_vram_info(struct radeon_device *rdev); int rs690_mc_init(struct radeon_device *rdev); @@ -325,7 +325,7 @@ uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg); void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); void rs690_bandwidth_update(struct radeon_device *rdev); static struct radeon_asic rs690_asic = { - .init = &rs600_init, + .init = &rs690_init, .errata = &rs690_errata, .vram_info = &rs690_vram_info, .gpu_reset = &r300_gpu_reset, diff --git a/trunk/drivers/gpu/drm/radeon/rs600.c b/trunk/drivers/gpu/drm/radeon/rs600.c index 02fd11aad6a2..7e8ce983a908 100644 --- a/trunk/drivers/gpu/drm/radeon/rs600.c +++ b/trunk/drivers/gpu/drm/radeon/rs600.c @@ -409,68 +409,3 @@ void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) ((reg) & RS600_MC_ADDR_MASK)); WREG32(RS600_MC_DATA, v); } - -static const unsigned rs600_reg_safe_bm[219] = { - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0x17FF1FFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFF30FFBF, - 0xFFFFFFF8, 0xC3E6FFFF, 0xFFFFF6DF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFF03F, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFEFCE, 0xF00EBFFF, 0x007C0000, - 0xF0000078, 0xFF000009, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFF7FF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFC78, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, - 0x38FF8F50, 0xFFF88082, 0xF000000C, 0xFAE009FF, - 0x0000FFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, - 0x00000000, 0x0000C100, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xFFFF0000, 0xFFFFFFFF, 0xFF80FFFF, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0003FC01, 0xFFFFFCF8, 0xFF800B19, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, - 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, -}; - -int rs600_init(struct radeon_device *rdev) -{ - rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; - rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm); - return 0; -} diff --git a/trunk/drivers/gpu/drm/radeon/rs690.c b/trunk/drivers/gpu/drm/radeon/rs690.c index 879882533e45..bc6b7c5339bc 100644 --- a/trunk/drivers/gpu/drm/radeon/rs690.c +++ b/trunk/drivers/gpu/drm/radeon/rs690.c @@ -653,3 +653,67 @@ void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); } +static const unsigned rs690_reg_safe_bm[219] = { + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF, + 0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000, + 0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF, + 0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF, + 0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000, + 0x00000000,0x0000C100,0x00000000,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF, + 0x00000000,0x00000000,0x00000000,0x00000000, + 0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, + 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF, +}; + +int rs690_init(struct radeon_device *rdev) +{ + rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm; + rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm); + return 0; +} diff --git a/trunk/drivers/gpu/drm/radeon/rv515.c b/trunk/drivers/gpu/drm/radeon/rv515.c index 0566fb67e460..31a7f668ae5a 100644 --- a/trunk/drivers/gpu/drm/radeon/rv515.c +++ b/trunk/drivers/gpu/drm/radeon/rv515.c @@ -508,7 +508,7 @@ static const unsigned r500_reg_safe_bm[219] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFF80FFFF, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x0003FC01, 0x3FFFFCF8, 0xFF800B19, 0xFFDFFFFF, + 0x0003FC01, 0x3FFFFCF8, 0xFE800B19, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, diff --git a/trunk/drivers/ide/ide-cs.c b/trunk/drivers/ide/ide-cs.c index 063b933d864a..527908ff298c 100644 --- a/trunk/drivers/ide/ide-cs.c +++ b/trunk/drivers/ide/ide-cs.c @@ -408,7 +408,6 @@ static struct pcmcia_device_id ide_ids[] = { PCMCIA_DEVICE_PROD_ID123("PCMCIA", "IDE CARD", "F1", 0x281f1c5d, 0x1907960c, 0xf7fde8b9), PCMCIA_DEVICE_PROD_ID12("ARGOSY", "CD-ROM", 0x78f308dc, 0x66536591), PCMCIA_DEVICE_PROD_ID12("ARGOSY", "PnPIDE", 0x78f308dc, 0x0c694728), - PCMCIA_DEVICE_PROD_ID12("CNF ", "CD-ROM", 0x46d7db81, 0x66536591), PCMCIA_DEVICE_PROD_ID12("CNF CD-M", "CD-ROM", 0x7d93b852, 0x66536591), PCMCIA_DEVICE_PROD_ID12("Creative Technology Ltd.", "PCMCIA CD-ROM Interface Card", 0xff8c8a45, 0xfe8020c4), PCMCIA_DEVICE_PROD_ID12("Digital Equipment Corporation.", "Digital Mobile Media CD-ROM", 0x17692a66, 0xef1dcbde), diff --git a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c index e2a63214008a..72aa57cdf697 100644 --- a/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c +++ b/trunk/drivers/infiniband/hw/cxgb3/iwch_provider.c @@ -1418,6 +1418,7 @@ int iwch_register_device(struct iwch_dev *dev) bail2: ib_unregister_device(&dev->ibdev); bail1: + kfree(dev->ibdev.iwcm); return ret; } @@ -1430,5 +1431,6 @@ void iwch_unregister_device(struct iwch_dev *dev) device_remove_file(&dev->ibdev.dev, iwch_class_attributes[i]); ib_unregister_device(&dev->ibdev); + kfree(dev->ibdev.iwcm); return; } diff --git a/trunk/drivers/md/dm-log-userspace-base.c b/trunk/drivers/md/dm-log-userspace-base.c index 652bd33109e3..6e186b1a062d 100644 --- a/trunk/drivers/md/dm-log-userspace-base.c +++ b/trunk/drivers/md/dm-log-userspace-base.c @@ -582,7 +582,7 @@ static int userspace_status(struct dm_dirty_log *log, status_type_t status_type, break; case STATUSTYPE_TABLE: sz = 0; - table_args = strchr(lc->usr_argv_str, ' '); + table_args = strstr(lc->usr_argv_str, " "); BUG_ON(!table_args); /* There will always be a ' ' */ table_args++; diff --git a/trunk/drivers/net/gianfar.c b/trunk/drivers/net/gianfar.c index a00ec639c380..24f7ca5e17de 100644 --- a/trunk/drivers/net/gianfar.c +++ b/trunk/drivers/net/gianfar.c @@ -491,7 +491,7 @@ static int gfar_remove(struct of_device *ofdev) dev_set_drvdata(&ofdev->dev, NULL); - unregister_netdev(priv->ndev); + unregister_netdev(dev); iounmap(priv->regs); free_netdev(priv->ndev); diff --git a/trunk/drivers/net/tun.c b/trunk/drivers/net/tun.c index 87214a257d2a..42b6c6319bc2 100644 --- a/trunk/drivers/net/tun.c +++ b/trunk/drivers/net/tun.c @@ -130,10 +130,17 @@ static inline struct tun_sock *tun_sk(struct sock *sk) static int tun_attach(struct tun_struct *tun, struct file *file) { struct tun_file *tfile = file->private_data; + const struct cred *cred = current_cred(); int err; ASSERT_RTNL(); + /* Check permissions */ + if (((tun->owner != -1 && cred->euid != tun->owner) || + (tun->group != -1 && !in_egroup_p(tun->group))) && + !capable(CAP_NET_ADMIN)) + return -EPERM; + netif_tx_lock_bh(tun->dev); err = -EINVAL; @@ -919,8 +926,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) dev = __dev_get_by_name(net, ifr->ifr_name); if (dev) { - const struct cred *cred = current_cred(); - if (ifr->ifr_flags & IFF_TUN_EXCL) return -EBUSY; if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops) @@ -930,14 +935,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) else return -EINVAL; - if (((tun->owner != -1 && cred->euid != tun->owner) || - (tun->group != -1 && !in_egroup_p(tun->group))) && - !capable(CAP_NET_ADMIN)) - return -EPERM; - err = security_tun_dev_attach(tun->sk); - if (err < 0) - return err; - err = tun_attach(tun, file); if (err < 0) return err; @@ -950,9 +947,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) if (!capable(CAP_NET_ADMIN)) return -EPERM; - err = security_tun_dev_create(); - if (err < 0) - return err; /* Set dev type */ if (ifr->ifr_flags & IFF_TUN) { @@ -995,8 +989,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr) tun->sk = sk; container_of(sk, struct tun_sock, sk)->tun = tun; - security_tun_dev_post_create(sk); - tun_net_init(dev); if (strchr(dev->name, '%')) { diff --git a/trunk/drivers/staging/comedi/comedi_fops.c b/trunk/drivers/staging/comedi/comedi_fops.c index 640f65c6ef84..9d7c99394ec6 100644 --- a/trunk/drivers/staging/comedi/comedi_fops.c +++ b/trunk/drivers/staging/comedi/comedi_fops.c @@ -1752,12 +1752,12 @@ static int comedi_open(struct inode *inode, struct file *file) mutex_lock(&dev->mutex); if (dev->attached) goto ok; - if (!capable(CAP_NET_ADMIN) && dev->in_request_module) { + if (!capable(CAP_SYS_MODULE) && dev->in_request_module) { DPRINTK("in request module\n"); mutex_unlock(&dev->mutex); return -ENODEV; } - if (capable(CAP_NET_ADMIN) && dev->in_request_module) + if (capable(CAP_SYS_MODULE) && dev->in_request_module) goto ok; dev->in_request_module = 1; @@ -1770,8 +1770,8 @@ static int comedi_open(struct inode *inode, struct file *file) dev->in_request_module = 0; - if (!dev->attached && !capable(CAP_NET_ADMIN)) { - DPRINTK("not attached and not CAP_NET_ADMIN\n"); + if (!dev->attached && !capable(CAP_SYS_MODULE)) { + DPRINTK("not attached and not CAP_SYS_MODULE\n"); mutex_unlock(&dev->mutex); return -ENODEV; } diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 7c1e65d54872..b7c1603cd4bd 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -501,22 +501,22 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, } } - if (last_bss > elf_bss) { - /* - * Now fill out the bss section. First pad the last page up - * to the page boundary, and then perform a mmap to make sure - * that there are zero-mapped pages up to and including the - * last bss page. - */ - if (padzero(elf_bss)) { - error = -EFAULT; - goto out_close; - } + /* + * Now fill out the bss section. First pad the last page up + * to the page boundary, and then perform a mmap to make sure + * that there are zero-mapped pages up to and including the + * last bss page. + */ + if (padzero(elf_bss)) { + error = -EFAULT; + goto out_close; + } - /* What we have mapped so far */ - elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); + /* What we have mapped so far */ + elf_bss = ELF_PAGESTART(elf_bss + ELF_MIN_ALIGN - 1); - /* Map the last of the bss segment */ + /* Map the last of the bss segment */ + if (last_bss > elf_bss) { down_write(¤t->mm->mmap_sem); error = do_brk(elf_bss, last_bss - elf_bss); up_write(¤t->mm->mmap_sem); diff --git a/trunk/fs/ext2/acl.c b/trunk/fs/ext2/acl.c index a63d44256a70..d636e1297cad 100644 --- a/trunk/fs/ext2/acl.c +++ b/trunk/fs/ext2/acl.c @@ -230,7 +230,7 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return error; } -int +static int ext2_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = ext2_get_acl(inode, ACL_TYPE_ACCESS); @@ -246,6 +246,12 @@ ext2_check_acl(struct inode *inode, int mask) return -EAGAIN; } +int +ext2_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, ext2_check_acl); +} + /* * Initialize the ACLs of a new inode. Called from ext2_new_inode. * diff --git a/trunk/fs/ext2/acl.h b/trunk/fs/ext2/acl.h index 3ff6cbb9ac44..ecefe478898f 100644 --- a/trunk/fs/ext2/acl.h +++ b/trunk/fs/ext2/acl.h @@ -54,13 +54,13 @@ static inline int ext2_acl_count(size_t size) #ifdef CONFIG_EXT2_FS_POSIX_ACL /* acl.c */ -extern int ext2_check_acl (struct inode *, int); +extern int ext2_permission (struct inode *, int); extern int ext2_acl_chmod (struct inode *); extern int ext2_init_acl (struct inode *, struct inode *); #else #include -#define ext2_check_acl NULL +#define ext2_permission NULL #define ext2_get_acl NULL #define ext2_set_acl NULL diff --git a/trunk/fs/ext2/file.c b/trunk/fs/ext2/file.c index a2f3afd1a1c1..2b9e47dc9222 100644 --- a/trunk/fs/ext2/file.c +++ b/trunk/fs/ext2/file.c @@ -85,6 +85,6 @@ const struct inode_operations ext2_file_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .permission = ext2_permission, .fiemap = ext2_fiemap, }; diff --git a/trunk/fs/ext2/namei.c b/trunk/fs/ext2/namei.c index 23701f289e98..78d9b925fc94 100644 --- a/trunk/fs/ext2/namei.c +++ b/trunk/fs/ext2/namei.c @@ -400,7 +400,7 @@ const struct inode_operations ext2_dir_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .permission = ext2_permission, }; const struct inode_operations ext2_special_inode_operations = { @@ -411,5 +411,5 @@ const struct inode_operations ext2_special_inode_operations = { .removexattr = generic_removexattr, #endif .setattr = ext2_setattr, - .check_acl = ext2_check_acl, + .permission = ext2_permission, }; diff --git a/trunk/fs/ext3/acl.c b/trunk/fs/ext3/acl.c index c9b0df376b5f..e167bae37ef0 100644 --- a/trunk/fs/ext3/acl.c +++ b/trunk/fs/ext3/acl.c @@ -238,7 +238,7 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type, return error; } -int +static int ext3_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = ext3_get_acl(inode, ACL_TYPE_ACCESS); @@ -254,6 +254,12 @@ ext3_check_acl(struct inode *inode, int mask) return -EAGAIN; } +int +ext3_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, ext3_check_acl); +} + /* * Initialize the ACLs of a new inode. Called from ext3_new_inode. * diff --git a/trunk/fs/ext3/acl.h b/trunk/fs/ext3/acl.h index 597334626de9..07d15a3a5969 100644 --- a/trunk/fs/ext3/acl.h +++ b/trunk/fs/ext3/acl.h @@ -54,13 +54,13 @@ static inline int ext3_acl_count(size_t size) #ifdef CONFIG_EXT3_FS_POSIX_ACL /* acl.c */ -extern int ext3_check_acl (struct inode *, int); +extern int ext3_permission (struct inode *, int); extern int ext3_acl_chmod (struct inode *); extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT3_FS_POSIX_ACL */ #include -#define ext3_check_acl NULL +#define ext3_permission NULL static inline int ext3_acl_chmod(struct inode *inode) diff --git a/trunk/fs/ext3/file.c b/trunk/fs/ext3/file.c index 299253214789..5b49704b231b 100644 --- a/trunk/fs/ext3/file.c +++ b/trunk/fs/ext3/file.c @@ -137,7 +137,7 @@ const struct inode_operations ext3_file_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .permission = ext3_permission, .fiemap = ext3_fiemap, }; diff --git a/trunk/fs/ext3/namei.c b/trunk/fs/ext3/namei.c index aad6400c9b77..6ff7b9730234 100644 --- a/trunk/fs/ext3/namei.c +++ b/trunk/fs/ext3/namei.c @@ -2445,7 +2445,7 @@ const struct inode_operations ext3_dir_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .permission = ext3_permission, }; const struct inode_operations ext3_special_inode_operations = { @@ -2456,5 +2456,5 @@ const struct inode_operations ext3_special_inode_operations = { .listxattr = ext3_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext3_check_acl, + .permission = ext3_permission, }; diff --git a/trunk/fs/ext4/acl.c b/trunk/fs/ext4/acl.c index 0df88b2a69b0..f6d8967149ca 100644 --- a/trunk/fs/ext4/acl.c +++ b/trunk/fs/ext4/acl.c @@ -236,7 +236,7 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type, return error; } -int +static int ext4_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = ext4_get_acl(inode, ACL_TYPE_ACCESS); @@ -252,6 +252,12 @@ ext4_check_acl(struct inode *inode, int mask) return -EAGAIN; } +int +ext4_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, ext4_check_acl); +} + /* * Initialize the ACLs of a new inode. Called from ext4_new_inode. * diff --git a/trunk/fs/ext4/acl.h b/trunk/fs/ext4/acl.h index 9d843d5deac4..949789d2bba6 100644 --- a/trunk/fs/ext4/acl.h +++ b/trunk/fs/ext4/acl.h @@ -54,13 +54,13 @@ static inline int ext4_acl_count(size_t size) #ifdef CONFIG_EXT4_FS_POSIX_ACL /* acl.c */ -extern int ext4_check_acl(struct inode *, int); +extern int ext4_permission(struct inode *, int); extern int ext4_acl_chmod(struct inode *); extern int ext4_init_acl(handle_t *, struct inode *, struct inode *); #else /* CONFIG_EXT4_FS_POSIX_ACL */ #include -#define ext4_check_acl NULL +#define ext4_permission NULL static inline int ext4_acl_chmod(struct inode *inode) diff --git a/trunk/fs/ext4/file.c b/trunk/fs/ext4/file.c index 27f3c5354c0e..3f1873fef1c6 100644 --- a/trunk/fs/ext4/file.c +++ b/trunk/fs/ext4/file.c @@ -207,7 +207,7 @@ const struct inode_operations ext4_file_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .permission = ext4_permission, .fallocate = ext4_fallocate, .fiemap = ext4_fiemap, }; diff --git a/trunk/fs/ext4/namei.c b/trunk/fs/ext4/namei.c index 114abe5d2c1d..de04013d16ff 100644 --- a/trunk/fs/ext4/namei.c +++ b/trunk/fs/ext4/namei.c @@ -2536,7 +2536,7 @@ const struct inode_operations ext4_dir_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .permission = ext4_permission, .fiemap = ext4_fiemap, }; @@ -2548,5 +2548,5 @@ const struct inode_operations ext4_special_inode_operations = { .listxattr = ext4_listxattr, .removexattr = generic_removexattr, #endif - .check_acl = ext4_check_acl, + .permission = ext4_permission, }; diff --git a/trunk/fs/jffs2/acl.c b/trunk/fs/jffs2/acl.c index 7edb62e97419..8fcb6239218e 100644 --- a/trunk/fs/jffs2/acl.c +++ b/trunk/fs/jffs2/acl.c @@ -258,7 +258,7 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl) return rc; } -int jffs2_check_acl(struct inode *inode, int mask) +static int jffs2_check_acl(struct inode *inode, int mask) { struct posix_acl *acl; int rc; @@ -274,6 +274,11 @@ int jffs2_check_acl(struct inode *inode, int mask) return -EAGAIN; } +int jffs2_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, jffs2_check_acl); +} + int jffs2_init_acl_pre(struct inode *dir_i, struct inode *inode, int *i_mode) { struct posix_acl *acl, *clone; diff --git a/trunk/fs/jffs2/acl.h b/trunk/fs/jffs2/acl.h index f0ba63e3c36b..fc929f2a14f6 100644 --- a/trunk/fs/jffs2/acl.h +++ b/trunk/fs/jffs2/acl.h @@ -26,7 +26,7 @@ struct jffs2_acl_header { #ifdef CONFIG_JFFS2_FS_POSIX_ACL -extern int jffs2_check_acl(struct inode *, int); +extern int jffs2_permission(struct inode *, int); extern int jffs2_acl_chmod(struct inode *); extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); extern int jffs2_init_acl_post(struct inode *); @@ -36,7 +36,7 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler; #else -#define jffs2_check_acl (NULL) +#define jffs2_permission (NULL) #define jffs2_acl_chmod(inode) (0) #define jffs2_init_acl_pre(dir_i,inode,mode) (0) #define jffs2_init_acl_post(inode) (0) diff --git a/trunk/fs/jffs2/dir.c b/trunk/fs/jffs2/dir.c index 7aa4417e085f..6f60cc910f4c 100644 --- a/trunk/fs/jffs2/dir.c +++ b/trunk/fs/jffs2/dir.c @@ -55,7 +55,7 @@ const struct inode_operations jffs2_dir_inode_operations = .rmdir = jffs2_rmdir, .mknod = jffs2_mknod, .rename = jffs2_rename, - .check_acl = jffs2_check_acl, + .permission = jffs2_permission, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/trunk/fs/jffs2/file.c b/trunk/fs/jffs2/file.c index b7b74e299142..23c947539864 100644 --- a/trunk/fs/jffs2/file.c +++ b/trunk/fs/jffs2/file.c @@ -56,7 +56,7 @@ const struct file_operations jffs2_file_operations = const struct inode_operations jffs2_file_inode_operations = { - .check_acl = jffs2_check_acl, + .permission = jffs2_permission, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/trunk/fs/jffs2/symlink.c b/trunk/fs/jffs2/symlink.c index 4ec11e8bda8c..b7339c3b6ad9 100644 --- a/trunk/fs/jffs2/symlink.c +++ b/trunk/fs/jffs2/symlink.c @@ -21,7 +21,7 @@ const struct inode_operations jffs2_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = jffs2_follow_link, - .check_acl = jffs2_check_acl, + .permission = jffs2_permission, .setattr = jffs2_setattr, .setxattr = jffs2_setxattr, .getxattr = jffs2_getxattr, diff --git a/trunk/fs/jfs/acl.c b/trunk/fs/jfs/acl.c index d66477c34306..a29c7c3e3fb8 100644 --- a/trunk/fs/jfs/acl.c +++ b/trunk/fs/jfs/acl.c @@ -114,7 +114,7 @@ static int jfs_set_acl(tid_t tid, struct inode *inode, int type, return rc; } -int jfs_check_acl(struct inode *inode, int mask) +static int jfs_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = jfs_get_acl(inode, ACL_TYPE_ACCESS); @@ -129,6 +129,11 @@ int jfs_check_acl(struct inode *inode, int mask) return -EAGAIN; } +int jfs_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, jfs_check_acl); +} + int jfs_init_acl(tid_t tid, struct inode *inode, struct inode *dir) { struct posix_acl *acl = NULL; diff --git a/trunk/fs/jfs/file.c b/trunk/fs/jfs/file.c index 2b70fa78e4a7..7f6063acaa3b 100644 --- a/trunk/fs/jfs/file.c +++ b/trunk/fs/jfs/file.c @@ -96,7 +96,7 @@ const struct inode_operations jfs_file_inode_operations = { .removexattr = jfs_removexattr, #ifdef CONFIG_JFS_POSIX_ACL .setattr = jfs_setattr, - .check_acl = jfs_check_acl, + .permission = jfs_permission, #endif }; diff --git a/trunk/fs/jfs/jfs_acl.h b/trunk/fs/jfs/jfs_acl.h index b07bd417ef85..88475f10a389 100644 --- a/trunk/fs/jfs/jfs_acl.h +++ b/trunk/fs/jfs/jfs_acl.h @@ -20,7 +20,7 @@ #ifdef CONFIG_JFS_POSIX_ACL -int jfs_check_acl(struct inode *, int); +int jfs_permission(struct inode *, int); int jfs_init_acl(tid_t, struct inode *, struct inode *); int jfs_setattr(struct dentry *, struct iattr *); diff --git a/trunk/fs/jfs/namei.c b/trunk/fs/jfs/namei.c index c79a4270f083..514ee2edb92a 100644 --- a/trunk/fs/jfs/namei.c +++ b/trunk/fs/jfs/namei.c @@ -1543,7 +1543,7 @@ const struct inode_operations jfs_dir_inode_operations = { .removexattr = jfs_removexattr, #ifdef CONFIG_JFS_POSIX_ACL .setattr = jfs_setattr, - .check_acl = jfs_check_acl, + .permission = jfs_permission, #endif }; diff --git a/trunk/fs/locks.c b/trunk/fs/locks.c index 52366e877d76..b6440f52178f 100644 --- a/trunk/fs/locks.c +++ b/trunk/fs/locks.c @@ -1591,7 +1591,7 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) if (can_sleep) lock->fl_flags |= FL_SLEEP; - error = security_file_lock(filp, lock->fl_type); + error = security_file_lock(filp, cmd); if (error) goto out_free; diff --git a/trunk/fs/namei.c b/trunk/fs/namei.c index d11f404667e9..f3c5b278895a 100644 --- a/trunk/fs/namei.c +++ b/trunk/fs/namei.c @@ -169,10 +169,19 @@ void putname(const char *name) EXPORT_SYMBOL(putname); #endif -/* - * This does basic POSIX ACL permission checking + +/** + * generic_permission - check for access rights on a Posix-like filesystem + * @inode: inode to check access rights for + * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) + * @check_acl: optional callback to check for Posix ACLs + * + * Used to check for read/write/execute permissions on a file. + * We use "fsuid" for this, letting us set arbitrary permissions + * for filesystem access without changing the "normal" uids which + * are used for other things.. */ -static int acl_permission_check(struct inode *inode, int mask, +int generic_permission(struct inode *inode, int mask, int (*check_acl)(struct inode *inode, int mask)) { umode_t mode = inode->i_mode; @@ -184,7 +193,9 @@ static int acl_permission_check(struct inode *inode, int mask, else { if (IS_POSIXACL(inode) && (mode & S_IRWXG) && check_acl) { int error = check_acl(inode, mask); - if (error != -EAGAIN) + if (error == -EACCES) + goto check_capabilities; + else if (error != -EAGAIN) return error; } @@ -197,32 +208,8 @@ static int acl_permission_check(struct inode *inode, int mask, */ if ((mask & ~mode) == 0) return 0; - return -EACCES; -} - -/** - * generic_permission - check for access rights on a Posix-like filesystem - * @inode: inode to check access rights for - * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) - * @check_acl: optional callback to check for Posix ACLs - * - * Used to check for read/write/execute permissions on a file. - * We use "fsuid" for this, letting us set arbitrary permissions - * for filesystem access without changing the "normal" uids which - * are used for other things.. - */ -int generic_permission(struct inode *inode, int mask, - int (*check_acl)(struct inode *inode, int mask)) -{ - int ret; - - /* - * Do the basic POSIX ACL permission checks. - */ - ret = acl_permission_check(inode, mask, check_acl); - if (ret != -EACCES) - return ret; + check_capabilities: /* * Read/write DACs are always overridable. * Executable DACs are overridable if at least one exec bit is set. @@ -275,7 +262,7 @@ int inode_permission(struct inode *inode, int mask) if (inode->i_op->permission) retval = inode->i_op->permission(inode, mask); else - retval = generic_permission(inode, mask, inode->i_op->check_acl); + retval = generic_permission(inode, mask, NULL); if (retval) return retval; @@ -445,22 +432,29 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, */ static int exec_permission_lite(struct inode *inode) { - int ret; + umode_t mode = inode->i_mode; - if (inode->i_op->permission) { - ret = inode->i_op->permission(inode, MAY_EXEC); - if (!ret) - goto ok; - return ret; - } - ret = acl_permission_check(inode, MAY_EXEC, inode->i_op->check_acl); - if (!ret) + if (inode->i_op->permission) + return -EAGAIN; + + if (current_fsuid() == inode->i_uid) + mode >>= 6; + else if (in_group_p(inode->i_gid)) + mode >>= 3; + + if (mode & MAY_EXEC) goto ok; - if (capable(CAP_DAC_OVERRIDE) || capable(CAP_DAC_READ_SEARCH)) + if ((inode->i_mode & S_IXUGO) && capable(CAP_DAC_OVERRIDE)) goto ok; - return ret; + if (S_ISDIR(inode->i_mode) && capable(CAP_DAC_OVERRIDE)) + goto ok; + + if (S_ISDIR(inode->i_mode) && capable(CAP_DAC_READ_SEARCH)) + goto ok; + + return -EACCES; ok: return security_inode_permission(inode, MAY_EXEC); } @@ -859,6 +853,12 @@ static int __link_path_walk(const char *name, struct nameidata *nd) nd->flags |= LOOKUP_CONTINUE; err = exec_permission_lite(inode); + if (err == -EAGAIN) + err = inode_permission(nd->path.dentry->d_inode, + MAY_EXEC); + if (!err) + err = ima_path_check(&nd->path, MAY_EXEC, + IMA_COUNT_UPDATE); if (err) break; @@ -1533,42 +1533,37 @@ int may_open(struct path *path, int acc_mode, int flag) if (error) return error; - error = ima_path_check(path, acc_mode ? - acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) : - ACC_MODE(flag) & (MAY_READ | MAY_WRITE), + error = ima_path_check(path, + acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC), IMA_COUNT_UPDATE); - if (error) return error; /* * An append-only file must be opened in append mode for writing. */ if (IS_APPEND(inode)) { - error = -EPERM; if ((flag & FMODE_WRITE) && !(flag & O_APPEND)) - goto err_out; + return -EPERM; if (flag & O_TRUNC) - goto err_out; + return -EPERM; } /* O_NOATIME can only be set by the owner or superuser */ if (flag & O_NOATIME) - if (!is_owner_or_cap(inode)) { - error = -EPERM; - goto err_out; - } + if (!is_owner_or_cap(inode)) + return -EPERM; /* * Ensure there are no outstanding leases on the file. */ error = break_lease(inode, flag); if (error) - goto err_out; + return error; if (flag & O_TRUNC) { error = get_write_access(inode); if (error) - goto err_out; + return error; /* * Refuse to truncate files with mandatory locks held on them. @@ -1586,17 +1581,12 @@ int may_open(struct path *path, int acc_mode, int flag) } put_write_access(inode); if (error) - goto err_out; + return error; } else if (flag & FMODE_WRITE) vfs_dq_init(inode); return 0; -err_out: - ima_counts_put(path, acc_mode ? - acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC) : - ACC_MODE(flag) & (MAY_READ | MAY_WRITE)); - return error; } /* diff --git a/trunk/fs/nfsd/auth.c b/trunk/fs/nfsd/auth.c index 36fcabbf5186..5573508f707f 100644 --- a/trunk/fs/nfsd/auth.c +++ b/trunk/fs/nfsd/auth.c @@ -34,8 +34,6 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) int flags = nfsexp_flags(rqstp, exp); int ret; - validate_process_creds(); - /* discard any old override before preparing the new set */ revert_creds(get_cred(current->real_cred)); new = prepare_creds(); @@ -88,10 +86,8 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp) else new->cap_effective = cap_raise_nfsd_set(new->cap_effective, new->cap_permitted); - validate_process_creds(); put_cred(override_creds(new)); put_cred(new); - validate_process_creds(); return 0; oom: diff --git a/trunk/fs/nfsd/nfssvc.c b/trunk/fs/nfsd/nfssvc.c index 24d58adfe5fd..492c79b7800b 100644 --- a/trunk/fs/nfsd/nfssvc.c +++ b/trunk/fs/nfsd/nfssvc.c @@ -496,9 +496,7 @@ nfsd(void *vrqstp) /* Lock the export hash tables for reading. */ exp_readlock(); - validate_process_creds(); svc_process(rqstp); - validate_process_creds(); /* Unlock export hash tables */ exp_readunlock(); diff --git a/trunk/fs/nfsd/vfs.c b/trunk/fs/nfsd/vfs.c index 8fa09bfbcba7..23341c1063bc 100644 --- a/trunk/fs/nfsd/vfs.c +++ b/trunk/fs/nfsd/vfs.c @@ -684,8 +684,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, __be32 err; int host_err; - validate_process_creds(); - /* * If we get here, then the client has already done an "open", * and (hopefully) checked permission - so allow OWNER_OVERRIDE @@ -742,7 +740,6 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, out_nfserr: err = nfserrno(host_err); out: - validate_process_creds(); return err; } diff --git a/trunk/fs/open.c b/trunk/fs/open.c index 31191bf513e4..dd98e8076024 100644 --- a/trunk/fs/open.c +++ b/trunk/fs/open.c @@ -199,7 +199,7 @@ SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, struct file *filp) { - int ret; + int err; struct iattr newattrs; /* Not pretty: "inode->i_size" shouldn't really be signed. But it is. */ @@ -214,14 +214,12 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, } /* Remove suid/sgid on truncate too */ - ret = should_remove_suid(dentry); - if (ret) - newattrs.ia_valid |= ret | ATTR_FORCE; + newattrs.ia_valid |= should_remove_suid(dentry); mutex_lock(&dentry->d_inode->i_mutex); - ret = notify_change(dentry, &newattrs); + err = notify_change(dentry, &newattrs); mutex_unlock(&dentry->d_inode->i_mutex); - return ret; + return err; } static long do_sys_truncate(const char __user *pathname, loff_t length) @@ -959,8 +957,6 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags, int error; struct file *f; - validate_creds(cred); - /* * We must always pass in a valid mount pointer. Historically * callers got away with not passing it, but we must enforce this at diff --git a/trunk/fs/sysfs/dir.c b/trunk/fs/sysfs/dir.c index 0050fc40e8c9..14f2d71ea3ce 100644 --- a/trunk/fs/sysfs/dir.c +++ b/trunk/fs/sysfs/dir.c @@ -760,7 +760,6 @@ static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, const struct inode_operations sysfs_dir_inode_operations = { .lookup = sysfs_lookup, .setattr = sysfs_setattr, - .setxattr = sysfs_setxattr, }; static void remove_dir(struct sysfs_dirent *sd) diff --git a/trunk/fs/sysfs/inode.c b/trunk/fs/sysfs/inode.c index 2b6a8d9de73d..555f0ff988df 100644 --- a/trunk/fs/sysfs/inode.c +++ b/trunk/fs/sysfs/inode.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include "sysfs.h" extern struct super_block * sysfs_sb; @@ -37,7 +35,6 @@ static struct backing_dev_info sysfs_backing_dev_info = { static const struct inode_operations sysfs_inode_operations ={ .setattr = sysfs_setattr, - .setxattr = sysfs_setxattr, }; int __init sysfs_inode_init(void) @@ -45,37 +42,18 @@ int __init sysfs_inode_init(void) return bdi_init(&sysfs_backing_dev_info); } -struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd) -{ - struct sysfs_inode_attrs *attrs; - struct iattr *iattrs; - - attrs = kzalloc(sizeof(struct sysfs_inode_attrs), GFP_KERNEL); - if (!attrs) - return NULL; - iattrs = &attrs->ia_iattr; - - /* assign default attributes */ - iattrs->ia_mode = sd->s_mode; - iattrs->ia_uid = 0; - iattrs->ia_gid = 0; - iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME; - - return attrs; -} int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) { struct inode * inode = dentry->d_inode; struct sysfs_dirent * sd = dentry->d_fsdata; - struct sysfs_inode_attrs *sd_attrs; - struct iattr *iattrs; + struct iattr * sd_iattr; unsigned int ia_valid = iattr->ia_valid; int error; if (!sd) return -EINVAL; - sd_attrs = sd->s_iattr; + sd_iattr = sd->s_iattr; error = inode_change_ok(inode, iattr); if (error) @@ -87,77 +65,42 @@ int sysfs_setattr(struct dentry * dentry, struct iattr * iattr) if (error) return error; - if (!sd_attrs) { + if (!sd_iattr) { /* setting attributes for the first time, allocate now */ - sd_attrs = sysfs_init_inode_attrs(sd); - if (!sd_attrs) + sd_iattr = kzalloc(sizeof(struct iattr), GFP_KERNEL); + if (!sd_iattr) return -ENOMEM; - sd->s_iattr = sd_attrs; - } else { - /* attributes were changed at least once in past */ - iattrs = &sd_attrs->ia_iattr; - - if (ia_valid & ATTR_UID) - iattrs->ia_uid = iattr->ia_uid; - if (ia_valid & ATTR_GID) - iattrs->ia_gid = iattr->ia_gid; - if (ia_valid & ATTR_ATIME) - iattrs->ia_atime = timespec_trunc(iattr->ia_atime, - inode->i_sb->s_time_gran); - if (ia_valid & ATTR_MTIME) - iattrs->ia_mtime = timespec_trunc(iattr->ia_mtime, - inode->i_sb->s_time_gran); - if (ia_valid & ATTR_CTIME) - iattrs->ia_ctime = timespec_trunc(iattr->ia_ctime, - inode->i_sb->s_time_gran); - if (ia_valid & ATTR_MODE) { - umode_t mode = iattr->ia_mode; - - if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) - mode &= ~S_ISGID; - iattrs->ia_mode = sd->s_mode = mode; - } + /* assign default attributes */ + sd_iattr->ia_mode = sd->s_mode; + sd_iattr->ia_uid = 0; + sd_iattr->ia_gid = 0; + sd_iattr->ia_atime = sd_iattr->ia_mtime = sd_iattr->ia_ctime = CURRENT_TIME; + sd->s_iattr = sd_iattr; } - return error; -} - -int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) -{ - struct sysfs_dirent *sd = dentry->d_fsdata; - struct sysfs_inode_attrs *iattrs; - void *secdata; - int error; - u32 secdata_len = 0; - if (!sd) - return -EINVAL; - if (!sd->s_iattr) - sd->s_iattr = sysfs_init_inode_attrs(sd); - if (!sd->s_iattr) - return -ENOMEM; - - iattrs = sd->s_iattr; - - if (!strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)) { - const char *suffix = name + XATTR_SECURITY_PREFIX_LEN; - error = security_inode_setsecurity(dentry->d_inode, suffix, - value, size, flags); - if (error) - goto out; - error = security_inode_getsecctx(dentry->d_inode, - &secdata, &secdata_len); - if (error) - goto out; - if (iattrs->ia_secdata) - security_release_secctx(iattrs->ia_secdata, - iattrs->ia_secdata_len); - iattrs->ia_secdata = secdata; - iattrs->ia_secdata_len = secdata_len; + /* attributes were changed atleast once in past */ + + if (ia_valid & ATTR_UID) + sd_iattr->ia_uid = iattr->ia_uid; + if (ia_valid & ATTR_GID) + sd_iattr->ia_gid = iattr->ia_gid; + if (ia_valid & ATTR_ATIME) + sd_iattr->ia_atime = timespec_trunc(iattr->ia_atime, + inode->i_sb->s_time_gran); + if (ia_valid & ATTR_MTIME) + sd_iattr->ia_mtime = timespec_trunc(iattr->ia_mtime, + inode->i_sb->s_time_gran); + if (ia_valid & ATTR_CTIME) + sd_iattr->ia_ctime = timespec_trunc(iattr->ia_ctime, + inode->i_sb->s_time_gran); + if (ia_valid & ATTR_MODE) { + umode_t mode = iattr->ia_mode; + + if (!in_group_p(inode->i_gid) && !capable(CAP_FSETID)) + mode &= ~S_ISGID; + sd_iattr->ia_mode = sd->s_mode = mode; + } - } else - return -EINVAL; -out: return error; } @@ -203,7 +146,6 @@ static int sysfs_count_nlink(struct sysfs_dirent *sd) static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) { struct bin_attribute *bin_attr; - struct sysfs_inode_attrs *iattrs; inode->i_private = sysfs_get(sd); inode->i_mapping->a_ops = &sysfs_aops; @@ -212,20 +154,16 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) inode->i_ino = sd->s_ino; lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key); - iattrs = sd->s_iattr; - if (iattrs) { + if (sd->s_iattr) { /* sysfs_dirent has non-default attributes * get them for the new inode from persistent copy * in sysfs_dirent */ - set_inode_attr(inode, &iattrs->ia_iattr); - if (iattrs->ia_secdata) - security_inode_notifysecctx(inode, - iattrs->ia_secdata, - iattrs->ia_secdata_len); + set_inode_attr(inode, sd->s_iattr); } else set_default_inode_attr(inode, sd->s_mode); + /* initialize inode according to type */ switch (sysfs_type(sd)) { case SYSFS_DIR: diff --git a/trunk/fs/sysfs/symlink.c b/trunk/fs/sysfs/symlink.c index c5081ad77026..1d897ad808e0 100644 --- a/trunk/fs/sysfs/symlink.c +++ b/trunk/fs/sysfs/symlink.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "sysfs.h" @@ -210,7 +209,6 @@ static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *co } const struct inode_operations sysfs_symlink_inode_operations = { - .setxattr = sysfs_setxattr, .readlink = generic_readlink, .follow_link = sysfs_follow_link, .put_link = sysfs_put_link, diff --git a/trunk/fs/sysfs/sysfs.h b/trunk/fs/sysfs/sysfs.h index af4c4e7482ac..3fa0d98481e2 100644 --- a/trunk/fs/sysfs/sysfs.h +++ b/trunk/fs/sysfs/sysfs.h @@ -8,8 +8,6 @@ * This file is released under the GPLv2. */ -#include - struct sysfs_open_dirent; /* type-specific structures for sysfs_dirent->s_* union members */ @@ -33,12 +31,6 @@ struct sysfs_elem_bin_attr { struct hlist_head buffers; }; -struct sysfs_inode_attrs { - struct iattr ia_iattr; - void *ia_secdata; - u32 ia_secdata_len; -}; - /* * sysfs_dirent - the building block of sysfs hierarchy. Each and * every sysfs node is represented by single sysfs_dirent. @@ -64,7 +56,7 @@ struct sysfs_dirent { unsigned int s_flags; ino_t s_ino; umode_t s_mode; - struct sysfs_inode_attrs *s_iattr; + struct iattr *s_iattr; }; #define SD_DEACTIVATED_BIAS INT_MIN @@ -156,8 +148,6 @@ static inline void __sysfs_put(struct sysfs_dirent *sd) struct inode *sysfs_get_inode(struct sysfs_dirent *sd); void sysfs_delete_inode(struct inode *inode); int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); -int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags); int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const char *name); int sysfs_inode_init(void); diff --git a/trunk/fs/xattr.c b/trunk/fs/xattr.c index 6d4f6d3449fb..1c3d0af59ddf 100644 --- a/trunk/fs/xattr.c +++ b/trunk/fs/xattr.c @@ -66,28 +66,22 @@ xattr_permission(struct inode *inode, const char *name, int mask) return inode_permission(inode, mask); } -/** - * __vfs_setxattr_noperm - perform setxattr operation without performing - * permission checks. - * - * @dentry - object to perform setxattr on - * @name - xattr name to set - * @value - value to set @name to - * @size - size of @value - * @flags - flags to pass into filesystem operations - * - * returns the result of the internal setxattr or setsecurity operations. - * - * This function requires the caller to lock the inode's i_mutex before it - * is executed. It also assumes that the caller will make the appropriate - * permission checks. - */ -int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, - const void *value, size_t size, int flags) +int +vfs_setxattr(struct dentry *dentry, const char *name, const void *value, + size_t size, int flags) { struct inode *inode = dentry->d_inode; - int error = -EOPNOTSUPP; + int error; + + error = xattr_permission(inode, name, MAY_WRITE); + if (error) + return error; + mutex_lock(&inode->i_mutex); + error = security_inode_setxattr(dentry, name, value, size, flags); + if (error) + goto out; + error = -EOPNOTSUPP; if (inode->i_op->setxattr) { error = inode->i_op->setxattr(dentry, name, value, size, flags); if (!error) { @@ -103,29 +97,6 @@ int __vfs_setxattr_noperm(struct dentry *dentry, const char *name, if (!error) fsnotify_xattr(dentry); } - - return error; -} - - -int -vfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t size, int flags) -{ - struct inode *inode = dentry->d_inode; - int error; - - error = xattr_permission(inode, name, MAY_WRITE); - if (error) - return error; - - mutex_lock(&inode->i_mutex); - error = security_inode_setxattr(dentry, name, value, size, flags); - if (error) - goto out; - - error = __vfs_setxattr_noperm(dentry, name, value, size, flags); - out: mutex_unlock(&inode->i_mutex); return error; diff --git a/trunk/fs/xfs/linux-2.6/xfs_iops.c b/trunk/fs/xfs/linux-2.6/xfs_iops.c index 6c32f1d63d8c..8070b34cc287 100644 --- a/trunk/fs/xfs/linux-2.6/xfs_iops.c +++ b/trunk/fs/xfs/linux-2.6/xfs_iops.c @@ -484,6 +484,14 @@ xfs_vn_put_link( kfree(s); } +STATIC int +xfs_vn_permission( + struct inode *inode, + int mask) +{ + return generic_permission(inode, mask, xfs_check_acl); +} + STATIC int xfs_vn_getattr( struct vfsmount *mnt, @@ -688,7 +696,7 @@ xfs_vn_fiemap( } static const struct inode_operations xfs_inode_operations = { - .check_acl = xfs_check_acl, + .permission = xfs_vn_permission, .truncate = xfs_vn_truncate, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, @@ -716,7 +724,7 @@ static const struct inode_operations xfs_dir_inode_operations = { .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, .rename = xfs_vn_rename, - .check_acl = xfs_check_acl, + .permission = xfs_vn_permission, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -741,7 +749,7 @@ static const struct inode_operations xfs_dir_ci_inode_operations = { .rmdir = xfs_vn_unlink, .mknod = xfs_vn_mknod, .rename = xfs_vn_rename, - .check_acl = xfs_check_acl, + .permission = xfs_vn_permission, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, @@ -754,7 +762,7 @@ static const struct inode_operations xfs_symlink_inode_operations = { .readlink = generic_readlink, .follow_link = xfs_vn_follow_link, .put_link = xfs_vn_put_link, - .check_acl = xfs_check_acl, + .permission = xfs_vn_permission, .getattr = xfs_vn_getattr, .setattr = xfs_vn_setattr, .setxattr = generic_setxattr, diff --git a/trunk/include/linux/cred.h b/trunk/include/linux/cred.h index 24520a539c6f..4fa999696310 100644 --- a/trunk/include/linux/cred.h +++ b/trunk/include/linux/cred.h @@ -114,13 +114,6 @@ struct thread_group_cred { */ struct cred { atomic_t usage; -#ifdef CONFIG_DEBUG_CREDENTIALS - atomic_t subscribers; /* number of processes subscribed */ - void *put_addr; - unsigned magic; -#define CRED_MAGIC 0x43736564 -#define CRED_MAGIC_DEAD 0x44656144 -#endif uid_t uid; /* real UID of the task */ gid_t gid; /* real GID of the task */ uid_t suid; /* saved UID of the task */ @@ -150,9 +143,7 @@ struct cred { }; extern void __put_cred(struct cred *); -extern void exit_creds(struct task_struct *); extern int copy_creds(struct task_struct *, unsigned long); -extern struct cred *cred_alloc_blank(void); extern struct cred *prepare_creds(void); extern struct cred *prepare_exec_creds(void); extern struct cred *prepare_usermodehelper_creds(void); @@ -167,60 +158,6 @@ extern int set_security_override_from_ctx(struct cred *, const char *); extern int set_create_files_as(struct cred *, struct inode *); extern void __init cred_init(void); -/* - * check for validity of credentials - */ -#ifdef CONFIG_DEBUG_CREDENTIALS -extern void __invalid_creds(const struct cred *, const char *, unsigned); -extern void __validate_process_creds(struct task_struct *, - const char *, unsigned); - -static inline bool creds_are_invalid(const struct cred *cred) -{ - if (cred->magic != CRED_MAGIC) - return true; - if (atomic_read(&cred->usage) < atomic_read(&cred->subscribers)) - return true; -#ifdef CONFIG_SECURITY_SELINUX - if ((unsigned long) cred->security < PAGE_SIZE) - return true; - if ((*(u32*)cred->security & 0xffffff00) == - (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) - return true; -#endif - return false; -} - -static inline void __validate_creds(const struct cred *cred, - const char *file, unsigned line) -{ - if (unlikely(creds_are_invalid(cred))) - __invalid_creds(cred, file, line); -} - -#define validate_creds(cred) \ -do { \ - __validate_creds((cred), __FILE__, __LINE__); \ -} while(0) - -#define validate_process_creds() \ -do { \ - __validate_process_creds(current, __FILE__, __LINE__); \ -} while(0) - -extern void validate_creds_for_do_exit(struct task_struct *); -#else -static inline void validate_creds(const struct cred *cred) -{ -} -static inline void validate_creds_for_do_exit(struct task_struct *tsk) -{ -} -static inline void validate_process_creds(void) -{ -} -#endif - /** * get_new_cred - Get a reference on a new set of credentials * @cred: The new credentials to reference @@ -249,9 +186,7 @@ static inline struct cred *get_new_cred(struct cred *cred) */ static inline const struct cred *get_cred(const struct cred *cred) { - struct cred *nonconst_cred = (struct cred *) cred; - validate_creds(cred); - return get_new_cred(nonconst_cred); + return get_new_cred((struct cred *) cred); } /** @@ -269,7 +204,7 @@ static inline void put_cred(const struct cred *_cred) { struct cred *cred = (struct cred *) _cred; - validate_creds(cred); + BUG_ON(atomic_read(&(cred)->usage) <= 0); if (atomic_dec_and_test(&(cred)->usage)) __put_cred(cred); } diff --git a/trunk/include/linux/fs.h b/trunk/include/linux/fs.h index c1f993515f51..73e9b643e455 100644 --- a/trunk/include/linux/fs.h +++ b/trunk/include/linux/fs.h @@ -1528,7 +1528,6 @@ struct inode_operations { void (*put_link) (struct dentry *, struct nameidata *, void *); void (*truncate) (struct inode *); int (*permission) (struct inode *, int); - int (*check_acl)(struct inode *, int); int (*setattr) (struct dentry *, struct iattr *); int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); diff --git a/trunk/include/linux/key.h b/trunk/include/linux/key.h index cd50dfa1d4c2..e544f466d69a 100644 --- a/trunk/include/linux/key.h +++ b/trunk/include/linux/key.h @@ -129,10 +129,7 @@ struct key { struct rw_semaphore sem; /* change vs change sem */ struct key_user *user; /* owner of this key */ void *security; /* security data for this key */ - union { - time_t expiry; /* time at which key expires (or 0) */ - time_t revoked_at; /* time at which key was revoked */ - }; + time_t expiry; /* time at which key expires (or 0) */ uid_t uid; gid_t gid; key_perm_t perm; /* access permissions */ @@ -278,8 +275,6 @@ static inline key_serial_t key_serial(struct key *key) extern ctl_table key_sysctls[]; #endif -extern void key_replace_session_keyring(void); - /* * the userspace interface */ @@ -302,7 +297,6 @@ extern void key_init(void); #define key_fsuid_changed(t) do { } while(0) #define key_fsgid_changed(t) do { } while(0) #define key_init() do { } while(0) -#define key_replace_session_keyring() do { } while(0) #endif /* CONFIG_KEYS */ #endif /* __KERNEL__ */ diff --git a/trunk/include/linux/keyctl.h b/trunk/include/linux/keyctl.h index bd383f1944fb..c0688eb72093 100644 --- a/trunk/include/linux/keyctl.h +++ b/trunk/include/linux/keyctl.h @@ -52,6 +52,5 @@ #define KEYCTL_SET_TIMEOUT 15 /* set key timeout */ #define KEYCTL_ASSUME_AUTHORITY 16 /* assume request_key() authorisation */ #define KEYCTL_GET_SECURITY 17 /* get key security label */ -#define KEYCTL_SESSION_TO_PARENT 18 /* apply session keyring to parent process */ #endif /* _LINUX_KEYCTL_H */ diff --git a/trunk/include/linux/lsm_audit.h b/trunk/include/linux/lsm_audit.h index 190c37854870..e461b2c3d711 100644 --- a/trunk/include/linux/lsm_audit.h +++ b/trunk/include/linux/lsm_audit.h @@ -33,7 +33,6 @@ struct common_audit_data { #define LSM_AUDIT_DATA_IPC 4 #define LSM_AUDIT_DATA_TASK 5 #define LSM_AUDIT_DATA_KEY 6 -#define LSM_AUDIT_NO_AUDIT 7 struct task_struct *tsk; union { struct { @@ -67,19 +66,16 @@ struct common_audit_data { } key_struct; #endif } u; + const char *function; /* this union contains LSM specific data */ union { -#ifdef CONFIG_SECURITY_SMACK /* SMACK data */ struct smack_audit_data { - const char *function; char *subject; char *object; char *request; int result; } smack_audit_data; -#endif -#ifdef CONFIG_SECURITY_SELINUX /* SELinux data */ struct { u32 ssid; @@ -87,12 +83,10 @@ struct common_audit_data { u16 tclass; u32 requested; u32 audited; - u32 denied; struct av_decision *avd; int result; } selinux_audit_data; -#endif - }; + } lsm_priv; /* these callback will be implemented by a specific LSM */ void (*lsm_pre_audit)(struct audit_buffer *, void *); void (*lsm_post_audit)(struct audit_buffer *, void *); @@ -110,7 +104,7 @@ int ipv6_skb_to_auditdata(struct sk_buff *skb, /* Initialize an LSM audit data structure. */ #define COMMON_AUDIT_DATA_INIT(_d, _t) \ { memset((_d), 0, sizeof(struct common_audit_data)); \ - (_d)->type = LSM_AUDIT_DATA_##_t; } + (_d)->type = LSM_AUDIT_DATA_##_t; (_d)->function = __func__; } void common_lsm_audit(struct common_audit_data *a); diff --git a/trunk/include/linux/sched.h b/trunk/include/linux/sched.h index 9304027673b0..0f1ea4a66957 100644 --- a/trunk/include/linux/sched.h +++ b/trunk/include/linux/sched.h @@ -1292,7 +1292,6 @@ struct task_struct { struct mutex cred_guard_mutex; /* guard against foreign influences on * credential calculations * (notably. ptrace) */ - struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */ char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock @@ -2078,7 +2077,7 @@ static inline unsigned long wait_task_inactive(struct task_struct *p, #define for_each_process(p) \ for (p = &init_task ; (p = next_task(p)) != &init_task ; ) -extern bool current_is_single_threaded(void); +extern bool is_single_threaded(struct task_struct *); /* * Careful: do_each_thread/while_each_thread is a double loop so diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index d050b66ab9ef..1f16eea2017b 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -53,7 +53,7 @@ struct audit_krule; extern int cap_capable(struct task_struct *tsk, const struct cred *cred, int cap, int audit); extern int cap_settime(struct timespec *ts, struct timezone *tz); -extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode); +extern int cap_ptrace_may_access(struct task_struct *child, unsigned int mode); extern int cap_ptrace_traceme(struct task_struct *parent); extern int cap_capget(struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted); extern int cap_capset(struct cred *new, const struct cred *old, @@ -653,11 +653,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * manual page for definitions of the @clone_flags. * @clone_flags contains the flags indicating what should be shared. * Return 0 if permission is granted. - * @cred_alloc_blank: - * @cred points to the credentials. - * @gfp indicates the atomicity of any memory allocations. - * Only allocate sufficient memory and attach to @cred such that - * cred_transfer() will not get ENOMEM. * @cred_free: * @cred points to the credentials. * Deallocate and clear the cred->security field in a set of credentials. @@ -670,10 +665,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @new points to the new credentials. * @old points to the original credentials. * Install a new set of credentials. - * @cred_transfer: - * @new points to the new credentials. - * @old points to the original credentials. - * Transfer data from original creds to new creds * @kernel_act_as: * Set the credentials for a kernel service to act as (subjective context). * @new points to the credentials to be modified. @@ -687,10 +678,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @inode points to the inode to use as a reference. * The current task must be the one that nominated @inode. * Return 0 if successful. - * @kernel_module_request: - * Ability to trigger the kernel to automatically upcall to userspace for - * userspace to load a kernel module with the given name. - * Return 0 if successful. * @task_setuid: * Check permission before setting one or more of the user identity * attributes of the current process. The @flags parameter indicates @@ -1007,17 +994,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Sets the connection's peersid to the secmark on skb. * @req_classify_flow: * Sets the flow's sid to the openreq sid. - * @tun_dev_create: - * Check permissions prior to creating a new TUN device. - * @tun_dev_post_create: - * This hook allows a module to update or allocate a per-socket security - * structure. - * @sk contains the newly created sock structure. - * @tun_dev_attach: - * Check permissions prior to attaching to a persistent TUN device. This - * hook can also be used by the module to update any security state - * associated with the TUN device's sock structure. - * @sk contains the existing sock structure. * * Security hooks for XFRM operations. * @@ -1112,13 +1088,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Return the length of the string (including terminating NUL) or -ve if * an error. * May also return 0 (and a NULL buffer pointer) if there is no label. - * @key_session_to_parent: - * Forcibly assign the session keyring from a process to its parent - * process. - * @cred: Pointer to process's credentials - * @parent_cred: Pointer to parent process's credentials - * @keyring: Proposed new session keyring - * Return 0 if permission is granted, -ve error otherwise. * * Security hooks affecting all System V IPC operations. * @@ -1260,7 +1229,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * @alter contains the flag indicating whether changes are to be made. * Return 0 if permission is granted. * - * @ptrace_access_check: + * @ptrace_may_access: * Check permission before allowing the current process to trace the * @child process. * Security modules may also want to perform a process tracing check @@ -1275,7 +1244,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * Check that the @parent process has sufficient permission to trace the * current process before allowing the current process to present itself * to the @parent process for tracing. - * The parent process will still have to undergo the ptrace_access_check + * The parent process will still have to undergo the ptrace_may_access * checks before it is allowed to trace this one. * @parent contains the task_struct structure for debugger process. * Return 0 if permission is granted. @@ -1382,47 +1351,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * audit_rule_init. * @rule contains the allocated rule * - * @inode_notifysecctx: - * Notify the security module of what the security context of an inode - * should be. Initializes the incore security context managed by the - * security module for this inode. Example usage: NFS client invokes - * this hook to initialize the security context in its incore inode to the - * value provided by the server for the file when the server returned the - * file's attributes to the client. - * - * Must be called with inode->i_mutex locked. - * - * @inode we wish to set the security context of. - * @ctx contains the string which we wish to set in the inode. - * @ctxlen contains the length of @ctx. - * - * @inode_setsecctx: - * Change the security context of an inode. Updates the - * incore security context managed by the security module and invokes the - * fs code as needed (via __vfs_setxattr_noperm) to update any backing - * xattrs that represent the context. Example usage: NFS server invokes - * this hook to change the security context in its incore inode and on the - * backing filesystem to a value provided by the client on a SETATTR - * operation. - * - * Must be called with inode->i_mutex locked. - * - * @dentry contains the inode we wish to set the security context of. - * @ctx contains the string which we wish to set in the inode. - * @ctxlen contains the length of @ctx. - * - * @inode_getsecctx: - * Returns a string containing all relavent security context information - * - * @inode we wish to set the security context of. - * @ctx is a pointer in which to place the allocated security context. - * @ctxlen points to the place to put the length of @ctx. * This is the main security structure. */ struct security_operations { char name[SECURITY_NAME_MAX + 1]; - int (*ptrace_access_check) (struct task_struct *child, unsigned int mode); + int (*ptrace_may_access) (struct task_struct *child, unsigned int mode); int (*ptrace_traceme) (struct task_struct *parent); int (*capget) (struct task_struct *target, kernel_cap_t *effective, @@ -1549,15 +1483,12 @@ struct security_operations { int (*dentry_open) (struct file *file, const struct cred *cred); int (*task_create) (unsigned long clone_flags); - int (*cred_alloc_blank) (struct cred *cred, gfp_t gfp); void (*cred_free) (struct cred *cred); int (*cred_prepare)(struct cred *new, const struct cred *old, gfp_t gfp); void (*cred_commit)(struct cred *new, const struct cred *old); - void (*cred_transfer)(struct cred *new, const struct cred *old); int (*kernel_act_as)(struct cred *new, u32 secid); int (*kernel_create_files_as)(struct cred *new, struct inode *inode); - int (*kernel_module_request)(void); int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags); int (*task_fix_setuid) (struct cred *new, const struct cred *old, int flags); @@ -1625,10 +1556,6 @@ struct security_operations { int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); void (*release_secctx) (char *secdata, u32 seclen); - int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen); - int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen); - int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen); - #ifdef CONFIG_SECURITY_NETWORK int (*unix_stream_connect) (struct socket *sock, struct socket *other, struct sock *newsk); @@ -1665,9 +1592,6 @@ struct security_operations { void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req); void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb); void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl); - int (*tun_dev_create)(void); - void (*tun_dev_post_create)(struct sock *sk); - int (*tun_dev_attach)(struct sock *sk); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1696,9 +1620,6 @@ struct security_operations { const struct cred *cred, key_perm_t perm); int (*key_getsecurity)(struct key *key, char **_buffer); - int (*key_session_to_parent)(const struct cred *cred, - const struct cred *parent_cred, - struct key *key); #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT @@ -1716,7 +1637,7 @@ extern int security_module_enable(struct security_operations *ops); extern int register_security(struct security_operations *ops); /* Security operations */ -int security_ptrace_access_check(struct task_struct *child, unsigned int mode); +int security_ptrace_may_access(struct task_struct *child, unsigned int mode); int security_ptrace_traceme(struct task_struct *parent); int security_capget(struct task_struct *target, kernel_cap_t *effective, @@ -1815,14 +1736,11 @@ int security_file_send_sigiotask(struct task_struct *tsk, int security_file_receive(struct file *file); int security_dentry_open(struct file *file, const struct cred *cred); int security_task_create(unsigned long clone_flags); -int security_cred_alloc_blank(struct cred *cred, gfp_t gfp); void security_cred_free(struct cred *cred); int security_prepare_creds(struct cred *new, const struct cred *old, gfp_t gfp); void security_commit_creds(struct cred *new, const struct cred *old); -void security_transfer_creds(struct cred *new, const struct cred *old); int security_kernel_act_as(struct cred *new, u32 secid); int security_kernel_create_files_as(struct cred *new, struct inode *inode); -int security_kernel_module_request(void); int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags); int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags); @@ -1878,9 +1796,6 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); void security_release_secctx(char *secdata, u32 seclen); -int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen); -int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen); -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen); #else /* CONFIG_SECURITY */ struct security_mnt_opts { }; @@ -1903,10 +1818,10 @@ static inline int security_init(void) return 0; } -static inline int security_ptrace_access_check(struct task_struct *child, +static inline int security_ptrace_may_access(struct task_struct *child, unsigned int mode) { - return cap_ptrace_access_check(child, mode); + return cap_ptrace_may_access(child, mode); } static inline int security_ptrace_traceme(struct task_struct *parent) @@ -2351,11 +2266,6 @@ static inline int security_task_create(unsigned long clone_flags) return 0; } -static inline int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) -{ - return 0; -} - static inline void security_cred_free(struct cred *cred) { } @@ -2371,11 +2281,6 @@ static inline void security_commit_creds(struct cred *new, { } -static inline void security_transfer_creds(struct cred *new, - const struct cred *old) -{ -} - static inline int security_kernel_act_as(struct cred *cred, u32 secid) { return 0; @@ -2387,11 +2292,6 @@ static inline int security_kernel_create_files_as(struct cred *cred, return 0; } -static inline int security_kernel_module_request(void) -{ - return 0; -} - static inline int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) { @@ -2637,19 +2537,6 @@ static inline int security_secctx_to_secid(const char *secdata, static inline void security_release_secctx(char *secdata, u32 seclen) { } - -static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) -{ - return -EOPNOTSUPP; -} -static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - return -EOPNOTSUPP; -} -static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) -{ - return -EOPNOTSUPP; -} #endif /* CONFIG_SECURITY */ #ifdef CONFIG_SECURITY_NETWORK @@ -2688,9 +2575,6 @@ void security_inet_csk_clone(struct sock *newsk, const struct request_sock *req); void security_inet_conn_established(struct sock *sk, struct sk_buff *skb); -int security_tun_dev_create(void); -void security_tun_dev_post_create(struct sock *sk); -int security_tun_dev_attach(struct sock *sk); #else /* CONFIG_SECURITY_NETWORK */ static inline int security_unix_stream_connect(struct socket *sock, @@ -2841,20 +2725,6 @@ static inline void security_inet_conn_established(struct sock *sk, struct sk_buff *skb) { } - -static inline int security_tun_dev_create(void) -{ - return 0; -} - -static inline void security_tun_dev_post_create(struct sock *sk) -{ -} - -static inline int security_tun_dev_attach(struct sock *sk) -{ - return 0; -} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -3011,9 +2881,6 @@ void security_key_free(struct key *key); int security_key_permission(key_ref_t key_ref, const struct cred *cred, key_perm_t perm); int security_key_getsecurity(struct key *key, char **_buffer); -int security_key_session_to_parent(const struct cred *cred, - const struct cred *parent_cred, - struct key *key); #else @@ -3041,13 +2908,6 @@ static inline int security_key_getsecurity(struct key *key, char **_buffer) return 0; } -static inline int security_key_session_to_parent(const struct cred *cred, - const struct cred *parent_cred, - struct key *key) -{ - return 0; -} - #endif #endif /* CONFIG_KEYS */ diff --git a/trunk/include/linux/shmem_fs.h b/trunk/include/linux/shmem_fs.h index 6d3f2f449ead..abff6c9b413c 100644 --- a/trunk/include/linux/shmem_fs.h +++ b/trunk/include/linux/shmem_fs.h @@ -39,7 +39,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode) } #ifdef CONFIG_TMPFS_POSIX_ACL -int shmem_check_acl(struct inode *, int); +int shmem_permission(struct inode *, int); int shmem_acl_init(struct inode *, struct inode *); extern struct xattr_handler shmem_xattr_acl_access_handler; diff --git a/trunk/include/linux/xattr.h b/trunk/include/linux/xattr.h index 5c84af8c5f6f..d131e352cfe1 100644 --- a/trunk/include/linux/xattr.h +++ b/trunk/include/linux/xattr.h @@ -49,7 +49,6 @@ struct xattr_handler { ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t); ssize_t vfs_getxattr(struct dentry *, const char *, void *, size_t); ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size); -int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, int); int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int); int vfs_removexattr(struct dentry *, const char *); diff --git a/trunk/kernel/acct.c b/trunk/kernel/acct.c index 9a4715a2f6bf..9f3391090b3e 100644 --- a/trunk/kernel/acct.c +++ b/trunk/kernel/acct.c @@ -491,17 +491,13 @@ static void do_acct_process(struct bsd_acct_struct *acct, u64 run_time; struct timespec uptime; struct tty_struct *tty; - const struct cred *orig_cred; - - /* Perform file operations on behalf of whoever enabled accounting */ - orig_cred = override_creds(file->f_cred); /* * First check to see if there is enough free_space to continue * the process accounting system. */ if (!check_free_space(acct, file)) - goto out; + return; /* * Fill the accounting struct with the needed info as recorded @@ -582,8 +578,6 @@ static void do_acct_process(struct bsd_acct_struct *acct, sizeof(acct_t), &file->f_pos); current->signal->rlim[RLIMIT_FSIZE].rlim_cur = flim; set_fs(fs); -out: - revert_creds(orig_cred); } /** diff --git a/trunk/kernel/cred.c b/trunk/kernel/cred.c index 006fcab009d5..1bb4d7e5d616 100644 --- a/trunk/kernel/cred.c +++ b/trunk/kernel/cred.c @@ -18,18 +18,6 @@ #include #include "cred-internals.h" -#if 0 -#define kdebug(FMT, ...) \ - printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__) -#else -static inline __attribute__((format(printf, 1, 2))) -void no_printk(const char *fmt, ...) -{ -} -#define kdebug(FMT, ...) \ - no_printk("[%-5.5s%5u] "FMT"\n", current->comm, current->pid ,##__VA_ARGS__) -#endif - static struct kmem_cache *cred_jar; /* @@ -48,10 +36,6 @@ static struct thread_group_cred init_tgcred = { */ struct cred init_cred = { .usage = ATOMIC_INIT(4), -#ifdef CONFIG_DEBUG_CREDENTIALS - .subscribers = ATOMIC_INIT(2), - .magic = CRED_MAGIC, -#endif .securebits = SECUREBITS_DEFAULT, .cap_inheritable = CAP_INIT_INH_SET, .cap_permitted = CAP_FULL_SET, @@ -64,31 +48,6 @@ struct cred init_cred = { #endif }; -static inline void set_cred_subscribers(struct cred *cred, int n) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - atomic_set(&cred->subscribers, n); -#endif -} - -static inline int read_cred_subscribers(const struct cred *cred) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - return atomic_read(&cred->subscribers); -#else - return 0; -#endif -} - -static inline void alter_cred_subscribers(const struct cred *_cred, int n) -{ -#ifdef CONFIG_DEBUG_CREDENTIALS - struct cred *cred = (struct cred *) _cred; - - atomic_add(n, &cred->subscribers); -#endif -} - /* * Dispose of the shared task group credentials */ @@ -126,22 +85,9 @@ static void put_cred_rcu(struct rcu_head *rcu) { struct cred *cred = container_of(rcu, struct cred, rcu); - kdebug("put_cred_rcu(%p)", cred); - -#ifdef CONFIG_DEBUG_CREDENTIALS - if (cred->magic != CRED_MAGIC_DEAD || - atomic_read(&cred->usage) != 0 || - read_cred_subscribers(cred) != 0) - panic("CRED: put_cred_rcu() sees %p with" - " mag %x, put %p, usage %d, subscr %d\n", - cred, cred->magic, cred->put_addr, - atomic_read(&cred->usage), - read_cred_subscribers(cred)); -#else if (atomic_read(&cred->usage) != 0) panic("CRED: put_cred_rcu() sees %p with usage %d\n", cred, atomic_read(&cred->usage)); -#endif security_cred_free(cred); key_put(cred->thread_keyring); @@ -160,90 +106,12 @@ static void put_cred_rcu(struct rcu_head *rcu) */ void __put_cred(struct cred *cred) { - kdebug("__put_cred(%p{%d,%d})", cred, - atomic_read(&cred->usage), - read_cred_subscribers(cred)); - BUG_ON(atomic_read(&cred->usage) != 0); -#ifdef CONFIG_DEBUG_CREDENTIALS - BUG_ON(read_cred_subscribers(cred) != 0); - cred->magic = CRED_MAGIC_DEAD; - cred->put_addr = __builtin_return_address(0); -#endif - BUG_ON(cred == current->cred); - BUG_ON(cred == current->real_cred); call_rcu(&cred->rcu, put_cred_rcu); } EXPORT_SYMBOL(__put_cred); -/* - * Clean up a task's credentials when it exits - */ -void exit_creds(struct task_struct *tsk) -{ - struct cred *cred; - - kdebug("exit_creds(%u,%p,%p,{%d,%d})", tsk->pid, tsk->real_cred, tsk->cred, - atomic_read(&tsk->cred->usage), - read_cred_subscribers(tsk->cred)); - - cred = (struct cred *) tsk->real_cred; - tsk->real_cred = NULL; - validate_creds(cred); - alter_cred_subscribers(cred, -1); - put_cred(cred); - - cred = (struct cred *) tsk->cred; - tsk->cred = NULL; - validate_creds(cred); - alter_cred_subscribers(cred, -1); - put_cred(cred); - - cred = (struct cred *) tsk->replacement_session_keyring; - if (cred) { - tsk->replacement_session_keyring = NULL; - validate_creds(cred); - put_cred(cred); - } -} - -/* - * Allocate blank credentials, such that the credentials can be filled in at a - * later date without risk of ENOMEM. - */ -struct cred *cred_alloc_blank(void) -{ - struct cred *new; - - new = kmem_cache_zalloc(cred_jar, GFP_KERNEL); - if (!new) - return NULL; - -#ifdef CONFIG_KEYS - new->tgcred = kzalloc(sizeof(*new->tgcred), GFP_KERNEL); - if (!new->tgcred) { - kfree(new); - return NULL; - } - atomic_set(&new->tgcred->usage, 1); -#endif - - atomic_set(&new->usage, 1); - - if (security_cred_alloc_blank(new, GFP_KERNEL) < 0) - goto error; - -#ifdef CONFIG_DEBUG_CREDENTIALS - new->magic = CRED_MAGIC; -#endif - return new; - -error: - abort_creds(new); - return NULL; -} - /** * prepare_creds - Prepare a new set of credentials for modification * @@ -264,19 +132,16 @@ struct cred *prepare_creds(void) const struct cred *old; struct cred *new; - validate_process_creds(); + BUG_ON(atomic_read(&task->real_cred->usage) < 1); new = kmem_cache_alloc(cred_jar, GFP_KERNEL); if (!new) return NULL; - kdebug("prepare_creds() alloc %p", new); - old = task->cred; memcpy(new, old, sizeof(struct cred)); atomic_set(&new->usage, 1); - set_cred_subscribers(new, 0); get_group_info(new->group_info); get_uid(new->user); @@ -292,7 +157,6 @@ struct cred *prepare_creds(void) if (security_prepare_creds(new, old, GFP_KERNEL) < 0) goto error; - validate_creds(new); return new; error: @@ -365,12 +229,9 @@ struct cred *prepare_usermodehelper_creds(void) if (!new) return NULL; - kdebug("prepare_usermodehelper_creds() alloc %p", new); - memcpy(new, &init_cred, sizeof(struct cred)); atomic_set(&new->usage, 1); - set_cred_subscribers(new, 0); get_group_info(new->group_info); get_uid(new->user); @@ -389,7 +250,6 @@ struct cred *prepare_usermodehelper_creds(void) #endif if (security_prepare_creds(new, &init_cred, GFP_ATOMIC) < 0) goto error; - validate_creds(new); BUG_ON(atomic_read(&new->usage) != 1); return new; @@ -426,10 +286,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) ) { p->real_cred = get_cred(p->cred); get_cred(p->cred); - alter_cred_subscribers(p->cred, 2); - kdebug("share_creds(%p{%d,%d})", - p->cred, atomic_read(&p->cred->usage), - read_cred_subscribers(p->cred)); atomic_inc(&p->cred->user->processes); return 0; } @@ -475,8 +331,6 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) atomic_inc(&new->user->processes); p->cred = p->real_cred = get_cred(new); - alter_cred_subscribers(new, 2); - validate_creds(new); return 0; error_put: @@ -501,20 +355,13 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags) int commit_creds(struct cred *new) { struct task_struct *task = current; - const struct cred *old = task->real_cred; - - kdebug("commit_creds(%p{%d,%d})", new, - atomic_read(&new->usage), - read_cred_subscribers(new)); + const struct cred *old; - BUG_ON(task->cred != old); -#ifdef CONFIG_DEBUG_CREDENTIALS - BUG_ON(read_cred_subscribers(old) < 2); - validate_creds(old); - validate_creds(new); -#endif + BUG_ON(task->cred != task->real_cred); + BUG_ON(atomic_read(&task->real_cred->usage) < 2); BUG_ON(atomic_read(&new->usage) < 1); + old = task->real_cred; security_commit_creds(new, old); get_cred(new); /* we will require a ref for the subj creds too */ @@ -543,14 +390,12 @@ int commit_creds(struct cred *new) * cheaply with the new uid cache, so if it matters * we should be checking for it. -DaveM */ - alter_cred_subscribers(new, 2); if (new->user != old->user) atomic_inc(&new->user->processes); rcu_assign_pointer(task->real_cred, new); rcu_assign_pointer(task->cred, new); if (new->user != old->user) atomic_dec(&old->user->processes); - alter_cred_subscribers(old, -2); sched_switch_user(task); @@ -583,13 +428,6 @@ EXPORT_SYMBOL(commit_creds); */ void abort_creds(struct cred *new) { - kdebug("abort_creds(%p{%d,%d})", new, - atomic_read(&new->usage), - read_cred_subscribers(new)); - -#ifdef CONFIG_DEBUG_CREDENTIALS - BUG_ON(read_cred_subscribers(new) != 0); -#endif BUG_ON(atomic_read(&new->usage) < 1); put_cred(new); } @@ -606,20 +444,7 @@ const struct cred *override_creds(const struct cred *new) { const struct cred *old = current->cred; - kdebug("override_creds(%p{%d,%d})", new, - atomic_read(&new->usage), - read_cred_subscribers(new)); - - validate_creds(old); - validate_creds(new); - get_cred(new); - alter_cred_subscribers(new, 1); - rcu_assign_pointer(current->cred, new); - alter_cred_subscribers(old, -1); - - kdebug("override_creds() = %p{%d,%d}", old, - atomic_read(&old->usage), - read_cred_subscribers(old)); + rcu_assign_pointer(current->cred, get_cred(new)); return old; } EXPORT_SYMBOL(override_creds); @@ -635,15 +460,7 @@ void revert_creds(const struct cred *old) { const struct cred *override = current->cred; - kdebug("revert_creds(%p{%d,%d})", old, - atomic_read(&old->usage), - read_cred_subscribers(old)); - - validate_creds(old); - validate_creds(override); - alter_cred_subscribers(old, 1); rcu_assign_pointer(current->cred, old); - alter_cred_subscribers(override, -1); put_cred(override); } EXPORT_SYMBOL(revert_creds); @@ -685,15 +502,11 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) if (!new) return NULL; - kdebug("prepare_kernel_cred() alloc %p", new); - if (daemon) old = get_task_cred(daemon); else old = get_cred(&init_cred); - validate_creds(old); - *new = *old; get_uid(new->user); get_group_info(new->group_info); @@ -713,9 +526,7 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) goto error; atomic_set(&new->usage, 1); - set_cred_subscribers(new, 0); put_cred(old); - validate_creds(new); return new; error: @@ -778,95 +589,3 @@ int set_create_files_as(struct cred *new, struct inode *inode) return security_kernel_create_files_as(new, inode); } EXPORT_SYMBOL(set_create_files_as); - -#ifdef CONFIG_DEBUG_CREDENTIALS - -/* - * dump invalid credentials - */ -static void dump_invalid_creds(const struct cred *cred, const char *label, - const struct task_struct *tsk) -{ - printk(KERN_ERR "CRED: %s credentials: %p %s%s%s\n", - label, cred, - cred == &init_cred ? "[init]" : "", - cred == tsk->real_cred ? "[real]" : "", - cred == tsk->cred ? "[eff]" : ""); - printk(KERN_ERR "CRED: ->magic=%x, put_addr=%p\n", - cred->magic, cred->put_addr); - printk(KERN_ERR "CRED: ->usage=%d, subscr=%d\n", - atomic_read(&cred->usage), - read_cred_subscribers(cred)); - printk(KERN_ERR "CRED: ->*uid = { %d,%d,%d,%d }\n", - cred->uid, cred->euid, cred->suid, cred->fsuid); - printk(KERN_ERR "CRED: ->*gid = { %d,%d,%d,%d }\n", - cred->gid, cred->egid, cred->sgid, cred->fsgid); -#ifdef CONFIG_SECURITY - printk(KERN_ERR "CRED: ->security is %p\n", cred->security); - if ((unsigned long) cred->security >= PAGE_SIZE && - (((unsigned long) cred->security & 0xffffff00) != - (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))) - printk(KERN_ERR "CRED: ->security {%x, %x}\n", - ((u32*)cred->security)[0], - ((u32*)cred->security)[1]); -#endif -} - -/* - * report use of invalid credentials - */ -void __invalid_creds(const struct cred *cred, const char *file, unsigned line) -{ - printk(KERN_ERR "CRED: Invalid credentials\n"); - printk(KERN_ERR "CRED: At %s:%u\n", file, line); - dump_invalid_creds(cred, "Specified", current); - BUG(); -} -EXPORT_SYMBOL(__invalid_creds); - -/* - * check the credentials on a process - */ -void __validate_process_creds(struct task_struct *tsk, - const char *file, unsigned line) -{ - if (tsk->cred == tsk->real_cred) { - if (unlikely(read_cred_subscribers(tsk->cred) < 2 || - creds_are_invalid(tsk->cred))) - goto invalid_creds; - } else { - if (unlikely(read_cred_subscribers(tsk->real_cred) < 1 || - read_cred_subscribers(tsk->cred) < 1 || - creds_are_invalid(tsk->real_cred) || - creds_are_invalid(tsk->cred))) - goto invalid_creds; - } - return; - -invalid_creds: - printk(KERN_ERR "CRED: Invalid process credentials\n"); - printk(KERN_ERR "CRED: At %s:%u\n", file, line); - - dump_invalid_creds(tsk->real_cred, "Real", tsk); - if (tsk->cred != tsk->real_cred) - dump_invalid_creds(tsk->cred, "Effective", tsk); - else - printk(KERN_ERR "CRED: Effective creds == Real creds\n"); - BUG(); -} -EXPORT_SYMBOL(__validate_process_creds); - -/* - * check creds for do_exit() - */ -void validate_creds_for_do_exit(struct task_struct *tsk) -{ - kdebug("validate_creds_for_do_exit(%p,%p{%d,%d})", - tsk->real_cred, tsk->cred, - atomic_read(&tsk->cred->usage), - read_cred_subscribers(tsk->cred)); - - __validate_process_creds(tsk, __FILE__, __LINE__); -} - -#endif /* CONFIG_DEBUG_CREDENTIALS */ diff --git a/trunk/kernel/exit.c b/trunk/kernel/exit.c index c98ff7a8025f..869dc221733e 100644 --- a/trunk/kernel/exit.c +++ b/trunk/kernel/exit.c @@ -901,8 +901,6 @@ NORET_TYPE void do_exit(long code) tracehook_report_exit(&code); - validate_creds_for_do_exit(tsk); - /* * We're taking recursive faults here in do_exit. Safest is to just * leave this task alone and wait for reboot. @@ -1011,8 +1009,6 @@ NORET_TYPE void do_exit(long code) if (tsk->splice_pipe) __free_pipe_info(tsk->splice_pipe); - validate_creds_for_do_exit(tsk); - preempt_disable(); /* causes final put_task_struct in finish_task_switch(). */ tsk->state = TASK_DEAD; diff --git a/trunk/kernel/fork.c b/trunk/kernel/fork.c index aab8579c6093..e6c04d462ab2 100644 --- a/trunk/kernel/fork.c +++ b/trunk/kernel/fork.c @@ -152,7 +152,8 @@ void __put_task_struct(struct task_struct *tsk) WARN_ON(atomic_read(&tsk->usage)); WARN_ON(tsk == current); - exit_creds(tsk); + put_cred(tsk->real_cred); + put_cred(tsk->cred); delayacct_tsk_free(tsk); if (!profile_handoff_task(tsk)) @@ -1296,7 +1297,8 @@ static struct task_struct *copy_process(unsigned long clone_flags, module_put(task_thread_info(p)->exec_domain->module); bad_fork_cleanup_count: atomic_dec(&p->cred->user->processes); - exit_creds(p); + put_cred(p->real_cred); + put_cred(p->cred); bad_fork_free: free_task(p); fork_out: diff --git a/trunk/kernel/kmod.c b/trunk/kernel/kmod.c index 4e8cae2e9148..385c31a1bdbf 100644 --- a/trunk/kernel/kmod.c +++ b/trunk/kernel/kmod.c @@ -78,10 +78,6 @@ int __request_module(bool wait, const char *fmt, ...) #define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ static int kmod_loop_msg; - ret = security_kernel_module_request(); - if (ret) - return ret; - va_start(args, fmt); ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); va_end(args); @@ -466,7 +462,6 @@ int call_usermodehelper_exec(struct subprocess_info *sub_info, int retval = 0; BUG_ON(atomic_read(&sub_info->cred->usage) != 1); - validate_creds(sub_info->cred); helper_lock(); if (sub_info->path[0] == '\0') diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index 307c285af59e..082c320e4dbf 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -152,7 +152,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode) if (!dumpable && !capable(CAP_SYS_PTRACE)) return -EPERM; - return security_ptrace_access_check(task, mode); + return security_ptrace_may_access(task, mode); } bool ptrace_may_access(struct task_struct *task, unsigned int mode) diff --git a/trunk/kernel/sysctl.c b/trunk/kernel/sysctl.c index 71d8dc7f9920..58be76017fd0 100644 --- a/trunk/kernel/sysctl.c +++ b/trunk/kernel/sysctl.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include diff --git a/trunk/lib/Kconfig.debug b/trunk/lib/Kconfig.debug index fbb87cf138c5..12327b2bb785 100644 --- a/trunk/lib/Kconfig.debug +++ b/trunk/lib/Kconfig.debug @@ -653,21 +653,6 @@ config DEBUG_NOTIFIERS This is a relatively cheap check but if you care about maximum performance, say N. -config DEBUG_CREDENTIALS - bool "Debug credential management" - depends on DEBUG_KERNEL - help - Enable this 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. - - Furthermore, if SELinux is enabled, this also checks that the - security pointer in the cred struct is never seen to be invalid. - - If unsure, say N. - # # Select this config option from the architecture Kconfig, if it # it is preferred to always offer frame pointers as a config diff --git a/trunk/lib/is_single_threaded.c b/trunk/lib/is_single_threaded.c index bd2bea963364..f1ed2fe76c65 100644 --- a/trunk/lib/is_single_threaded.c +++ b/trunk/lib/is_single_threaded.c @@ -12,47 +12,34 @@ #include -/* - * Returns true if the task does not share ->mm with another thread/process. +/** + * is_single_threaded - Determine if a thread group is single-threaded or not + * @p: A task in the thread group in question + * + * This returns true if the thread group to which a task belongs is single + * threaded, false if it is not. */ -bool current_is_single_threaded(void) +bool is_single_threaded(struct task_struct *p) { - struct task_struct *task = current; - struct mm_struct *mm = task->mm; - struct task_struct *p, *t; - bool ret; - - if (atomic_read(&task->signal->live) != 1) - return false; + struct task_struct *g, *t; + struct mm_struct *mm = p->mm; - if (atomic_read(&mm->mm_users) == 1) - return true; + if (atomic_read(&p->signal->count) != 1) + goto no; - ret = false; - rcu_read_lock(); - for_each_process(p) { - if (unlikely(p->flags & PF_KTHREAD)) - continue; - if (unlikely(p == task->group_leader)) - continue; - - t = p; - do { - if (unlikely(t->mm == mm)) - goto found; - if (likely(t->mm)) - break; - /* - * t->mm == NULL. Make sure next_thread/next_task - * will see other CLONE_VM tasks which might be - * forked before exiting. - */ - smp_rmb(); - } while_each_thread(p, t); + if (atomic_read(&p->mm->mm_users) != 1) { + read_lock(&tasklist_lock); + do_each_thread(g, t) { + if (t->mm == mm && t != p) + goto no_unlock; + } while_each_thread(g, t); + read_unlock(&tasklist_lock); } - ret = true; -found: - rcu_read_unlock(); - return ret; + return true; + +no_unlock: + read_unlock(&tasklist_lock); +no: + return false; } diff --git a/trunk/mm/shmem.c b/trunk/mm/shmem.c index 5a0b3d4055f3..d713239ce2ce 100644 --- a/trunk/mm/shmem.c +++ b/trunk/mm/shmem.c @@ -2446,7 +2446,7 @@ static const struct inode_operations shmem_inode_operations = { .getxattr = generic_getxattr, .listxattr = generic_listxattr, .removexattr = generic_removexattr, - .check_acl = shmem_check_acl, + .permission = shmem_permission, #endif }; @@ -2469,7 +2469,7 @@ static const struct inode_operations shmem_dir_inode_operations = { .getxattr = generic_getxattr, .listxattr = generic_listxattr, .removexattr = generic_removexattr, - .check_acl = shmem_check_acl, + .permission = shmem_permission, #endif }; @@ -2480,7 +2480,7 @@ static const struct inode_operations shmem_special_inode_operations = { .getxattr = generic_getxattr, .listxattr = generic_listxattr, .removexattr = generic_removexattr, - .check_acl = shmem_check_acl, + .permission = shmem_permission, #endif }; diff --git a/trunk/mm/shmem_acl.c b/trunk/mm/shmem_acl.c index df2c87fdae50..606a8e757a42 100644 --- a/trunk/mm/shmem_acl.c +++ b/trunk/mm/shmem_acl.c @@ -157,7 +157,7 @@ shmem_acl_init(struct inode *inode, struct inode *dir) /** * shmem_check_acl - check_acl() callback for generic_permission() */ -int +static int shmem_check_acl(struct inode *inode, int mask) { struct posix_acl *acl = shmem_get_acl(inode, ACL_TYPE_ACCESS); @@ -169,3 +169,12 @@ shmem_check_acl(struct inode *inode, int mask) } return -EAGAIN; } + +/** + * shmem_permission - permission() inode operation + */ +int +shmem_permission(struct inode *inode, int mask) +{ + return generic_permission(inode, mask, shmem_check_acl); +} diff --git a/trunk/net/core/dev.c b/trunk/net/core/dev.c index 278d489aad3b..6a94475aee85 100644 --- a/trunk/net/core/dev.c +++ b/trunk/net/core/dev.c @@ -1031,7 +1031,7 @@ void dev_load(struct net *net, const char *name) dev = __dev_get_by_name(net, name); read_unlock(&dev_base_lock); - if (!dev && capable(CAP_NET_ADMIN)) + if (!dev && capable(CAP_SYS_MODULE)) request_module("%s", name); } diff --git a/trunk/net/ipv4/tcp_cong.c b/trunk/net/ipv4/tcp_cong.c index 6428b342b164..e92beb9e55e0 100644 --- a/trunk/net/ipv4/tcp_cong.c +++ b/trunk/net/ipv4/tcp_cong.c @@ -116,7 +116,7 @@ int tcp_set_default_congestion_control(const char *name) spin_lock(&tcp_cong_list_lock); ca = tcp_ca_find(name); #ifdef CONFIG_MODULES - if (!ca && capable(CAP_NET_ADMIN)) { + if (!ca && capable(CAP_SYS_MODULE)) { spin_unlock(&tcp_cong_list_lock); request_module("tcp_%s", name); @@ -246,7 +246,7 @@ int tcp_set_congestion_control(struct sock *sk, const char *name) #ifdef CONFIG_MODULES /* not found attempt to autoload module */ - if (!ca && capable(CAP_NET_ADMIN)) { + if (!ca && capable(CAP_SYS_MODULE)) { rcu_read_unlock(); request_module("tcp_%s", name); rcu_read_lock(); diff --git a/trunk/security/Makefile b/trunk/security/Makefile index 95ecc06392d7..b56e7f9ecbc2 100644 --- a/trunk/security/Makefile +++ b/trunk/security/Makefile @@ -16,7 +16,9 @@ obj-$(CONFIG_SECURITYFS) += inode.o # Must precede capability.o in order to stack properly. obj-$(CONFIG_SECURITY_SELINUX) += selinux/built-in.o obj-$(CONFIG_SECURITY_SMACK) += smack/built-in.o -obj-$(CONFIG_AUDIT) += lsm_audit.o +ifeq ($(CONFIG_AUDIT),y) +obj-$(CONFIG_SECURITY_SMACK) += lsm_audit.o +endif obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/built-in.o obj-$(CONFIG_SECURITY_ROOTPLUG) += root_plug.o obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o diff --git a/trunk/security/capability.c b/trunk/security/capability.c index fce07a7bc825..88f752e8152c 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -373,11 +373,6 @@ static int cap_task_create(unsigned long clone_flags) return 0; } -static int cap_cred_alloc_blank(struct cred *cred, gfp_t gfp) -{ - return 0; -} - static void cap_cred_free(struct cred *cred) { } @@ -391,10 +386,6 @@ static void cap_cred_commit(struct cred *new, const struct cred *old) { } -static void cap_cred_transfer(struct cred *new, const struct cred *old) -{ -} - static int cap_kernel_act_as(struct cred *new, u32 secid) { return 0; @@ -405,11 +396,6 @@ static int cap_kernel_create_files_as(struct cred *new, struct inode *inode) return 0; } -static int cap_kernel_module_request(void) -{ - return 0; -} - static int cap_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) { return 0; @@ -715,26 +701,10 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb) { } - - static void cap_req_classify_flow(const struct request_sock *req, struct flowi *fl) { } - -static int cap_tun_dev_create(void) -{ - return 0; -} - -static void cap_tun_dev_post_create(struct sock *sk) -{ -} - -static int cap_tun_dev_attach(struct sock *sk) -{ - return 0; -} #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -822,20 +792,6 @@ static void cap_release_secctx(char *secdata, u32 seclen) { } -static int cap_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) -{ - return 0; -} - -static int cap_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - return 0; -} - -static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) -{ - return 0; -} #ifdef CONFIG_KEYS static int cap_key_alloc(struct key *key, const struct cred *cred, unsigned long flags) @@ -859,13 +815,6 @@ static int cap_key_getsecurity(struct key *key, char **_buffer) return 0; } -static int cap_key_session_to_parent(const struct cred *cred, - const struct cred *parent_cred, - struct key *key) -{ - return 0; -} - #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT @@ -905,7 +854,7 @@ struct security_operations default_security_ops = { void security_fixup_ops(struct security_operations *ops) { - set_to_cap_if_null(ops, ptrace_access_check); + set_to_cap_if_null(ops, ptrace_may_access); set_to_cap_if_null(ops, ptrace_traceme); set_to_cap_if_null(ops, capget); set_to_cap_if_null(ops, capset); @@ -991,14 +940,11 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, file_receive); set_to_cap_if_null(ops, dentry_open); set_to_cap_if_null(ops, task_create); - set_to_cap_if_null(ops, cred_alloc_blank); set_to_cap_if_null(ops, cred_free); set_to_cap_if_null(ops, cred_prepare); set_to_cap_if_null(ops, cred_commit); - set_to_cap_if_null(ops, cred_transfer); set_to_cap_if_null(ops, kernel_act_as); set_to_cap_if_null(ops, kernel_create_files_as); - set_to_cap_if_null(ops, kernel_module_request); set_to_cap_if_null(ops, task_setuid); set_to_cap_if_null(ops, task_fix_setuid); set_to_cap_if_null(ops, task_setgid); @@ -1046,9 +992,6 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, secid_to_secctx); set_to_cap_if_null(ops, secctx_to_secid); set_to_cap_if_null(ops, release_secctx); - set_to_cap_if_null(ops, inode_notifysecctx); - set_to_cap_if_null(ops, inode_setsecctx); - set_to_cap_if_null(ops, inode_getsecctx); #ifdef CONFIG_SECURITY_NETWORK set_to_cap_if_null(ops, unix_stream_connect); set_to_cap_if_null(ops, unix_may_send); @@ -1077,9 +1020,6 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, inet_csk_clone); set_to_cap_if_null(ops, inet_conn_established); set_to_cap_if_null(ops, req_classify_flow); - set_to_cap_if_null(ops, tun_dev_create); - set_to_cap_if_null(ops, tun_dev_post_create); - set_to_cap_if_null(ops, tun_dev_attach); #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM set_to_cap_if_null(ops, xfrm_policy_alloc_security); @@ -1098,7 +1038,6 @@ void security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, key_free); set_to_cap_if_null(ops, key_permission); set_to_cap_if_null(ops, key_getsecurity); - set_to_cap_if_null(ops, key_session_to_parent); #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT set_to_cap_if_null(ops, audit_rule_init); diff --git a/trunk/security/commoncap.c b/trunk/security/commoncap.c index fe30751a6cd9..e3097c0a1311 100644 --- a/trunk/security/commoncap.c +++ b/trunk/security/commoncap.c @@ -101,7 +101,7 @@ int cap_settime(struct timespec *ts, struct timezone *tz) } /** - * cap_ptrace_access_check - Determine whether the current process may access + * cap_ptrace_may_access - Determine whether the current process may access * another * @child: The process to be accessed * @mode: The mode of attachment. @@ -109,7 +109,7 @@ int cap_settime(struct timespec *ts, struct timezone *tz) * Determine whether a process may access another, returning 0 if permission * granted, -ve if denied. */ -int cap_ptrace_access_check(struct task_struct *child, unsigned int mode) +int cap_ptrace_may_access(struct task_struct *child, unsigned int mode) { int ret = 0; diff --git a/trunk/security/integrity/ima/ima_main.c b/trunk/security/integrity/ima/ima_main.c index b85e61bcf246..4732f5e5d127 100644 --- a/trunk/security/integrity/ima/ima_main.c +++ b/trunk/security/integrity/ima/ima_main.c @@ -249,11 +249,7 @@ void ima_counts_put(struct path *path, int mask) struct inode *inode = path->dentry->d_inode; struct ima_iint_cache *iint; - /* The inode may already have been freed, freeing the iint - * with it. Verify the inode is not NULL before dereferencing - * it. - */ - if (!ima_initialized || !inode || !S_ISREG(inode->i_mode)) + if (!ima_initialized || !S_ISREG(inode->i_mode)) return; iint = ima_iint_find_insert_get(inode); if (!iint) diff --git a/trunk/security/keys/Makefile b/trunk/security/keys/Makefile index 74d5447d7df7..747a464943af 100644 --- a/trunk/security/keys/Makefile +++ b/trunk/security/keys/Makefile @@ -3,7 +3,6 @@ # obj-y := \ - gc.o \ key.o \ keyring.o \ keyctl.o \ diff --git a/trunk/security/keys/compat.c b/trunk/security/keys/compat.c index 792c0a611a6d..c766c68a63bc 100644 --- a/trunk/security/keys/compat.c +++ b/trunk/security/keys/compat.c @@ -82,9 +82,6 @@ asmlinkage long compat_sys_keyctl(u32 option, case KEYCTL_GET_SECURITY: return keyctl_get_security(arg2, compat_ptr(arg3), arg4); - case KEYCTL_SESSION_TO_PARENT: - return keyctl_session_to_parent(); - default: return -EOPNOTSUPP; } diff --git a/trunk/security/keys/gc.c b/trunk/security/keys/gc.c deleted file mode 100644 index 1e616aef55fd..000000000000 --- a/trunk/security/keys/gc.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Key garbage collector - * - * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. - * Written by David Howells (dhowells@redhat.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public Licence - * as published by the Free Software Foundation; either version - * 2 of the Licence, or (at your option) any later version. - */ - -#include -#include -#include "internal.h" - -/* - * Delay between key revocation/expiry in seconds - */ -unsigned key_gc_delay = 5 * 60; - -/* - * Reaper - */ -static void key_gc_timer_func(unsigned long); -static void key_garbage_collector(struct work_struct *); -static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0); -static DECLARE_WORK(key_gc_work, key_garbage_collector); -static key_serial_t key_gc_cursor; /* the last key the gc considered */ -static unsigned long key_gc_executing; -static time_t key_gc_next_run = LONG_MAX; - -/* - * Schedule a garbage collection run - * - precision isn't particularly important - */ -void key_schedule_gc(time_t gc_at) -{ - unsigned long expires; - time_t now = current_kernel_time().tv_sec; - - kenter("%ld", gc_at - now); - - gc_at += key_gc_delay; - - if (now >= gc_at) { - schedule_work(&key_gc_work); - } else if (gc_at < key_gc_next_run) { - expires = jiffies + (gc_at - now) * HZ; - mod_timer(&key_gc_timer, expires); - } -} - -/* - * The garbage collector timer kicked off - */ -static void key_gc_timer_func(unsigned long data) -{ - kenter(""); - key_gc_next_run = LONG_MAX; - schedule_work(&key_gc_work); -} - -/* - * Garbage collect pointers from a keyring - * - return true if we altered the keyring - */ -static bool key_gc_keyring(struct key *keyring, time_t limit) - __releases(key_serial_lock) -{ - struct keyring_list *klist; - struct key *key; - int loop; - - kenter("%x", key_serial(keyring)); - - if (test_bit(KEY_FLAG_REVOKED, &keyring->flags)) - goto dont_gc; - - /* scan the keyring looking for dead keys */ - klist = rcu_dereference(keyring->payload.subscriptions); - if (!klist) - goto dont_gc; - - for (loop = klist->nkeys - 1; loop >= 0; loop--) { - key = klist->keys[loop]; - if (test_bit(KEY_FLAG_DEAD, &key->flags) || - (key->expiry > 0 && key->expiry <= limit)) - goto do_gc; - } - -dont_gc: - kleave(" = false"); - return false; - -do_gc: - key_gc_cursor = keyring->serial; - key_get(keyring); - spin_unlock(&key_serial_lock); - keyring_gc(keyring, limit); - key_put(keyring); - kleave(" = true"); - return true; -} - -/* - * Garbage collector for keys - * - this involves scanning the keyrings for dead, expired and revoked keys - * that have overstayed their welcome - */ -static void key_garbage_collector(struct work_struct *work) -{ - struct rb_node *rb; - key_serial_t cursor; - struct key *key, *xkey; - time_t new_timer = LONG_MAX, limit; - - kenter(""); - - if (test_and_set_bit(0, &key_gc_executing)) { - key_schedule_gc(current_kernel_time().tv_sec); - return; - } - - limit = current_kernel_time().tv_sec; - if (limit > key_gc_delay) - limit -= key_gc_delay; - else - limit = key_gc_delay; - - spin_lock(&key_serial_lock); - - if (RB_EMPTY_ROOT(&key_serial_tree)) - goto reached_the_end; - - cursor = key_gc_cursor; - if (cursor < 0) - cursor = 0; - - /* find the first key above the cursor */ - key = NULL; - rb = key_serial_tree.rb_node; - while (rb) { - xkey = rb_entry(rb, struct key, serial_node); - if (cursor < xkey->serial) { - key = xkey; - rb = rb->rb_left; - } else if (cursor > xkey->serial) { - rb = rb->rb_right; - } else { - rb = rb_next(rb); - if (!rb) - goto reached_the_end; - key = rb_entry(rb, struct key, serial_node); - break; - } - } - - if (!key) - goto reached_the_end; - - /* trawl through the keys looking for keyrings */ - for (;;) { - if (key->expiry > 0 && key->expiry < new_timer) - new_timer = key->expiry; - - if (key->type == &key_type_keyring && - key_gc_keyring(key, limit)) { - /* the gc ate our lock */ - schedule_work(&key_gc_work); - goto no_unlock; - } - - rb = rb_next(&key->serial_node); - if (!rb) { - key_gc_cursor = 0; - break; - } - key = rb_entry(rb, struct key, serial_node); - } - -out: - spin_unlock(&key_serial_lock); -no_unlock: - clear_bit(0, &key_gc_executing); - if (new_timer < LONG_MAX) - key_schedule_gc(new_timer); - - kleave(""); - return; - -reached_the_end: - key_gc_cursor = 0; - goto out; -} diff --git a/trunk/security/keys/internal.h b/trunk/security/keys/internal.h index 24ba0307b7ad..9fb679c66b8a 100644 --- a/trunk/security/keys/internal.h +++ b/trunk/security/keys/internal.h @@ -124,18 +124,11 @@ extern struct key *request_key_and_link(struct key_type *type, struct key *dest_keyring, unsigned long flags); -extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags, +extern key_ref_t lookup_user_key(key_serial_t id, int create, int partial, key_perm_t perm); -#define KEY_LOOKUP_CREATE 0x01 -#define KEY_LOOKUP_PARTIAL 0x02 -#define KEY_LOOKUP_FOR_UNLINK 0x04 extern long join_session_keyring(const char *name); -extern unsigned key_gc_delay; -extern void keyring_gc(struct key *keyring, time_t limit); -extern void key_schedule_gc(time_t expiry_at); - /* * check to see whether permission is granted to use a key in the desired way */ @@ -201,7 +194,6 @@ extern long keyctl_set_timeout(key_serial_t, unsigned); extern long keyctl_assume_authority(key_serial_t); extern long keyctl_get_security(key_serial_t keyid, char __user *buffer, size_t buflen); -extern long keyctl_session_to_parent(void); /* * debugging key validation diff --git a/trunk/security/keys/key.c b/trunk/security/keys/key.c index 08531ad0f252..4a1297d1ada4 100644 --- a/trunk/security/keys/key.c +++ b/trunk/security/keys/key.c @@ -500,7 +500,6 @@ int key_negate_and_link(struct key *key, set_bit(KEY_FLAG_INSTANTIATED, &key->flags); now = current_kernel_time(); key->expiry = now.tv_sec + timeout; - key_schedule_gc(key->expiry); if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags)) awaken = 1; @@ -643,8 +642,10 @@ struct key *key_lookup(key_serial_t id) goto error; found: - /* pretend it doesn't exist if it is awaiting deletion */ - if (atomic_read(&key->usage) == 0) + /* pretend it doesn't exist if it's dead */ + if (atomic_read(&key->usage) == 0 || + test_bit(KEY_FLAG_DEAD, &key->flags) || + key->type == &key_type_dead) goto not_found; /* this races with key_put(), but that doesn't matter since key_put() @@ -889,9 +890,6 @@ EXPORT_SYMBOL(key_update); */ void key_revoke(struct key *key) { - struct timespec now; - time_t time; - key_check(key); /* make sure no one's trying to change or use the key when we mark it @@ -904,14 +902,6 @@ void key_revoke(struct key *key) key->type->revoke) key->type->revoke(key); - /* set the death time to no more than the expiry time */ - now = current_kernel_time(); - time = now.tv_sec; - if (key->revoked_at == 0 || key->revoked_at > time) { - key->revoked_at = time; - key_schedule_gc(key->revoked_at); - } - up_write(&key->sem); } /* end key_revoke() */ @@ -968,10 +958,8 @@ void unregister_key_type(struct key_type *ktype) for (_n = rb_first(&key_serial_tree); _n; _n = rb_next(_n)) { key = rb_entry(_n, struct key, serial_node); - if (key->type == ktype) { + if (key->type == ktype) key->type = &key_type_dead; - set_bit(KEY_FLAG_DEAD, &key->flags); - } } spin_unlock(&key_serial_lock); @@ -996,8 +984,6 @@ void unregister_key_type(struct key_type *ktype) spin_unlock(&key_serial_lock); up_write(&key_types_sem); - key_schedule_gc(0); - } /* end unregister_key_type() */ EXPORT_SYMBOL(unregister_key_type); diff --git a/trunk/security/keys/keyctl.c b/trunk/security/keys/keyctl.c index 74c968524592..7f09fb897d2b 100644 --- a/trunk/security/keys/keyctl.c +++ b/trunk/security/keys/keyctl.c @@ -103,7 +103,7 @@ SYSCALL_DEFINE5(add_key, const char __user *, _type, } /* find the target keyring (which must be writable) */ - keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); + keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error3; @@ -185,8 +185,7 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, /* get the destination keyring if specified */ dest_ref = NULL; if (destringid) { - dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, - KEY_WRITE); + dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); if (IS_ERR(dest_ref)) { ret = PTR_ERR(dest_ref); goto error3; @@ -234,11 +233,9 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type, long keyctl_get_keyring_ID(key_serial_t id, int create) { key_ref_t key_ref; - unsigned long lflags; long ret; - lflags = create ? KEY_LOOKUP_CREATE : 0; - key_ref = lookup_user_key(id, lflags, KEY_SEARCH); + key_ref = lookup_user_key(id, create, 0, KEY_SEARCH); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error; @@ -312,7 +309,7 @@ long keyctl_update_key(key_serial_t id, } /* find the target key (which must be writable) */ - key_ref = lookup_user_key(id, 0, KEY_WRITE); + key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error2; @@ -340,16 +337,10 @@ long keyctl_revoke_key(key_serial_t id) key_ref_t key_ref; long ret; - key_ref = lookup_user_key(id, 0, KEY_WRITE); + key_ref = lookup_user_key(id, 0, 0, KEY_WRITE); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); - if (ret != -EACCES) - goto error; - key_ref = lookup_user_key(id, 0, KEY_SETATTR); - if (IS_ERR(key_ref)) { - ret = PTR_ERR(key_ref); - goto error; - } + goto error; } key_revoke(key_ref_to_ptr(key_ref)); @@ -372,7 +363,7 @@ long keyctl_keyring_clear(key_serial_t ringid) key_ref_t keyring_ref; long ret; - keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); + keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error; @@ -398,13 +389,13 @@ long keyctl_keyring_link(key_serial_t id, key_serial_t ringid) key_ref_t keyring_ref, key_ref; long ret; - keyring_ref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); + keyring_ref = lookup_user_key(ringid, 1, 0, KEY_WRITE); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error; } - key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE, KEY_LINK); + key_ref = lookup_user_key(id, 1, 0, KEY_LINK); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error2; @@ -432,13 +423,13 @@ long keyctl_keyring_unlink(key_serial_t id, key_serial_t ringid) key_ref_t keyring_ref, key_ref; long ret; - keyring_ref = lookup_user_key(ringid, 0, KEY_WRITE); + keyring_ref = lookup_user_key(ringid, 0, 0, KEY_WRITE); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error; } - key_ref = lookup_user_key(id, KEY_LOOKUP_FOR_UNLINK, 0); + key_ref = lookup_user_key(id, 0, 0, 0); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error2; @@ -474,7 +465,7 @@ long keyctl_describe_key(key_serial_t keyid, char *tmpbuf; long ret; - key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); + key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); if (IS_ERR(key_ref)) { /* viewing a key under construction is permitted if we have the * authorisation token handy */ @@ -483,8 +474,7 @@ long keyctl_describe_key(key_serial_t keyid, if (!IS_ERR(instkey)) { key_put(instkey); key_ref = lookup_user_key(keyid, - KEY_LOOKUP_PARTIAL, - 0); + 0, 1, 0); if (!IS_ERR(key_ref)) goto okay; } @@ -568,7 +558,7 @@ long keyctl_keyring_search(key_serial_t ringid, } /* get the keyring at which to begin the search */ - keyring_ref = lookup_user_key(ringid, 0, KEY_SEARCH); + keyring_ref = lookup_user_key(ringid, 0, 0, KEY_SEARCH); if (IS_ERR(keyring_ref)) { ret = PTR_ERR(keyring_ref); goto error2; @@ -577,8 +567,7 @@ long keyctl_keyring_search(key_serial_t ringid, /* get the destination keyring if specified */ dest_ref = NULL; if (destringid) { - dest_ref = lookup_user_key(destringid, KEY_LOOKUP_CREATE, - KEY_WRITE); + dest_ref = lookup_user_key(destringid, 1, 0, KEY_WRITE); if (IS_ERR(dest_ref)) { ret = PTR_ERR(dest_ref); goto error3; @@ -648,7 +637,7 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) long ret; /* find the key first */ - key_ref = lookup_user_key(keyid, 0, 0); + key_ref = lookup_user_key(keyid, 0, 0, 0); if (IS_ERR(key_ref)) { ret = -ENOKEY; goto error; @@ -711,8 +700,7 @@ long keyctl_chown_key(key_serial_t id, uid_t uid, gid_t gid) if (uid == (uid_t) -1 && gid == (gid_t) -1) goto error; - key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, - KEY_SETATTR); + key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error; @@ -817,8 +805,7 @@ long keyctl_setperm_key(key_serial_t id, key_perm_t perm) if (perm & ~(KEY_POS_ALL | KEY_USR_ALL | KEY_GRP_ALL | KEY_OTH_ALL)) goto error; - key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, - KEY_SETATTR); + key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error; @@ -860,7 +847,7 @@ static long get_instantiation_keyring(key_serial_t ringid, /* if a specific keyring is nominated by ID, then use that */ if (ringid > 0) { - dkref = lookup_user_key(ringid, KEY_LOOKUP_CREATE, KEY_WRITE); + dkref = lookup_user_key(ringid, 1, 0, KEY_WRITE); if (IS_ERR(dkref)) return PTR_ERR(dkref); *_dest_keyring = key_ref_to_ptr(dkref); @@ -1096,8 +1083,7 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) time_t expiry; long ret; - key_ref = lookup_user_key(id, KEY_LOOKUP_CREATE | KEY_LOOKUP_PARTIAL, - KEY_SETATTR); + key_ref = lookup_user_key(id, 1, 1, KEY_SETATTR); if (IS_ERR(key_ref)) { ret = PTR_ERR(key_ref); goto error; @@ -1115,7 +1101,6 @@ long keyctl_set_timeout(key_serial_t id, unsigned timeout) } key->expiry = expiry; - key_schedule_gc(key->expiry); up_write(&key->sem); key_put(key); @@ -1185,7 +1170,7 @@ long keyctl_get_security(key_serial_t keyid, char *context; long ret; - key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, KEY_VIEW); + key_ref = lookup_user_key(keyid, 0, 1, KEY_VIEW); if (IS_ERR(key_ref)) { if (PTR_ERR(key_ref) != -EACCES) return PTR_ERR(key_ref); @@ -1197,7 +1182,7 @@ long keyctl_get_security(key_serial_t keyid, return PTR_ERR(key_ref); key_put(instkey); - key_ref = lookup_user_key(keyid, KEY_LOOKUP_PARTIAL, 0); + key_ref = lookup_user_key(keyid, 0, 1, 0); if (IS_ERR(key_ref)) return PTR_ERR(key_ref); } @@ -1228,105 +1213,6 @@ long keyctl_get_security(key_serial_t keyid, return ret; } -/* - * attempt to install the calling process's session keyring on the process's - * parent process - * - the keyring must exist and must grant us LINK permission - * - implements keyctl(KEYCTL_SESSION_TO_PARENT) - */ -long keyctl_session_to_parent(void) -{ - struct task_struct *me, *parent; - const struct cred *mycred, *pcred; - struct cred *cred, *oldcred; - key_ref_t keyring_r; - int ret; - - keyring_r = lookup_user_key(KEY_SPEC_SESSION_KEYRING, 0, KEY_LINK); - if (IS_ERR(keyring_r)) - return PTR_ERR(keyring_r); - - /* our parent is going to need a new cred struct, a new tgcred struct - * and new security data, so we allocate them here to prevent ENOMEM in - * our parent */ - ret = -ENOMEM; - cred = cred_alloc_blank(); - if (!cred) - goto error_keyring; - - cred->tgcred->session_keyring = key_ref_to_ptr(keyring_r); - keyring_r = NULL; - - me = current; - write_lock_irq(&tasklist_lock); - - parent = me->real_parent; - ret = -EPERM; - - /* the parent mustn't be init and mustn't be a kernel thread */ - if (parent->pid <= 1 || !parent->mm) - goto not_permitted; - - /* the parent must be single threaded */ - if (atomic_read(&parent->signal->count) != 1) - goto not_permitted; - - /* the parent and the child must have different session keyrings or - * there's no point */ - mycred = current_cred(); - pcred = __task_cred(parent); - if (mycred == pcred || - mycred->tgcred->session_keyring == pcred->tgcred->session_keyring) - goto already_same; - - /* the parent must have the same effective ownership and mustn't be - * SUID/SGID */ - if (pcred-> uid != mycred->euid || - pcred->euid != mycred->euid || - pcred->suid != mycred->euid || - pcred-> gid != mycred->egid || - pcred->egid != mycred->egid || - pcred->sgid != mycred->egid) - goto not_permitted; - - /* the keyrings must have the same UID */ - if (pcred ->tgcred->session_keyring->uid != mycred->euid || - mycred->tgcred->session_keyring->uid != mycred->euid) - goto not_permitted; - - /* the LSM must permit the replacement of the parent's keyring with the - * keyring from this process */ - ret = security_key_session_to_parent(mycred, pcred, - key_ref_to_ptr(keyring_r)); - if (ret < 0) - goto not_permitted; - - /* if there's an already pending keyring replacement, then we replace - * that */ - oldcred = parent->replacement_session_keyring; - - /* the replacement session keyring is applied just prior to userspace - * restarting */ - parent->replacement_session_keyring = cred; - cred = NULL; - set_ti_thread_flag(task_thread_info(parent), TIF_NOTIFY_RESUME); - - write_unlock_irq(&tasklist_lock); - if (oldcred) - put_cred(oldcred); - return 0; - -already_same: - ret = 0; -not_permitted: - put_cred(cred); - return ret; - -error_keyring: - key_ref_put(keyring_r); - return ret; -} - /*****************************************************************************/ /* * the key control system call @@ -1412,9 +1298,6 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, (char __user *) arg3, (size_t) arg4); - case KEYCTL_SESSION_TO_PARENT: - return keyctl_session_to_parent(); - default: return -EOPNOTSUPP; } diff --git a/trunk/security/keys/keyring.c b/trunk/security/keys/keyring.c index ac977f661a79..3dba81c2eba3 100644 --- a/trunk/security/keys/keyring.c +++ b/trunk/security/keys/keyring.c @@ -1000,88 +1000,3 @@ static void keyring_revoke(struct key *keyring) } } /* end keyring_revoke() */ - -/* - * Determine whether a key is dead - */ -static bool key_is_dead(struct key *key, time_t limit) -{ - return test_bit(KEY_FLAG_DEAD, &key->flags) || - (key->expiry > 0 && key->expiry <= limit); -} - -/* - * Collect garbage from the contents of a keyring - */ -void keyring_gc(struct key *keyring, time_t limit) -{ - struct keyring_list *klist, *new; - struct key *key; - int loop, keep, max; - - kenter("%x", key_serial(keyring)); - - down_write(&keyring->sem); - - klist = keyring->payload.subscriptions; - if (!klist) - goto just_return; - - /* work out how many subscriptions we're keeping */ - keep = 0; - for (loop = klist->nkeys - 1; loop >= 0; loop--) - if (!key_is_dead(klist->keys[loop], limit)); - keep++; - - if (keep == klist->nkeys) - goto just_return; - - /* allocate a new keyring payload */ - max = roundup(keep, 4); - new = kmalloc(sizeof(struct keyring_list) + max * sizeof(struct key *), - GFP_KERNEL); - if (!new) - goto just_return; - new->maxkeys = max; - new->nkeys = 0; - new->delkey = 0; - - /* install the live keys - * - must take care as expired keys may be updated back to life - */ - keep = 0; - for (loop = klist->nkeys - 1; loop >= 0; loop--) { - key = klist->keys[loop]; - if (!key_is_dead(key, limit)) { - if (keep >= max) - goto discard_new; - new->keys[keep++] = key_get(key); - } - } - new->nkeys = keep; - - /* adjust the quota */ - key_payload_reserve(keyring, - sizeof(struct keyring_list) + - KEYQUOTA_LINK_BYTES * keep); - - if (keep == 0) { - rcu_assign_pointer(keyring->payload.subscriptions, NULL); - kfree(new); - } else { - rcu_assign_pointer(keyring->payload.subscriptions, new); - } - - up_write(&keyring->sem); - - call_rcu(&klist->rcu, keyring_clear_rcu_disposal); - kleave(" [yes]"); - return; - -discard_new: - new->nkeys = keep; - keyring_clear_rcu_disposal(&new->rcu); -just_return: - up_write(&keyring->sem); - kleave(" [no]"); -} diff --git a/trunk/security/keys/proc.c b/trunk/security/keys/proc.c index 9d01021ca0c8..769f9bdfd2b3 100644 --- a/trunk/security/keys/proc.c +++ b/trunk/security/keys/proc.c @@ -91,94 +91,59 @@ __initcall(key_proc_init); */ #ifdef CONFIG_KEYS_DEBUG_PROC_KEYS -static struct rb_node *key_serial_next(struct rb_node *n) +static struct rb_node *__key_serial_next(struct rb_node *n) { - struct user_namespace *user_ns = current_user_ns(); - - n = rb_next(n); while (n) { struct key *key = rb_entry(n, struct key, serial_node); - if (key->user->user_ns == user_ns) + if (key->user->user_ns == current_user_ns()) break; n = rb_next(n); } return n; } -static int proc_keys_open(struct inode *inode, struct file *file) +static struct rb_node *key_serial_next(struct rb_node *n) { - return seq_open(file, &proc_keys_ops); + return __key_serial_next(rb_next(n)); } -static struct key *find_ge_key(key_serial_t id) +static struct rb_node *key_serial_first(struct rb_root *r) { - struct user_namespace *user_ns = current_user_ns(); - struct rb_node *n = key_serial_tree.rb_node; - struct key *minkey = NULL; - - while (n) { - struct key *key = rb_entry(n, struct key, serial_node); - if (id < key->serial) { - if (!minkey || minkey->serial > key->serial) - minkey = key; - n = n->rb_left; - } else if (id > key->serial) { - n = n->rb_right; - } else { - minkey = key; - break; - } - key = NULL; - } + struct rb_node *n = rb_first(r); + return __key_serial_next(n); +} - if (!minkey) - return NULL; +static int proc_keys_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &proc_keys_ops); - for (;;) { - if (minkey->user->user_ns == user_ns) - return minkey; - n = rb_next(&minkey->serial_node); - if (!n) - return NULL; - minkey = rb_entry(n, struct key, serial_node); - } } static void *proc_keys_start(struct seq_file *p, loff_t *_pos) - __acquires(key_serial_lock) { - key_serial_t pos = *_pos; - struct key *key; + struct rb_node *_p; + loff_t pos = *_pos; spin_lock(&key_serial_lock); - if (*_pos > INT_MAX) - return NULL; - key = find_ge_key(pos); - if (!key) - return NULL; - *_pos = key->serial; - return &key->serial_node; -} + _p = key_serial_first(&key_serial_tree); + while (pos > 0 && _p) { + pos--; + _p = key_serial_next(_p); + } + + return _p; -static inline key_serial_t key_node_serial(struct rb_node *n) -{ - struct key *key = rb_entry(n, struct key, serial_node); - return key->serial; } static void *proc_keys_next(struct seq_file *p, void *v, loff_t *_pos) { - struct rb_node *n; + (*_pos)++; + return key_serial_next((struct rb_node *) v); - n = key_serial_next(v); - if (n) - *_pos = key_node_serial(n); - return n; } static void proc_keys_stop(struct seq_file *p, void *v) - __releases(key_serial_lock) { spin_unlock(&key_serial_lock); } @@ -209,9 +174,11 @@ static int proc_keys_show(struct seq_file *m, void *v) /* come up with a suitable timeout value */ if (key->expiry == 0) { memcpy(xbuf, "perm", 5); - } else if (now.tv_sec >= key->expiry) { + } + else if (now.tv_sec >= key->expiry) { memcpy(xbuf, "expd", 5); - } else { + } + else { timo = key->expiry - now.tv_sec; if (timo < 60) @@ -251,7 +218,9 @@ static int proc_keys_show(struct seq_file *m, void *v) seq_putc(m, '\n'); rcu_read_unlock(); + return 0; + } #endif /* CONFIG_KEYS_DEBUG_PROC_KEYS */ @@ -277,7 +246,6 @@ static struct rb_node *key_user_first(struct rb_root *r) struct rb_node *n = rb_first(r); return __key_user_next(n); } - /*****************************************************************************/ /* * implement "/proc/key-users" to provides a list of the key users @@ -285,10 +253,10 @@ static struct rb_node *key_user_first(struct rb_root *r) static int proc_key_users_open(struct inode *inode, struct file *file) { return seq_open(file, &proc_key_users_ops); + } static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) - __acquires(key_user_lock) { struct rb_node *_p; loff_t pos = *_pos; @@ -302,16 +270,17 @@ static void *proc_key_users_start(struct seq_file *p, loff_t *_pos) } return _p; + } static void *proc_key_users_next(struct seq_file *p, void *v, loff_t *_pos) { (*_pos)++; return key_user_next((struct rb_node *) v); + } static void proc_key_users_stop(struct seq_file *p, void *v) - __releases(key_user_lock) { spin_unlock(&key_user_lock); } diff --git a/trunk/security/keys/process_keys.c b/trunk/security/keys/process_keys.c index 5c23afb31ece..276d27882ce8 100644 --- a/trunk/security/keys/process_keys.c +++ b/trunk/security/keys/process_keys.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include "internal.h" @@ -488,7 +487,7 @@ static int lookup_user_key_possessed(const struct key *key, const void *target) * - don't create special keyrings unless so requested * - partially constructed keys aren't found unless requested */ -key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, +key_ref_t lookup_user_key(key_serial_t id, int create, int partial, key_perm_t perm) { struct request_key_auth *rka; @@ -504,7 +503,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, switch (id) { case KEY_SPEC_THREAD_KEYRING: if (!cred->thread_keyring) { - if (!(lflags & KEY_LOOKUP_CREATE)) + if (!create) goto error; ret = install_thread_keyring(); @@ -522,7 +521,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, case KEY_SPEC_PROCESS_KEYRING: if (!cred->tgcred->process_keyring) { - if (!(lflags & KEY_LOOKUP_CREATE)) + if (!create) goto error; ret = install_process_keyring(); @@ -643,14 +642,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, break; } - /* unlink does not use the nominated key in any way, so can skip all - * the permission checks as it is only concerned with the keyring */ - if (lflags & KEY_LOOKUP_FOR_UNLINK) { - ret = 0; - goto error; - } - - if (!(lflags & KEY_LOOKUP_PARTIAL)) { + if (!partial) { ret = wait_for_key_construction(key, true); switch (ret) { case -ERESTARTSYS: @@ -668,8 +660,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags, } ret = -EIO; - if (!(lflags & KEY_LOOKUP_PARTIAL) && - !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) + if (!partial && !test_bit(KEY_FLAG_INSTANTIATED, &key->flags)) goto invalid_key; /* check the permissions */ @@ -711,7 +702,7 @@ long join_session_keyring(const char *name) /* only permit this if there's a single thread in the thread group - * this avoids us having to adjust the creds on all threads and risking * ENOMEM */ - if (!current_is_single_threaded()) + if (!is_single_threaded(current)) return -EMLINK; new = prepare_creds(); @@ -769,51 +760,3 @@ long join_session_keyring(const char *name) abort_creds(new); return ret; } - -/* - * Replace a process's session keyring when that process resumes userspace on - * behalf of one of its children - */ -void key_replace_session_keyring(void) -{ - const struct cred *old; - struct cred *new; - - if (!current->replacement_session_keyring) - return; - - write_lock_irq(&tasklist_lock); - new = current->replacement_session_keyring; - current->replacement_session_keyring = NULL; - write_unlock_irq(&tasklist_lock); - - if (!new) - return; - - old = current_cred(); - new-> uid = old-> uid; - new-> euid = old-> euid; - new-> suid = old-> suid; - new->fsuid = old->fsuid; - new-> gid = old-> gid; - new-> egid = old-> egid; - new-> sgid = old-> sgid; - new->fsgid = old->fsgid; - new->user = get_uid(old->user); - new->group_info = get_group_info(old->group_info); - - new->securebits = old->securebits; - new->cap_inheritable = old->cap_inheritable; - new->cap_permitted = old->cap_permitted; - new->cap_effective = old->cap_effective; - new->cap_bset = old->cap_bset; - - new->jit_keyring = old->jit_keyring; - new->thread_keyring = key_get(old->thread_keyring); - new->tgcred->tgid = old->tgcred->tgid; - new->tgcred->process_keyring = key_get(old->tgcred->process_keyring); - - security_transfer_creds(new, old); - - commit_creds(new); -} diff --git a/trunk/security/keys/sysctl.c b/trunk/security/keys/sysctl.c index 5e05dc09e2db..b611d493c2d8 100644 --- a/trunk/security/keys/sysctl.c +++ b/trunk/security/keys/sysctl.c @@ -13,8 +13,6 @@ #include #include "internal.h" -static const int zero, one = 1, max = INT_MAX; - ctl_table key_sysctls[] = { { .ctl_name = CTL_UNNUMBERED, @@ -22,9 +20,7 @@ ctl_table key_sysctls[] = { .data = &key_quota_maxkeys, .maxlen = sizeof(unsigned), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = (void *) &one, - .extra2 = (void *) &max, + .proc_handler = &proc_dointvec, }, { .ctl_name = CTL_UNNUMBERED, @@ -32,9 +28,7 @@ ctl_table key_sysctls[] = { .data = &key_quota_maxbytes, .maxlen = sizeof(unsigned), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = (void *) &one, - .extra2 = (void *) &max, + .proc_handler = &proc_dointvec, }, { .ctl_name = CTL_UNNUMBERED, @@ -42,9 +36,7 @@ ctl_table key_sysctls[] = { .data = &key_quota_root_maxkeys, .maxlen = sizeof(unsigned), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = (void *) &one, - .extra2 = (void *) &max, + .proc_handler = &proc_dointvec, }, { .ctl_name = CTL_UNNUMBERED, @@ -52,19 +44,7 @@ ctl_table key_sysctls[] = { .data = &key_quota_root_maxbytes, .maxlen = sizeof(unsigned), .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = (void *) &one, - .extra2 = (void *) &max, - }, - { - .ctl_name = CTL_UNNUMBERED, - .procname = "gc_delay", - .data = &key_gc_delay, - .maxlen = sizeof(unsigned), - .mode = 0644, - .proc_handler = &proc_dointvec_minmax, - .extra1 = (void *) &zero, - .extra2 = (void *) &max, + .proc_handler = &proc_dointvec, }, { .ctl_name = 0 } }; diff --git a/trunk/security/lsm_audit.c b/trunk/security/lsm_audit.c index 500aad0ebd6a..94b868494b31 100644 --- a/trunk/security/lsm_audit.c +++ b/trunk/security/lsm_audit.c @@ -220,8 +220,6 @@ static void dump_common_audit_data(struct audit_buffer *ab, } switch (a->type) { - case LSM_AUDIT_NO_AUDIT: - return; case LSM_AUDIT_DATA_IPC: audit_log_format(ab, " key=%d ", a->u.ipc_id); break; diff --git a/trunk/security/security.c b/trunk/security/security.c index c4c673240c1c..dc7674fbfc7a 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -124,9 +124,9 @@ int register_security(struct security_operations *ops) /* Security operations */ -int security_ptrace_access_check(struct task_struct *child, unsigned int mode) +int security_ptrace_may_access(struct task_struct *child, unsigned int mode) { - return security_ops->ptrace_access_check(child, mode); + return security_ops->ptrace_may_access(child, mode); } int security_ptrace_traceme(struct task_struct *parent) @@ -684,11 +684,6 @@ int security_task_create(unsigned long clone_flags) return security_ops->task_create(clone_flags); } -int security_cred_alloc_blank(struct cred *cred, gfp_t gfp) -{ - return security_ops->cred_alloc_blank(cred, gfp); -} - void security_cred_free(struct cred *cred) { security_ops->cred_free(cred); @@ -704,11 +699,6 @@ void security_commit_creds(struct cred *new, const struct cred *old) security_ops->cred_commit(new, old); } -void security_transfer_creds(struct cred *new, const struct cred *old) -{ - security_ops->cred_transfer(new, old); -} - int security_kernel_act_as(struct cred *new, u32 secid) { return security_ops->kernel_act_as(new, secid); @@ -719,11 +709,6 @@ int security_kernel_create_files_as(struct cred *new, struct inode *inode) return security_ops->kernel_create_files_as(new, inode); } -int security_kernel_module_request(void) -{ - return security_ops->kernel_module_request(); -} - int security_task_setuid(uid_t id0, uid_t id1, uid_t id2, int flags) { return security_ops->task_setuid(id0, id1, id2, flags); @@ -974,24 +959,6 @@ void security_release_secctx(char *secdata, u32 seclen) } EXPORT_SYMBOL(security_release_secctx); -int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) -{ - return security_ops->inode_notifysecctx(inode, ctx, ctxlen); -} -EXPORT_SYMBOL(security_inode_notifysecctx); - -int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - return security_ops->inode_setsecctx(dentry, ctx, ctxlen); -} -EXPORT_SYMBOL(security_inode_setsecctx); - -int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) -{ - return security_ops->inode_getsecctx(inode, ctx, ctxlen); -} -EXPORT_SYMBOL(security_inode_getsecctx); - #ifdef CONFIG_SECURITY_NETWORK int security_unix_stream_connect(struct socket *sock, struct socket *other, @@ -1145,24 +1112,6 @@ void security_inet_conn_established(struct sock *sk, security_ops->inet_conn_established(sk, skb); } -int security_tun_dev_create(void) -{ - return security_ops->tun_dev_create(); -} -EXPORT_SYMBOL(security_tun_dev_create); - -void security_tun_dev_post_create(struct sock *sk) -{ - return security_ops->tun_dev_post_create(sk); -} -EXPORT_SYMBOL(security_tun_dev_post_create); - -int security_tun_dev_attach(struct sock *sk) -{ - return security_ops->tun_dev_attach(sk); -} -EXPORT_SYMBOL(security_tun_dev_attach); - #endif /* CONFIG_SECURITY_NETWORK */ #ifdef CONFIG_SECURITY_NETWORK_XFRM @@ -1269,13 +1218,6 @@ int security_key_getsecurity(struct key *key, char **_buffer) return security_ops->key_getsecurity(key, _buffer); } -int security_key_session_to_parent(const struct cred *cred, - const struct cred *parent_cred, - struct key *key) -{ - return security_ops->key_session_to_parent(cred, parent_cred, key); -} - #endif /* CONFIG_KEYS */ #ifdef CONFIG_AUDIT diff --git a/trunk/security/selinux/avc.c b/trunk/security/selinux/avc.c index e3d19014259b..b2ab60859832 100644 --- a/trunk/security/selinux/avc.c +++ b/trunk/security/selinux/avc.c @@ -137,7 +137,7 @@ static inline int avc_hash(u32 ssid, u32 tsid, u16 tclass) * @tclass: target security class * @av: access vector */ -static void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) +void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av) { const char **common_pts = NULL; u32 common_base = 0; @@ -492,35 +492,23 @@ static struct avc_node *avc_insert(u32 ssid, u32 tsid, u16 tclass, struct av_dec return node; } -/** - * avc_audit_pre_callback - SELinux specific information - * will be called by generic audit code - * @ab: the audit buffer - * @a: audit_data - */ -static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) +static inline void avc_print_ipv6_addr(struct audit_buffer *ab, + struct in6_addr *addr, __be16 port, + char *name1, char *name2) { - struct common_audit_data *ad = a; - audit_log_format(ab, "avc: %s ", - ad->selinux_audit_data.denied ? "denied" : "granted"); - avc_dump_av(ab, ad->selinux_audit_data.tclass, - ad->selinux_audit_data.audited); - audit_log_format(ab, " for "); + if (!ipv6_addr_any(addr)) + audit_log_format(ab, " %s=%pI6", name1, addr); + if (port) + audit_log_format(ab, " %s=%d", name2, ntohs(port)); } -/** - * avc_audit_post_callback - SELinux specific information - * will be called by generic audit code - * @ab: the audit buffer - * @a: audit_data - */ -static void avc_audit_post_callback(struct audit_buffer *ab, void *a) +static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr, + __be16 port, char *name1, char *name2) { - struct common_audit_data *ad = a; - audit_log_format(ab, " "); - avc_dump_query(ab, ad->selinux_audit_data.ssid, - ad->selinux_audit_data.tsid, - ad->selinux_audit_data.tclass); + if (addr) + audit_log_format(ab, " %s=%pI4", name1, &addr); + if (port) + audit_log_format(ab, " %s=%d", name2, ntohs(port)); } /** @@ -544,10 +532,13 @@ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) */ void avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, - struct av_decision *avd, int result, struct common_audit_data *a) + struct av_decision *avd, int result, struct avc_audit_data *a) { - struct common_audit_data stack_data; + struct task_struct *tsk = current; + struct inode *inode = NULL; u32 denied, audited; + struct audit_buffer *ab; + denied = requested & ~avd->allowed; if (denied) { audited = denied; @@ -560,20 +551,144 @@ void avc_audit(u32 ssid, u32 tsid, if (!(audited & avd->auditallow)) return; } - if (!a) { - a = &stack_data; - memset(a, 0, sizeof(*a)); - a->type = LSM_AUDIT_NO_AUDIT; + + ab = audit_log_start(current->audit_context, GFP_ATOMIC, AUDIT_AVC); + if (!ab) + return; /* audit_panic has been called */ + audit_log_format(ab, "avc: %s ", denied ? "denied" : "granted"); + avc_dump_av(ab, tclass, audited); + audit_log_format(ab, " for "); + if (a && a->tsk) + tsk = a->tsk; + if (tsk && tsk->pid) { + audit_log_format(ab, " pid=%d comm=", tsk->pid); + audit_log_untrustedstring(ab, tsk->comm); } - a->selinux_audit_data.tclass = tclass; - a->selinux_audit_data.requested = requested; - a->selinux_audit_data.ssid = ssid; - a->selinux_audit_data.tsid = tsid; - a->selinux_audit_data.audited = audited; - a->selinux_audit_data.denied = denied; - a->lsm_pre_audit = avc_audit_pre_callback; - a->lsm_post_audit = avc_audit_post_callback; - common_lsm_audit(a); + if (a) { + switch (a->type) { + case AVC_AUDIT_DATA_IPC: + audit_log_format(ab, " key=%d", a->u.ipc_id); + break; + case AVC_AUDIT_DATA_CAP: + audit_log_format(ab, " capability=%d", a->u.cap); + break; + case AVC_AUDIT_DATA_FS: + if (a->u.fs.path.dentry) { + struct dentry *dentry = a->u.fs.path.dentry; + if (a->u.fs.path.mnt) { + audit_log_d_path(ab, "path=", + &a->u.fs.path); + } else { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, dentry->d_name.name); + } + inode = dentry->d_inode; + } else if (a->u.fs.inode) { + struct dentry *dentry; + inode = a->u.fs.inode; + dentry = d_find_alias(inode); + if (dentry) { + audit_log_format(ab, " name="); + audit_log_untrustedstring(ab, dentry->d_name.name); + dput(dentry); + } + } + if (inode) + audit_log_format(ab, " dev=%s ino=%lu", + inode->i_sb->s_id, + inode->i_ino); + break; + case AVC_AUDIT_DATA_NET: + if (a->u.net.sk) { + struct sock *sk = a->u.net.sk; + struct unix_sock *u; + int len = 0; + char *p = NULL; + + switch (sk->sk_family) { + case AF_INET: { + struct inet_sock *inet = inet_sk(sk); + + avc_print_ipv4_addr(ab, inet->rcv_saddr, + inet->sport, + "laddr", "lport"); + avc_print_ipv4_addr(ab, inet->daddr, + inet->dport, + "faddr", "fport"); + break; + } + case AF_INET6: { + struct inet_sock *inet = inet_sk(sk); + struct ipv6_pinfo *inet6 = inet6_sk(sk); + + avc_print_ipv6_addr(ab, &inet6->rcv_saddr, + inet->sport, + "laddr", "lport"); + avc_print_ipv6_addr(ab, &inet6->daddr, + inet->dport, + "faddr", "fport"); + break; + } + case AF_UNIX: + u = unix_sk(sk); + if (u->dentry) { + struct path path = { + .dentry = u->dentry, + .mnt = u->mnt + }; + audit_log_d_path(ab, "path=", + &path); + break; + } + if (!u->addr) + break; + len = u->addr->len-sizeof(short); + p = &u->addr->name->sun_path[0]; + audit_log_format(ab, " path="); + if (*p) + audit_log_untrustedstring(ab, p); + else + audit_log_n_hex(ab, p, len); + break; + } + } + + switch (a->u.net.family) { + case AF_INET: + avc_print_ipv4_addr(ab, a->u.net.v4info.saddr, + a->u.net.sport, + "saddr", "src"); + avc_print_ipv4_addr(ab, a->u.net.v4info.daddr, + a->u.net.dport, + "daddr", "dest"); + break; + case AF_INET6: + avc_print_ipv6_addr(ab, &a->u.net.v6info.saddr, + a->u.net.sport, + "saddr", "src"); + avc_print_ipv6_addr(ab, &a->u.net.v6info.daddr, + a->u.net.dport, + "daddr", "dest"); + break; + } + if (a->u.net.netif > 0) { + struct net_device *dev; + + /* NOTE: we always use init's namespace */ + dev = dev_get_by_index(&init_net, + a->u.net.netif); + if (dev) { + audit_log_format(ab, " netif=%s", + dev->name); + dev_put(dev); + } + } + break; + } + } + audit_log_format(ab, " "); + avc_dump_query(ab, ssid, tsid, tclass); + audit_log_end(ab); } /** @@ -841,7 +956,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, * another -errno upon other errors. */ int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, - u32 requested, struct common_audit_data *auditdata) + u32 requested, struct avc_audit_data *auditdata) { struct av_decision avd; int rc; @@ -855,9 +970,3 @@ u32 avc_policy_seqno(void) { return avc_cache.latest_notif; } - -void avc_disable(void) -{ - if (avc_node_cachep) - kmem_cache_destroy(avc_node_cachep); -} diff --git a/trunk/security/selinux/hooks.c b/trunk/security/selinux/hooks.c index 417f7c994522..8d8b69c5664e 100644 --- a/trunk/security/selinux/hooks.c +++ b/trunk/security/selinux/hooks.c @@ -13,8 +13,8 @@ * Eric Paris * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * - * Copyright (C) 2006, 2007, 2009 Hewlett-Packard Development Company, L.P. - * Paul Moore + * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. + * Paul Moore * Copyright (C) 2007 Hitachi Software Engineering Co., Ltd. * Yuichi Nakamura * @@ -448,10 +448,6 @@ static int sb_finish_set_opts(struct super_block *sb) sbsec->behavior > ARRAY_SIZE(labeling_behaviors)) sbsec->flags &= ~SE_SBLABELSUPP; - /* Special handling for sysfs. Is genfs but also has setxattr handler*/ - if (strncmp(sb->s_type->name, "sysfs", sizeof("sysfs")) == 0) - sbsec->flags |= SE_SBLABELSUPP; - /* Initialize the root inode. */ rc = inode_doinit_with_dentry(root_inode, root); @@ -1483,14 +1479,14 @@ static int task_has_capability(struct task_struct *tsk, const struct cred *cred, int cap, int audit) { - struct common_audit_data ad; + struct avc_audit_data ad; struct av_decision avd; u16 sclass; u32 sid = cred_sid(cred); u32 av = CAP_TO_MASK(cap); int rc; - COMMON_AUDIT_DATA_INIT(&ad, CAP); + AVC_AUDIT_DATA_INIT(&ad, CAP); ad.tsk = tsk; ad.u.cap = cap; @@ -1529,14 +1525,12 @@ static int task_has_system(struct task_struct *tsk, static int inode_has_perm(const struct cred *cred, struct inode *inode, u32 perms, - struct common_audit_data *adp) + struct avc_audit_data *adp) { struct inode_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid; - validate_creds(cred); - if (unlikely(IS_PRIVATE(inode))) return 0; @@ -1545,7 +1539,7 @@ static int inode_has_perm(const struct cred *cred, if (!adp) { adp = &ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.inode = inode; } @@ -1561,9 +1555,9 @@ static inline int dentry_has_perm(const struct cred *cred, u32 av) { struct inode *inode = dentry->d_inode; - struct common_audit_data ad; + struct avc_audit_data ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.mnt = mnt; ad.u.fs.path.dentry = dentry; return inode_has_perm(cred, inode, av, &ad); @@ -1583,11 +1577,11 @@ static int file_has_perm(const struct cred *cred, { struct file_security_struct *fsec = file->f_security; struct inode *inode = file->f_path.dentry->d_inode; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = cred_sid(cred); int rc; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path = file->f_path; if (sid != fsec->sid) { @@ -1618,7 +1612,7 @@ static int may_create(struct inode *dir, struct inode_security_struct *dsec; struct superblock_security_struct *sbsec; u32 sid, newsid; - struct common_audit_data ad; + struct avc_audit_data ad; int rc; dsec = dir->i_security; @@ -1627,7 +1621,7 @@ static int may_create(struct inode *dir, sid = tsec->sid; newsid = tsec->create_sid; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = dentry; rc = avc_has_perm(sid, dsec->sid, SECCLASS_DIR, @@ -1671,7 +1665,7 @@ static int may_link(struct inode *dir, { struct inode_security_struct *dsec, *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); u32 av; int rc; @@ -1679,7 +1673,7 @@ static int may_link(struct inode *dir, dsec = dir->i_security; isec = dentry->d_inode->i_security; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = dentry; av = DIR__SEARCH; @@ -1714,7 +1708,7 @@ static inline int may_rename(struct inode *old_dir, struct dentry *new_dentry) { struct inode_security_struct *old_dsec, *new_dsec, *old_isec, *new_isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); u32 av; int old_is_dir, new_is_dir; @@ -1725,7 +1719,7 @@ static inline int may_rename(struct inode *old_dir, old_is_dir = S_ISDIR(old_dentry->d_inode->i_mode); new_dsec = new_dir->i_security; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = old_dentry; rc = avc_has_perm(sid, old_dsec->sid, SECCLASS_DIR, @@ -1767,7 +1761,7 @@ static inline int may_rename(struct inode *old_dir, static int superblock_has_perm(const struct cred *cred, struct super_block *sb, u32 perms, - struct common_audit_data *ad) + struct avc_audit_data *ad) { struct superblock_security_struct *sbsec; u32 sid = cred_sid(cred); @@ -1861,12 +1855,12 @@ static inline u32 open_file_to_av(struct file *file) /* Hook functions begin here. */ -static int selinux_ptrace_access_check(struct task_struct *child, +static int selinux_ptrace_may_access(struct task_struct *child, unsigned int mode) { int rc; - rc = cap_ptrace_access_check(child, mode); + rc = cap_ptrace_may_access(child, mode); if (rc) return rc; @@ -2107,7 +2101,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) const struct task_security_struct *old_tsec; struct task_security_struct *new_tsec; struct inode_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; struct inode *inode = bprm->file->f_path.dentry->d_inode; int rc; @@ -2145,7 +2139,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) return rc; } - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path = bprm->file->f_path; if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) @@ -2238,7 +2232,7 @@ extern struct dentry *selinux_null; static inline void flush_unauthorized_files(const struct cred *cred, struct files_struct *files) { - struct common_audit_data ad; + struct avc_audit_data ad; struct file *file, *devnull = NULL; struct tty_struct *tty; struct fdtable *fdt; @@ -2272,7 +2266,7 @@ static inline void flush_unauthorized_files(const struct cred *cred, /* Revalidate access to inherited open files. */ - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); spin_lock(&files->file_lock); for (;;) { @@ -2521,7 +2515,7 @@ static int selinux_sb_copy_data(char *orig, char *copy) static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) { const struct cred *cred = current_cred(); - struct common_audit_data ad; + struct avc_audit_data ad; int rc; rc = superblock_doinit(sb, data); @@ -2532,7 +2526,7 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) if (flags & MS_KERNMOUNT) return 0; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = sb->s_root; return superblock_has_perm(cred, sb, FILESYSTEM__MOUNT, &ad); } @@ -2540,9 +2534,9 @@ static int selinux_sb_kern_mount(struct super_block *sb, int flags, void *data) static int selinux_sb_statfs(struct dentry *dentry) { const struct cred *cred = current_cred(); - struct common_audit_data ad; + struct avc_audit_data ad; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = dentry->d_sb->s_root; return superblock_has_perm(cred, dentry->d_sb, FILESYSTEM__GETATTR, &ad); } @@ -2717,18 +2711,12 @@ static int selinux_inode_permission(struct inode *inode, int mask) static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) { const struct cred *cred = current_cred(); - unsigned int ia_valid = iattr->ia_valid; - - /* ATTR_FORCE is just used for ATTR_KILL_S[UG]ID. */ - if (ia_valid & ATTR_FORCE) { - ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_MODE | - ATTR_FORCE); - if (!ia_valid) - return 0; - } - if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | - ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) + if (iattr->ia_valid & ATTR_FORCE) + return 0; + + if (iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | + ATTR_ATIME_SET | ATTR_MTIME_SET)) return dentry_has_perm(cred, NULL, dentry, FILE__SETATTR); return dentry_has_perm(cred, NULL, dentry, FILE__WRITE); @@ -2768,7 +2756,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, struct inode *inode = dentry->d_inode; struct inode_security_struct *isec = inode->i_security; struct superblock_security_struct *sbsec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 newsid, sid = current_sid(); int rc = 0; @@ -2782,7 +2770,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, if (!is_owner_or_cap(inode)) return -EPERM; - COMMON_AUDIT_DATA_INIT(&ad, FS); + AVC_AUDIT_DATA_INIT(&ad, FS); ad.u.fs.path.dentry = dentry; rc = avc_has_perm(sid, isec->sid, isec->sclass, @@ -2927,7 +2915,6 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, return rc; isec->sid = newsid; - isec->initialized = 1; return 0; } @@ -2952,6 +2939,11 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) const struct cred *cred = current_cred(); struct inode *inode = file->f_path.dentry->d_inode; + if (!mask) { + /* No permission to check. Existence test. */ + return 0; + } + /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) mask |= MAY_APPEND; @@ -2962,20 +2954,10 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) static int selinux_file_permission(struct file *file, int mask) { - struct inode *inode = file->f_path.dentry->d_inode; - struct file_security_struct *fsec = file->f_security; - struct inode_security_struct *isec = inode->i_security; - u32 sid = current_sid(); - if (!mask) /* No permission to check. Existence test. */ return 0; - if (sid == fsec->sid && fsec->isid == isec->sid && - fsec->pseqno == avc_policy_seqno()) - /* No change since dentry_open check. */ - return 0; - return selinux_revalidate_file_permission(file, mask); } @@ -3237,30 +3219,13 @@ static int selinux_task_create(unsigned long clone_flags) return current_has_perm(current, PROCESS__FORK); } -/* - * allocate the SELinux part of blank credentials - */ -static int selinux_cred_alloc_blank(struct cred *cred, gfp_t gfp) -{ - struct task_security_struct *tsec; - - tsec = kzalloc(sizeof(struct task_security_struct), gfp); - if (!tsec) - return -ENOMEM; - - cred->security = tsec; - return 0; -} - /* * detach and free the LSM part of a set of credentials */ static void selinux_cred_free(struct cred *cred) { struct task_security_struct *tsec = cred->security; - - BUG_ON((unsigned long) cred->security < PAGE_SIZE); - cred->security = (void *) 0x7UL; + cred->security = NULL; kfree(tsec); } @@ -3283,17 +3248,6 @@ static int selinux_cred_prepare(struct cred *new, const struct cred *old, return 0; } -/* - * transfer the SELinux data to a blank set of creds - */ -static void selinux_cred_transfer(struct cred *new, const struct cred *old) -{ - const struct task_security_struct *old_tsec = old->security; - struct task_security_struct *tsec = new->security; - - *tsec = *old_tsec; -} - /* * set the security data for a kernel service * - all the creation contexts are set to unlabelled @@ -3338,11 +3292,6 @@ static int selinux_kernel_create_files_as(struct cred *new, struct inode *inode) return 0; } -static int selinux_kernel_module_request(void) -{ - return task_has_system(current, SYSTEM__MODULE_REQUEST); -} - static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) { return current_has_perm(p, PROCESS__SETPGID); @@ -3460,7 +3409,7 @@ static void selinux_task_to_inode(struct task_struct *p, /* Returns error only if unable to parse addresses */ static int selinux_parse_skb_ipv4(struct sk_buff *skb, - struct common_audit_data *ad, u8 *proto) + struct avc_audit_data *ad, u8 *proto) { int offset, ihlen, ret = -EINVAL; struct iphdr _iph, *ih; @@ -3541,7 +3490,7 @@ static int selinux_parse_skb_ipv4(struct sk_buff *skb, /* Returns error only if unable to parse addresses */ static int selinux_parse_skb_ipv6(struct sk_buff *skb, - struct common_audit_data *ad, u8 *proto) + struct avc_audit_data *ad, u8 *proto) { u8 nexthdr; int ret = -EINVAL, offset; @@ -3612,7 +3561,7 @@ static int selinux_parse_skb_ipv6(struct sk_buff *skb, #endif /* IPV6 */ -static int selinux_parse_skb(struct sk_buff *skb, struct common_audit_data *ad, +static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad, char **_addrp, int src, u8 *proto) { char *addrp; @@ -3694,7 +3643,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, u32 perms) { struct inode_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid; int err = 0; @@ -3704,7 +3653,7 @@ static int socket_has_perm(struct task_struct *task, struct socket *sock, goto out; sid = task_sid(task); - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.sk = sock->sk; err = avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); @@ -3791,7 +3740,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (family == PF_INET || family == PF_INET6) { char *addrp; struct inode_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; unsigned short snum; @@ -3820,7 +3769,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in snum, &sid); if (err) goto out; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.sport = htons(snum); ad.u.net.family = family; err = avc_has_perm(isec->sid, sid, @@ -3853,7 +3802,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in if (err) goto out; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.sport = htons(snum); ad.u.net.family = family; @@ -3887,7 +3836,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, isec = SOCK_INODE(sock)->i_security; if (isec->sclass == SECCLASS_TCP_SOCKET || isec->sclass == SECCLASS_DCCP_SOCKET) { - struct common_audit_data ad; + struct avc_audit_data ad; struct sockaddr_in *addr4 = NULL; struct sockaddr_in6 *addr6 = NULL; unsigned short snum; @@ -3912,7 +3861,7 @@ static int selinux_socket_connect(struct socket *sock, struct sockaddr *address, perm = (isec->sclass == SECCLASS_TCP_SOCKET) ? TCP_SOCKET__NAME_CONNECT : DCCP_SOCKET__NAME_CONNECT; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.dport = htons(snum); ad.u.net.family = sk->sk_family; err = avc_has_perm(isec->sid, sid, isec->sclass, perm, &ad); @@ -4002,13 +3951,13 @@ static int selinux_socket_unix_stream_connect(struct socket *sock, struct sk_security_struct *ssec; struct inode_security_struct *isec; struct inode_security_struct *other_isec; - struct common_audit_data ad; + struct avc_audit_data ad; int err; isec = SOCK_INODE(sock)->i_security; other_isec = SOCK_INODE(other)->i_security; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.sk = other->sk; err = avc_has_perm(isec->sid, other_isec->sid, @@ -4034,13 +3983,13 @@ static int selinux_socket_unix_may_send(struct socket *sock, { struct inode_security_struct *isec; struct inode_security_struct *other_isec; - struct common_audit_data ad; + struct avc_audit_data ad; int err; isec = SOCK_INODE(sock)->i_security; other_isec = SOCK_INODE(other)->i_security; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.sk = other->sk; err = avc_has_perm(isec->sid, other_isec->sid, @@ -4053,7 +4002,7 @@ static int selinux_socket_unix_may_send(struct socket *sock, static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family, u32 peer_sid, - struct common_audit_data *ad) + struct avc_audit_data *ad) { int err; u32 if_sid; @@ -4081,10 +4030,10 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb, struct sk_security_struct *sksec = sk->sk_security; u32 peer_sid; u32 sk_sid = sksec->sid; - struct common_audit_data ad; + struct avc_audit_data ad; char *addrp; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.netif = skb->iif; ad.u.net.family = family; err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); @@ -4122,7 +4071,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) struct sk_security_struct *sksec = sk->sk_security; u16 family = sk->sk_family; u32 sk_sid = sksec->sid; - struct common_audit_data ad; + struct avc_audit_data ad; char *addrp; u8 secmark_active; u8 peerlbl_active; @@ -4146,7 +4095,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb) if (!secmark_active && !peerlbl_active) return 0; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.netif = skb->iif; ad.u.net.family = family; err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL); @@ -4360,59 +4309,6 @@ static void selinux_req_classify_flow(const struct request_sock *req, fl->secid = req->secid; } -static int selinux_tun_dev_create(void) -{ - u32 sid = current_sid(); - - /* we aren't taking into account the "sockcreate" SID since the socket - * that is being created here is not a socket in the traditional sense, - * instead it is a private sock, accessible only to the kernel, and - * representing a wide range of network traffic spanning multiple - * connections unlike traditional sockets - check the TUN driver to - * get a better understanding of why this socket is special */ - - return avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, TUN_SOCKET__CREATE, - NULL); -} - -static void selinux_tun_dev_post_create(struct sock *sk) -{ - struct sk_security_struct *sksec = sk->sk_security; - - /* we don't currently perform any NetLabel based labeling here and it - * isn't clear that we would want to do so anyway; while we could apply - * labeling without the support of the TUN user the resulting labeled - * traffic from the other end of the connection would almost certainly - * cause confusion to the TUN user that had no idea network labeling - * protocols were being used */ - - /* see the comments in selinux_tun_dev_create() about why we don't use - * the sockcreate SID here */ - - sksec->sid = current_sid(); - sksec->sclass = SECCLASS_TUN_SOCKET; -} - -static int selinux_tun_dev_attach(struct sock *sk) -{ - struct sk_security_struct *sksec = sk->sk_security; - u32 sid = current_sid(); - int err; - - err = avc_has_perm(sid, sksec->sid, SECCLASS_TUN_SOCKET, - TUN_SOCKET__RELABELFROM, NULL); - if (err) - return err; - err = avc_has_perm(sid, sid, SECCLASS_TUN_SOCKET, - TUN_SOCKET__RELABELTO, NULL); - if (err) - return err; - - sksec->sid = sid; - - return 0; -} - static int selinux_nlmsg_perm(struct sock *sk, struct sk_buff *skb) { int err = 0; @@ -4457,7 +4353,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, int err; char *addrp; u32 peer_sid; - struct common_audit_data ad; + struct avc_audit_data ad; u8 secmark_active; u8 netlbl_active; u8 peerlbl_active; @@ -4474,7 +4370,7 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex, if (selinux_skb_peerlbl_sid(skb, family, &peer_sid) != 0) return NF_DROP; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.netif = ifindex; ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 1, NULL) != 0) @@ -4562,7 +4458,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, { struct sock *sk = skb->sk; struct sk_security_struct *sksec; - struct common_audit_data ad; + struct avc_audit_data ad; char *addrp; u8 proto; @@ -4570,7 +4466,7 @@ static unsigned int selinux_ip_postroute_compat(struct sk_buff *skb, return NF_ACCEPT; sksec = sk->sk_security; - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.netif = ifindex; ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, &proto)) @@ -4594,7 +4490,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, u32 secmark_perm; u32 peer_sid; struct sock *sk; - struct common_audit_data ad; + struct avc_audit_data ad; char *addrp; u8 secmark_active; u8 peerlbl_active; @@ -4653,7 +4549,7 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, int ifindex, secmark_perm = PACKET__SEND; } - COMMON_AUDIT_DATA_INIT(&ad, NET); + AVC_AUDIT_DATA_INIT(&ad, NET); ad.u.net.netif = ifindex; ad.u.net.family = family; if (selinux_parse_skb(skb, &ad, &addrp, 0, NULL)) @@ -4723,13 +4619,13 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb) static int selinux_netlink_recv(struct sk_buff *skb, int capability) { int err; - struct common_audit_data ad; + struct avc_audit_data ad; err = cap_netlink_recv(skb, capability); if (err) return err; - COMMON_AUDIT_DATA_INIT(&ad, CAP); + AVC_AUDIT_DATA_INIT(&ad, CAP); ad.u.cap = capability; return avc_has_perm(NETLINK_CB(skb).sid, NETLINK_CB(skb).sid, @@ -4788,12 +4684,12 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, u32 perms) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); isec = ipc_perms->security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = ipc_perms->key; return avc_has_perm(sid, isec->sid, isec->sclass, perms, &ad); @@ -4813,7 +4709,7 @@ static void selinux_msg_msg_free_security(struct msg_msg *msg) static int selinux_msg_queue_alloc_security(struct msg_queue *msq) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); int rc; @@ -4823,7 +4719,7 @@ static int selinux_msg_queue_alloc_security(struct msg_queue *msq) isec = msq->q_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4843,12 +4739,12 @@ static void selinux_msg_queue_free_security(struct msg_queue *msq) static int selinux_msg_queue_associate(struct msg_queue *msq, int msqflg) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); isec = msq->q_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_MSGQ, @@ -4887,7 +4783,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, { struct ipc_security_struct *isec; struct msg_security_struct *msec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); int rc; @@ -4908,7 +4804,7 @@ static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg, return rc; } - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; /* Can this process write to the queue? */ @@ -4932,14 +4828,14 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, { struct ipc_security_struct *isec; struct msg_security_struct *msec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = task_sid(target); int rc; isec = msq->q_perm.security; msec = msg->security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = msq->q_perm.key; rc = avc_has_perm(sid, isec->sid, @@ -4954,7 +4850,7 @@ static int selinux_msg_queue_msgrcv(struct msg_queue *msq, struct msg_msg *msg, static int selinux_shm_alloc_security(struct shmid_kernel *shp) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); int rc; @@ -4964,7 +4860,7 @@ static int selinux_shm_alloc_security(struct shmid_kernel *shp) isec = shp->shm_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = shp->shm_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -4984,12 +4880,12 @@ static void selinux_shm_free_security(struct shmid_kernel *shp) static int selinux_shm_associate(struct shmid_kernel *shp, int shmflg) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); isec = shp->shm_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = shp->shm_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SHM, @@ -5046,7 +4942,7 @@ static int selinux_shm_shmat(struct shmid_kernel *shp, static int selinux_sem_alloc_security(struct sem_array *sma) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); int rc; @@ -5056,7 +4952,7 @@ static int selinux_sem_alloc_security(struct sem_array *sma) isec = sma->sem_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = sma->sem_perm.key; rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM, @@ -5076,12 +4972,12 @@ static void selinux_sem_free_security(struct sem_array *sma) static int selinux_sem_associate(struct sem_array *sma, int semflg) { struct ipc_security_struct *isec; - struct common_audit_data ad; + struct avc_audit_data ad; u32 sid = current_sid(); isec = sma->sem_perm.security; - COMMON_AUDIT_DATA_INIT(&ad, IPC); + AVC_AUDIT_DATA_INIT(&ad, IPC); ad.u.ipc_id = sma->sem_perm.key; return avc_has_perm(sid, isec->sid, SECCLASS_SEM, @@ -5299,7 +5195,7 @@ static int selinux_setprocattr(struct task_struct *p, /* Only allow single threaded processes to change context */ error = -EPERM; - if (!current_is_single_threaded()) { + if (!is_single_threaded(p)) { error = security_bounded_transition(tsec->sid, sid); if (error) goto abort_change; @@ -5356,32 +5252,6 @@ static void selinux_release_secctx(char *secdata, u32 seclen) kfree(secdata); } -/* - * called with inode->i_mutex locked - */ -static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) -{ - return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0); -} - -/* - * called with inode->i_mutex locked - */ -static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0); -} - -static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) -{ - int len = 0; - len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX, - ctx, true); - if (len < 0) - return len; - *ctxlen = len; - return 0; -} #ifdef CONFIG_KEYS static int selinux_key_alloc(struct key *k, const struct cred *cred, @@ -5453,7 +5323,7 @@ static int selinux_key_getsecurity(struct key *key, char **_buffer) static struct security_operations selinux_ops = { .name = "selinux", - .ptrace_access_check = selinux_ptrace_access_check, + .ptrace_may_access = selinux_ptrace_may_access, .ptrace_traceme = selinux_ptrace_traceme, .capget = selinux_capget, .capset = selinux_capset, @@ -5526,13 +5396,10 @@ static struct security_operations selinux_ops = { .dentry_open = selinux_dentry_open, .task_create = selinux_task_create, - .cred_alloc_blank = selinux_cred_alloc_blank, .cred_free = selinux_cred_free, .cred_prepare = selinux_cred_prepare, - .cred_transfer = selinux_cred_transfer, .kernel_act_as = selinux_kernel_act_as, .kernel_create_files_as = selinux_kernel_create_files_as, - .kernel_module_request = selinux_kernel_module_request, .task_setpgid = selinux_task_setpgid, .task_getpgid = selinux_task_getpgid, .task_getsid = selinux_task_getsid, @@ -5581,9 +5448,6 @@ static struct security_operations selinux_ops = { .secid_to_secctx = selinux_secid_to_secctx, .secctx_to_secid = selinux_secctx_to_secid, .release_secctx = selinux_release_secctx, - .inode_notifysecctx = selinux_inode_notifysecctx, - .inode_setsecctx = selinux_inode_setsecctx, - .inode_getsecctx = selinux_inode_getsecctx, .unix_stream_connect = selinux_socket_unix_stream_connect, .unix_may_send = selinux_socket_unix_may_send, @@ -5613,9 +5477,6 @@ static struct security_operations selinux_ops = { .inet_csk_clone = selinux_inet_csk_clone, .inet_conn_established = selinux_inet_conn_established, .req_classify_flow = selinux_req_classify_flow, - .tun_dev_create = selinux_tun_dev_create, - .tun_dev_post_create = selinux_tun_dev_post_create, - .tun_dev_attach = selinux_tun_dev_attach, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, @@ -5830,9 +5691,6 @@ int selinux_disable(void) selinux_disabled = 1; selinux_enabled = 0; - /* Try to destroy the avc node cache */ - avc_disable(); - /* Reset security_ops to the secondary module, dummy or capability. */ security_ops = secondary_ops; diff --git a/trunk/security/selinux/include/av_inherit.h b/trunk/security/selinux/include/av_inherit.h index abedcd704dae..8377a4ba3b95 100644 --- a/trunk/security/selinux/include/av_inherit.h +++ b/trunk/security/selinux/include/av_inherit.h @@ -15,7 +15,6 @@ S_(SECCLASS_KEY_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_STREAM_SOCKET, socket, 0x00400000UL) S_(SECCLASS_UNIX_DGRAM_SOCKET, socket, 0x00400000UL) - S_(SECCLASS_TUN_SOCKET, socket, 0x00400000UL) S_(SECCLASS_IPC, ipc, 0x00000200UL) S_(SECCLASS_SEM, ipc, 0x00000200UL) S_(SECCLASS_MSGQ, ipc, 0x00000200UL) diff --git a/trunk/security/selinux/include/av_perm_to_string.h b/trunk/security/selinux/include/av_perm_to_string.h index 2b683ad83d21..31df1d7c1aee 100644 --- a/trunk/security/selinux/include/av_perm_to_string.h +++ b/trunk/security/selinux/include/av_perm_to_string.h @@ -107,7 +107,6 @@ S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_READ, "syslog_read") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_MOD, "syslog_mod") S_(SECCLASS_SYSTEM, SYSTEM__SYSLOG_CONSOLE, "syslog_console") - S_(SECCLASS_SYSTEM, SYSTEM__MODULE_REQUEST, "module_request") S_(SECCLASS_CAPABILITY, CAPABILITY__CHOWN, "chown") S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_OVERRIDE, "dac_override") S_(SECCLASS_CAPABILITY, CAPABILITY__DAC_READ_SEARCH, "dac_read_search") diff --git a/trunk/security/selinux/include/av_permissions.h b/trunk/security/selinux/include/av_permissions.h index 0546d616ccac..d645192ee950 100644 --- a/trunk/security/selinux/include/av_permissions.h +++ b/trunk/security/selinux/include/av_permissions.h @@ -423,28 +423,6 @@ #define UNIX_DGRAM_SOCKET__RECV_MSG 0x00080000UL #define UNIX_DGRAM_SOCKET__SEND_MSG 0x00100000UL #define UNIX_DGRAM_SOCKET__NAME_BIND 0x00200000UL -#define TUN_SOCKET__IOCTL 0x00000001UL -#define TUN_SOCKET__READ 0x00000002UL -#define TUN_SOCKET__WRITE 0x00000004UL -#define TUN_SOCKET__CREATE 0x00000008UL -#define TUN_SOCKET__GETATTR 0x00000010UL -#define TUN_SOCKET__SETATTR 0x00000020UL -#define TUN_SOCKET__LOCK 0x00000040UL -#define TUN_SOCKET__RELABELFROM 0x00000080UL -#define TUN_SOCKET__RELABELTO 0x00000100UL -#define TUN_SOCKET__APPEND 0x00000200UL -#define TUN_SOCKET__BIND 0x00000400UL -#define TUN_SOCKET__CONNECT 0x00000800UL -#define TUN_SOCKET__LISTEN 0x00001000UL -#define TUN_SOCKET__ACCEPT 0x00002000UL -#define TUN_SOCKET__GETOPT 0x00004000UL -#define TUN_SOCKET__SETOPT 0x00008000UL -#define TUN_SOCKET__SHUTDOWN 0x00010000UL -#define TUN_SOCKET__RECVFROM 0x00020000UL -#define TUN_SOCKET__SENDTO 0x00040000UL -#define TUN_SOCKET__RECV_MSG 0x00080000UL -#define TUN_SOCKET__SEND_MSG 0x00100000UL -#define TUN_SOCKET__NAME_BIND 0x00200000UL #define PROCESS__FORK 0x00000001UL #define PROCESS__TRANSITION 0x00000002UL #define PROCESS__SIGCHLD 0x00000004UL @@ -530,7 +508,6 @@ #define SYSTEM__SYSLOG_READ 0x00000002UL #define SYSTEM__SYSLOG_MOD 0x00000004UL #define SYSTEM__SYSLOG_CONSOLE 0x00000008UL -#define SYSTEM__MODULE_REQUEST 0x00000010UL #define CAPABILITY__CHOWN 0x00000001UL #define CAPABILITY__DAC_OVERRIDE 0x00000002UL #define CAPABILITY__DAC_READ_SEARCH 0x00000004UL diff --git a/trunk/security/selinux/include/avc.h b/trunk/security/selinux/include/avc.h index e94e82f73818..d12ff1a9c0aa 100644 --- a/trunk/security/selinux/include/avc.h +++ b/trunk/security/selinux/include/avc.h @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,48 @@ struct inode; struct sock; struct sk_buff; +/* Auxiliary data to use in generating the audit record. */ +struct avc_audit_data { + char type; +#define AVC_AUDIT_DATA_FS 1 +#define AVC_AUDIT_DATA_NET 2 +#define AVC_AUDIT_DATA_CAP 3 +#define AVC_AUDIT_DATA_IPC 4 + struct task_struct *tsk; + union { + struct { + struct path path; + struct inode *inode; + } fs; + struct { + int netif; + struct sock *sk; + u16 family; + __be16 dport; + __be16 sport; + union { + struct { + __be32 daddr; + __be32 saddr; + } v4; + struct { + struct in6_addr daddr; + struct in6_addr saddr; + } v6; + } fam; + } net; + int cap; + int ipc_id; + } u; +}; + +#define v4info fam.v4 +#define v6info fam.v6 + +/* Initialize an AVC audit data structure. */ +#define AVC_AUDIT_DATA_INIT(_d,_t) \ + { memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = AVC_AUDIT_DATA_##_t; } + /* * AVC statistics */ @@ -57,9 +98,7 @@ void __init avc_init(void); void avc_audit(u32 ssid, u32 tsid, u16 tclass, u32 requested, - struct av_decision *avd, - int result, - struct common_audit_data *a); + struct av_decision *avd, int result, struct avc_audit_data *auditdata); #define AVC_STRICT 1 /* Ignore permissive mode. */ int avc_has_perm_noaudit(u32 ssid, u32 tsid, @@ -69,7 +108,7 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested, - struct common_audit_data *auditdata); + struct avc_audit_data *auditdata); u32 avc_policy_seqno(void); @@ -88,13 +127,13 @@ int avc_add_callback(int (*callback)(u32 event, u32 ssid, u32 tsid, u32 events, u32 ssid, u32 tsid, u16 tclass, u32 perms); +/* Shows permission in human readable form */ +void avc_dump_av(struct audit_buffer *ab, u16 tclass, u32 av); + /* Exported to selinuxfs */ int avc_get_hash_stats(char *page); extern unsigned int avc_cache_threshold; -/* Attempt to free avc node cache */ -void avc_disable(void); - #ifdef CONFIG_SECURITY_SELINUX_AVC_STATS DECLARE_PER_CPU(struct avc_cache_stats, avc_cache_stats); #endif diff --git a/trunk/security/selinux/include/class_to_string.h b/trunk/security/selinux/include/class_to_string.h index 7ab9299bfb6b..21ec786611d4 100644 --- a/trunk/security/selinux/include/class_to_string.h +++ b/trunk/security/selinux/include/class_to_string.h @@ -77,4 +77,3 @@ S_(NULL) S_(NULL) S_("kernel_service") - S_("tun_socket") diff --git a/trunk/security/selinux/include/flask.h b/trunk/security/selinux/include/flask.h index f248500a1e3c..882f27d66fac 100644 --- a/trunk/security/selinux/include/flask.h +++ b/trunk/security/selinux/include/flask.h @@ -53,7 +53,6 @@ #define SECCLASS_PEER 68 #define SECCLASS_CAPABILITY2 69 #define SECCLASS_KERNEL_SERVICE 74 -#define SECCLASS_TUN_SOCKET 75 /* * Security identifier indices for initial entities diff --git a/trunk/security/selinux/include/netlabel.h b/trunk/security/selinux/include/netlabel.h index 8d7384280a7a..b4b5b9b2f0be 100644 --- a/trunk/security/selinux/include/netlabel.h +++ b/trunk/security/selinux/include/netlabel.h @@ -59,7 +59,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family); int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, struct sk_buff *skb, u16 family, - struct common_audit_data *ad); + struct avc_audit_data *ad); int selinux_netlbl_socket_setsockopt(struct socket *sock, int level, int optname); @@ -129,7 +129,7 @@ static inline int selinux_netlbl_socket_post_create(struct sock *sk, static inline int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, struct sk_buff *skb, u16 family, - struct common_audit_data *ad) + struct avc_audit_data *ad) { return 0; } diff --git a/trunk/security/selinux/include/xfrm.h b/trunk/security/selinux/include/xfrm.h index 13128f9a3e5a..289e24b39e3e 100644 --- a/trunk/security/selinux/include/xfrm.h +++ b/trunk/security/selinux/include/xfrm.h @@ -41,9 +41,9 @@ static inline int selinux_xfrm_enabled(void) } int selinux_xfrm_sock_rcv_skb(u32 sid, struct sk_buff *skb, - struct common_audit_data *ad); + struct avc_audit_data *ad); int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad, u8 proto); + struct avc_audit_data *ad, u8 proto); int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall); static inline void selinux_xfrm_notify_policyload(void) @@ -57,13 +57,13 @@ static inline int selinux_xfrm_enabled(void) } static inline int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad) + struct avc_audit_data *ad) { return 0; } static inline int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad, u8 proto) + struct avc_audit_data *ad, u8 proto) { return 0; } diff --git a/trunk/security/selinux/netlabel.c b/trunk/security/selinux/netlabel.c index e68823741ad5..2e984413c7b2 100644 --- a/trunk/security/selinux/netlabel.c +++ b/trunk/security/selinux/netlabel.c @@ -342,7 +342,7 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family) int selinux_netlbl_sock_rcv_skb(struct sk_security_struct *sksec, struct sk_buff *skb, u16 family, - struct common_audit_data *ad) + struct avc_audit_data *ad) { int rc; u32 nlbl_sid; diff --git a/trunk/security/selinux/ss/services.c b/trunk/security/selinux/ss/services.c index ff17820d35ec..500e6f78e115 100644 --- a/trunk/security/selinux/ss/services.c +++ b/trunk/security/selinux/ss/services.c @@ -22,11 +22,6 @@ * * Added validation of kernel classes and permissions * - * Updated: KaiGai Kohei - * - * Added support for bounds domain and audit messaged on masked permissions - * - * Copyright (C) 2008, 2009 NEC Corporation * Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P. * Copyright (C) 2004-2006 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004, 2006 Tresys Technology, LLC @@ -283,95 +278,6 @@ static int constraint_expr_eval(struct context *scontext, return s[0]; } -/* - * security_dump_masked_av - dumps masked permissions during - * security_compute_av due to RBAC, MLS/Constraint and Type bounds. - */ -static int dump_masked_av_helper(void *k, void *d, void *args) -{ - struct perm_datum *pdatum = d; - char **permission_names = args; - - BUG_ON(pdatum->value < 1 || pdatum->value > 32); - - permission_names[pdatum->value - 1] = (char *)k; - - return 0; -} - -static void security_dump_masked_av(struct context *scontext, - struct context *tcontext, - u16 tclass, - u32 permissions, - const char *reason) -{ - struct common_datum *common_dat; - struct class_datum *tclass_dat; - struct audit_buffer *ab; - char *tclass_name; - char *scontext_name = NULL; - char *tcontext_name = NULL; - char *permission_names[32]; - int index, length; - bool need_comma = false; - - if (!permissions) - return; - - tclass_name = policydb.p_class_val_to_name[tclass - 1]; - tclass_dat = policydb.class_val_to_struct[tclass - 1]; - common_dat = tclass_dat->comdatum; - - /* init permission_names */ - if (common_dat && - hashtab_map(common_dat->permissions.table, - dump_masked_av_helper, permission_names) < 0) - goto out; - - if (hashtab_map(tclass_dat->permissions.table, - dump_masked_av_helper, permission_names) < 0) - goto out; - - /* get scontext/tcontext in text form */ - if (context_struct_to_string(scontext, - &scontext_name, &length) < 0) - goto out; - - if (context_struct_to_string(tcontext, - &tcontext_name, &length) < 0) - goto out; - - /* audit a message */ - ab = audit_log_start(current->audit_context, - GFP_ATOMIC, AUDIT_SELINUX_ERR); - if (!ab) - goto out; - - audit_log_format(ab, "op=security_compute_av reason=%s " - "scontext=%s tcontext=%s tclass=%s perms=", - reason, scontext_name, tcontext_name, tclass_name); - - for (index = 0; index < 32; index++) { - u32 mask = (1 << index); - - if ((mask & permissions) == 0) - continue; - - audit_log_format(ab, "%s%s", - need_comma ? "," : "", - permission_names[index] - ? permission_names[index] : "????"); - need_comma = true; - } - audit_log_end(ab); -out: - /* release scontext/tcontext */ - kfree(tcontext_name); - kfree(scontext_name); - - return; -} - /* * security_boundary_permission - drops violated permissions * on boundary constraint. @@ -441,12 +347,28 @@ static void type_attribute_bounds_av(struct context *scontext, } if (masked) { + struct audit_buffer *ab; + char *stype_name + = policydb.p_type_val_to_name[source->value - 1]; + char *ttype_name + = policydb.p_type_val_to_name[target->value - 1]; + char *tclass_name + = policydb.p_class_val_to_name[tclass - 1]; + /* mask violated permissions */ avd->allowed &= ~masked; - /* audit masked permissions */ - security_dump_masked_av(scontext, tcontext, - tclass, masked, "bounds"); + /* notice to userspace via audit message */ + ab = audit_log_start(current->audit_context, + GFP_ATOMIC, AUDIT_SELINUX_ERR); + if (!ab) + return; + + audit_log_format(ab, "av boundary violation: " + "source=%s target=%s tclass=%s", + stype_name, ttype_name, tclass_name); + avc_dump_av(ab, tclass, masked); + audit_log_end(ab); } } @@ -558,7 +480,7 @@ static int context_struct_compute_av(struct context *scontext, if ((constraint->permissions & (avd->allowed)) && !constraint_expr_eval(scontext, tcontext, NULL, constraint->expr)) { - avd->allowed &= ~(constraint->permissions); + avd->allowed = (avd->allowed) & ~(constraint->permissions); } constraint = constraint->next; } @@ -577,8 +499,8 @@ static int context_struct_compute_av(struct context *scontext, break; } if (!ra) - avd->allowed &= ~(PROCESS__TRANSITION | - PROCESS__DYNTRANSITION); + avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | + PROCESS__DYNTRANSITION); } /* @@ -765,26 +687,6 @@ int security_bounded_transition(u32 old_sid, u32 new_sid) } index = type->bounds; } - - if (rc) { - char *old_name = NULL; - char *new_name = NULL; - int length; - - if (!context_struct_to_string(old_context, - &old_name, &length) && - !context_struct_to_string(new_context, - &new_name, &length)) { - audit_log(current->audit_context, - GFP_ATOMIC, AUDIT_SELINUX_ERR, - "op=security_bounded_transition " - "result=denied " - "oldcontext=%s newcontext=%s", - old_name, new_name); - } - kfree(new_name); - kfree(old_name); - } out: read_unlock(&policy_rwlock); diff --git a/trunk/security/selinux/xfrm.c b/trunk/security/selinux/xfrm.c index f3cb9ed731a9..72b18452e1a1 100644 --- a/trunk/security/selinux/xfrm.c +++ b/trunk/security/selinux/xfrm.c @@ -401,7 +401,7 @@ int selinux_xfrm_state_delete(struct xfrm_state *x) * gone thru the IPSec process. */ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad) + struct avc_audit_data *ad) { int i, rc = 0; struct sec_path *sp; @@ -442,7 +442,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb, * checked in the selinux_xfrm_state_pol_flow_match hook above. */ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb, - struct common_audit_data *ad, u8 proto) + struct avc_audit_data *ad, u8 proto) { struct dst_entry *dst; int rc = 0; diff --git a/trunk/security/smack/smack.h b/trunk/security/smack/smack.h index c6e9acae72e4..243bec175be0 100644 --- a/trunk/security/smack/smack.h +++ b/trunk/security/smack/smack.h @@ -275,7 +275,7 @@ static inline void smk_ad_init(struct smk_audit_info *a, const char *func, { memset(a, 0, sizeof(*a)); a->a.type = type; - a->a.smack_audit_data.function = func; + a->a.function = func; } static inline void smk_ad_setfield_u_tsk(struct smk_audit_info *a, diff --git a/trunk/security/smack/smack_access.c b/trunk/security/smack/smack_access.c index 0f9ac8146900..513dc1aa16dd 100644 --- a/trunk/security/smack/smack_access.c +++ b/trunk/security/smack/smack_access.c @@ -240,9 +240,8 @@ static inline void smack_str_from_perm(char *string, int access) static void smack_log_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; - struct smack_audit_data *sad = &ad->smack_audit_data; - audit_log_format(ab, "lsm=SMACK fn=%s action=%s", - ad->smack_audit_data.function, + struct smack_audit_data *sad = &ad->lsm_priv.smack_audit_data; + audit_log_format(ab, "lsm=SMACK fn=%s action=%s", ad->function, sad->result ? "denied" : "granted"); audit_log_format(ab, " subject="); audit_log_untrustedstring(ab, sad->subject); @@ -275,11 +274,11 @@ void smack_log(char *subject_label, char *object_label, int request, if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0) return; - if (a->smack_audit_data.function == NULL) - a->smack_audit_data.function = "unknown"; + if (a->function == NULL) + a->function = "unknown"; /* end preparing the audit data */ - sad = &a->smack_audit_data; + sad = &a->lsm_priv.smack_audit_data; smack_str_from_perm(request_buffer, request); sad->subject = subject_label; sad->object = object_label; diff --git a/trunk/security/smack/smack_lsm.c b/trunk/security/smack/smack_lsm.c index acae7ef4092d..0023182078c7 100644 --- a/trunk/security/smack/smack_lsm.c +++ b/trunk/security/smack/smack_lsm.c @@ -91,7 +91,7 @@ struct inode_smack *new_inode_smack(char *smack) */ /** - * smack_ptrace_access_check - Smack approval on PTRACE_ATTACH + * smack_ptrace_may_access - Smack approval on PTRACE_ATTACH * @ctp: child task pointer * @mode: ptrace attachment mode * @@ -99,13 +99,13 @@ struct inode_smack *new_inode_smack(char *smack) * * Do the capability checks, and require read and write. */ -static int smack_ptrace_access_check(struct task_struct *ctp, unsigned int mode) +static int smack_ptrace_may_access(struct task_struct *ctp, unsigned int mode) { int rc; struct smk_audit_info ad; char *sp, *tsp; - rc = cap_ptrace_access_check(ctp, mode); + rc = cap_ptrace_may_access(ctp, mode); if (rc != 0) return rc; @@ -1079,22 +1079,6 @@ static int smack_file_receive(struct file *file) * Task hooks */ -/** - * smack_cred_alloc_blank - "allocate" blank task-level security credentials - * @new: the new credentials - * @gfp: the atomicity of any memory allocations - * - * Prepare a blank set of credentials for modification. This must allocate all - * the memory the LSM module might require such that cred_transfer() can - * complete without error. - */ -static int smack_cred_alloc_blank(struct cred *cred, gfp_t gfp) -{ - cred->security = NULL; - return 0; -} - - /** * smack_cred_free - "free" task-level security credentials * @cred: the credentials in question @@ -1132,18 +1116,6 @@ static void smack_cred_commit(struct cred *new, const struct cred *old) { } -/** - * smack_cred_transfer - Transfer the old credentials to the new credentials - * @new: the new credentials - * @old: the original credentials - * - * Fill in a set of blank credentials from another set of credentials. - */ -static void smack_cred_transfer(struct cred *new, const struct cred *old) -{ - new->security = old->security; -} - /** * smack_kernel_act_as - Set the subjective context in a set of credentials * @new: points to the set of credentials to be modified. @@ -1666,7 +1638,6 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name, if (strcmp(name, XATTR_SMACK_SUFFIX) == 0) { nsp->smk_inode = sp; - nsp->smk_flags |= SMK_INODE_INSTANT; return 0; } /* @@ -2493,7 +2464,7 @@ static int smack_socket_sendmsg(struct socket *sock, struct msghdr *msg, /* * Perfectly reasonable for this to be NULL */ - if (sip == NULL || sip->sin_family != AF_INET) + if (sip == NULL || sip->sin_family != PF_INET) return 0; return smack_netlabel_send(sock->sk, sip); @@ -3058,31 +3029,10 @@ static void smack_release_secctx(char *secdata, u32 seclen) { } -static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen) -{ - return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0); -} - -static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen) -{ - return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0); -} - -static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen) -{ - int len = 0; - len = smack_inode_getsecurity(inode, XATTR_SMACK_SUFFIX, ctx, true); - - if (len < 0) - return len; - *ctxlen = len; - return 0; -} - struct security_operations smack_ops = { .name = "smack", - .ptrace_access_check = smack_ptrace_access_check, + .ptrace_may_access = smack_ptrace_may_access, .ptrace_traceme = smack_ptrace_traceme, .syslog = smack_syslog, @@ -3123,11 +3073,9 @@ struct security_operations smack_ops = { .file_send_sigiotask = smack_file_send_sigiotask, .file_receive = smack_file_receive, - .cred_alloc_blank = smack_cred_alloc_blank, .cred_free = smack_cred_free, .cred_prepare = smack_cred_prepare, .cred_commit = smack_cred_commit, - .cred_transfer = smack_cred_transfer, .kernel_act_as = smack_kernel_act_as, .kernel_create_files_as = smack_kernel_create_files_as, .task_setpgid = smack_task_setpgid, @@ -3207,9 +3155,6 @@ struct security_operations smack_ops = { .secid_to_secctx = smack_secid_to_secctx, .secctx_to_secid = smack_secctx_to_secid, .release_secctx = smack_release_secctx, - .inode_notifysecctx = smack_inode_notifysecctx, - .inode_setsecctx = smack_inode_setsecctx, - .inode_getsecctx = smack_inode_getsecctx, }; diff --git a/trunk/security/tomoyo/common.c b/trunk/security/tomoyo/common.c index 3c8bd8ee0b95..fdd1f4b8c448 100644 --- a/trunk/security/tomoyo/common.c +++ b/trunk/security/tomoyo/common.c @@ -1284,36 +1284,6 @@ static bool tomoyo_is_select_one(struct tomoyo_io_buffer *head, return true; } -/** - * tomoyo_delete_domain - Delete a domain. - * - * @domainname: The name of domain. - * - * Returns 0. - */ -static int tomoyo_delete_domain(char *domainname) -{ - struct tomoyo_domain_info *domain; - struct tomoyo_path_info name; - - name.name = domainname; - tomoyo_fill_path_info(&name); - down_write(&tomoyo_domain_list_lock); - /* Is there an active domain? */ - list_for_each_entry(domain, &tomoyo_domain_list, list) { - /* Never delete tomoyo_kernel_domain */ - if (domain == &tomoyo_kernel_domain) - continue; - if (domain->is_deleted || - tomoyo_pathcmp(domain->domainname, &name)) - continue; - domain->is_deleted = true; - break; - } - up_write(&tomoyo_domain_list_lock); - return 0; -} - /** * tomoyo_write_domain_policy - Write domain policy. * diff --git a/trunk/security/tomoyo/common.h b/trunk/security/tomoyo/common.h index 31df541911f7..6d6ba09af457 100644 --- a/trunk/security/tomoyo/common.h +++ b/trunk/security/tomoyo/common.h @@ -339,6 +339,8 @@ const char *tomoyo_get_last_name(const struct tomoyo_domain_info *domain); const char *tomoyo_get_msg(const bool is_enforce); /* Convert single path operation to operation name. */ const char *tomoyo_sp2keyword(const u8 operation); +/* Delete a domain. */ +int tomoyo_delete_domain(char *data); /* Create "alias" entry in exception policy. */ int tomoyo_write_alias_policy(char *data, const bool is_delete); /* diff --git a/trunk/security/tomoyo/domain.c b/trunk/security/tomoyo/domain.c index fcf52accce2b..1d8b16960576 100644 --- a/trunk/security/tomoyo/domain.c +++ b/trunk/security/tomoyo/domain.c @@ -717,6 +717,38 @@ int tomoyo_write_alias_policy(char *data, const bool is_delete) return tomoyo_update_alias_entry(data, cp, is_delete); } +/* Domain create/delete handler. */ + +/** + * tomoyo_delete_domain - Delete a domain. + * + * @domainname: The name of domain. + * + * Returns 0. + */ +int tomoyo_delete_domain(char *domainname) +{ + struct tomoyo_domain_info *domain; + struct tomoyo_path_info name; + + name.name = domainname; + tomoyo_fill_path_info(&name); + down_write(&tomoyo_domain_list_lock); + /* Is there an active domain? */ + list_for_each_entry(domain, &tomoyo_domain_list, list) { + /* Never delete tomoyo_kernel_domain */ + if (domain == &tomoyo_kernel_domain) + continue; + if (domain->is_deleted || + tomoyo_pathcmp(domain->domainname, &name)) + continue; + domain->is_deleted = true; + break; + } + up_write(&tomoyo_domain_list_lock); + return 0; +} + /** * tomoyo_find_or_assign_new_domain - Create a domain. * @@ -786,11 +818,13 @@ struct tomoyo_domain_info *tomoyo_find_or_assign_new_domain(const char * /** * tomoyo_find_next_domain - Find a domain. * - * @bprm: Pointer to "struct linux_binprm". + * @bprm: Pointer to "struct linux_binprm". + * @next_domain: Pointer to pointer to "struct tomoyo_domain_info". * * Returns 0 on success, negative value otherwise. */ -int tomoyo_find_next_domain(struct linux_binprm *bprm) +int tomoyo_find_next_domain(struct linux_binprm *bprm, + struct tomoyo_domain_info **next_domain) { /* * This function assumes that the size of buffer returned by @@ -912,11 +946,9 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) tomoyo_set_domain_flag(old_domain, false, TOMOYO_DOMAIN_FLAGS_TRANSITION_FAILED); out: - if (!domain) - domain = old_domain; - bprm->cred->security = domain; tomoyo_free(real_program_name); tomoyo_free(symlink_program_name); + *next_domain = domain ? domain : old_domain; tomoyo_free(tmp); return retval; } diff --git a/trunk/security/tomoyo/tomoyo.c b/trunk/security/tomoyo/tomoyo.c index 9548a0984cc4..3194d09fe0f4 100644 --- a/trunk/security/tomoyo/tomoyo.c +++ b/trunk/security/tomoyo/tomoyo.c @@ -14,12 +14,6 @@ #include "tomoyo.h" #include "realpath.h" -static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp) -{ - new->security = NULL; - return 0; -} - static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) { @@ -31,15 +25,6 @@ static int tomoyo_cred_prepare(struct cred *new, const struct cred *old, return 0; } -static void tomoyo_cred_transfer(struct cred *new, const struct cred *old) -{ - /* - * Since "struct tomoyo_domain_info *" is a sharable pointer, - * we don't need to duplicate. - */ - new->security = old->security; -} - static int tomoyo_bprm_set_creds(struct linux_binprm *bprm) { int rc; @@ -76,8 +61,14 @@ static int tomoyo_bprm_check_security(struct linux_binprm *bprm) * Execute permission is checked against pathname passed to do_execve() * using current domain. */ - if (!domain) - return tomoyo_find_next_domain(bprm); + if (!domain) { + struct tomoyo_domain_info *next_domain = NULL; + int retval = tomoyo_find_next_domain(bprm, &next_domain); + + if (!retval) + bprm->cred->security = next_domain; + return retval; + } /* * Read permission is checked against interpreters using next domain. * '1' is the result of open_to_namei_flags(O_RDONLY). @@ -277,9 +268,7 @@ static int tomoyo_dentry_open(struct file *f, const struct cred *cred) */ static struct security_operations tomoyo_security_ops = { .name = "tomoyo", - .cred_alloc_blank = tomoyo_cred_alloc_blank, .cred_prepare = tomoyo_cred_prepare, - .cred_transfer = tomoyo_cred_transfer, .bprm_set_creds = tomoyo_bprm_set_creds, .bprm_check_security = tomoyo_bprm_check_security, #ifdef CONFIG_SYSCTL diff --git a/trunk/security/tomoyo/tomoyo.h b/trunk/security/tomoyo/tomoyo.h index cd6ba0bf7069..0fd588a629cf 100644 --- a/trunk/security/tomoyo/tomoyo.h +++ b/trunk/security/tomoyo/tomoyo.h @@ -31,7 +31,8 @@ int tomoyo_check_2path_perm(struct tomoyo_domain_info *domain, struct path *path2); int tomoyo_check_rewrite_permission(struct tomoyo_domain_info *domain, struct file *filp); -int tomoyo_find_next_domain(struct linux_binprm *bprm); +int tomoyo_find_next_domain(struct linux_binprm *bprm, + struct tomoyo_domain_info **next_domain); /* Index numbers for Access Controls. */