diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 15:22:13 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-12-12 15:22:13 -0500 |
commit | 9977d9b379cb77e0f67bd6f4563618106e58e11d (patch) | |
tree | 0191accfddf578edb52c69c933d64521e3dce297 /kernel/auditsc.c | |
parent | cf4af01221579a4e895f43dbfc47598fbfc5a731 (diff) | |
parent | 541880d9a2c7871f6370071d55aa6662d329c51e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull big execve/kernel_thread/fork unification series from Al Viro:
"All architectures are converted to new model. Quite a bit of that
stuff is actually shared with architecture trees; in such cases it's
literally shared branch pulled by both, not a cherry-pick.
A lot of ugliness and black magic is gone (-3KLoC total in this one):
- kernel_thread()/kernel_execve()/sys_execve() redesign.
We don't do syscalls from kernel anymore for either kernel_thread()
or kernel_execve():
kernel_thread() is essentially clone(2) with callback run before we
return to userland, the callbacks either never return or do
successful do_execve() before returning.
kernel_execve() is a wrapper for do_execve() - it doesn't need to
do transition to user mode anymore.
As a result kernel_thread() and kernel_execve() are
arch-independent now - they live in kernel/fork.c and fs/exec.c
resp. sys_execve() is also in fs/exec.c and it's completely
architecture-independent.
- daemonize() is gone, along with its parts in fs/*.c
- struct pt_regs * is no longer passed to do_fork/copy_process/
copy_thread/do_execve/search_binary_handler/->load_binary/do_coredump.
- sys_fork()/sys_vfork()/sys_clone() unified; some architectures
still need wrappers (ones with callee-saved registers not saved in
pt_regs on syscall entry), but the main part of those suckers is in
kernel/fork.c now."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (113 commits)
do_coredump(): get rid of pt_regs argument
print_fatal_signal(): get rid of pt_regs argument
ptrace_signal(): get rid of unused arguments
get rid of ptrace_signal_deliver() arguments
new helper: signal_pt_regs()
unify default ptrace_signal_deliver
flagday: kill pt_regs argument of do_fork()
death to idle_regs()
don't pass regs to copy_process()
flagday: don't pass regs to copy_thread()
bfin: switch to generic vfork, get rid of pointless wrappers
xtensa: switch to generic clone()
openrisc: switch to use of generic fork and clone
unicore32: switch to generic clone(2)
score: switch to generic fork/vfork/clone
c6x: sanitize copy_thread(), get rid of clone(2) wrapper, switch to generic clone()
take sys_fork/sys_vfork/sys_clone prototypes to linux/syscalls.h
mn10300: switch to generic fork/vfork/clone
h8300: switch to generic fork/vfork/clone
tile: switch to generic clone()
...
Conflicts:
arch/microblaze/include/asm/Kbuild
Diffstat (limited to 'kernel/auditsc.c')
-rw-r--r-- | kernel/auditsc.c | 102 |
1 files changed, 21 insertions, 81 deletions
diff --git a/kernel/auditsc.c b/kernel/auditsc.c index fc7376bf86ea..e37e6a12c5e3 100644 --- a/kernel/auditsc.c +++ b/kernel/auditsc.c | |||
@@ -200,7 +200,6 @@ struct audit_context { | |||
200 | struct list_head names_list; /* anchor for struct audit_names->list */ | 200 | struct list_head names_list; /* anchor for struct audit_names->list */ |
201 | char * filterkey; /* key for rule that triggered record */ | 201 | char * filterkey; /* key for rule that triggered record */ |
202 | struct path pwd; | 202 | struct path pwd; |
203 | struct audit_context *previous; /* For nested syscalls */ | ||
204 | struct audit_aux_data *aux; | 203 | struct audit_aux_data *aux; |
205 | struct audit_aux_data *aux_pids; | 204 | struct audit_aux_data *aux_pids; |
206 | struct sockaddr_storage *sockaddr; | 205 | struct sockaddr_storage *sockaddr; |
@@ -1091,29 +1090,13 @@ int audit_alloc(struct task_struct *tsk) | |||
1091 | 1090 | ||
1092 | static inline void audit_free_context(struct audit_context *context) | 1091 | static inline void audit_free_context(struct audit_context *context) |
1093 | { | 1092 | { |
1094 | struct audit_context *previous; | 1093 | audit_free_names(context); |
1095 | int count = 0; | 1094 | unroll_tree_refs(context, NULL, 0); |
1096 | 1095 | free_tree_refs(context); | |
1097 | do { | 1096 | audit_free_aux(context); |
1098 | previous = context->previous; | 1097 | kfree(context->filterkey); |
1099 | if (previous || (count && count < 10)) { | 1098 | kfree(context->sockaddr); |
1100 | ++count; | 1099 | kfree(context); |
1101 | printk(KERN_ERR "audit(:%d): major=%d name_count=%d:" | ||
1102 | " freeing multiple contexts (%d)\n", | ||
1103 | context->serial, context->major, | ||
1104 | context->name_count, count); | ||
1105 | } | ||
1106 | audit_free_names(context); | ||
1107 | unroll_tree_refs(context, NULL, 0); | ||
1108 | free_tree_refs(context); | ||
1109 | audit_free_aux(context); | ||
1110 | kfree(context->filterkey); | ||
1111 | kfree(context->sockaddr); | ||
1112 | kfree(context); | ||
1113 | context = previous; | ||
1114 | } while (context); | ||
1115 | if (count >= 10) | ||
1116 | printk(KERN_ERR "audit: freed %d contexts\n", count); | ||
1117 | } | 1100 | } |
1118 | 1101 | ||
1119 | void audit_log_task_context(struct audit_buffer *ab) | 1102 | void audit_log_task_context(struct audit_buffer *ab) |
@@ -1783,42 +1766,6 @@ void __audit_syscall_entry(int arch, int major, | |||
1783 | if (!context) | 1766 | if (!context) |
1784 | return; | 1767 | return; |
1785 | 1768 | ||
1786 | /* | ||
1787 | * This happens only on certain architectures that make system | ||
1788 | * calls in kernel_thread via the entry.S interface, instead of | ||
1789 | * with direct calls. (If you are porting to a new | ||
1790 | * architecture, hitting this condition can indicate that you | ||
1791 | * got the _exit/_leave calls backward in entry.S.) | ||
1792 | * | ||
1793 | * i386 no | ||
1794 | * x86_64 no | ||
1795 | * ppc64 yes (see arch/powerpc/platforms/iseries/misc.S) | ||
1796 | * | ||
1797 | * This also happens with vm86 emulation in a non-nested manner | ||
1798 | * (entries without exits), so this case must be caught. | ||
1799 | */ | ||
1800 | if (context->in_syscall) { | ||
1801 | struct audit_context *newctx; | ||
1802 | |||
1803 | #if AUDIT_DEBUG | ||
1804 | printk(KERN_ERR | ||
1805 | "audit(:%d) pid=%d in syscall=%d;" | ||
1806 | " entering syscall=%d\n", | ||
1807 | context->serial, tsk->pid, context->major, major); | ||
1808 | #endif | ||
1809 | newctx = audit_alloc_context(context->state); | ||
1810 | if (newctx) { | ||
1811 | newctx->previous = context; | ||
1812 | context = newctx; | ||
1813 | tsk->audit_context = newctx; | ||
1814 | } else { | ||
1815 | /* If we can't alloc a new context, the best we | ||
1816 | * can do is to leak memory (any pending putname | ||
1817 | * will be lost). The only other alternative is | ||
1818 | * to abandon auditing. */ | ||
1819 | audit_zero_context(context, context->state); | ||
1820 | } | ||
1821 | } | ||
1822 | BUG_ON(context->in_syscall || context->name_count); | 1769 | BUG_ON(context->in_syscall || context->name_count); |
1823 | 1770 | ||
1824 | if (!audit_enabled) | 1771 | if (!audit_enabled) |
@@ -1881,28 +1828,21 @@ void __audit_syscall_exit(int success, long return_code) | |||
1881 | if (!list_empty(&context->killed_trees)) | 1828 | if (!list_empty(&context->killed_trees)) |
1882 | audit_kill_trees(&context->killed_trees); | 1829 | audit_kill_trees(&context->killed_trees); |
1883 | 1830 | ||
1884 | if (context->previous) { | 1831 | audit_free_names(context); |
1885 | struct audit_context *new_context = context->previous; | 1832 | unroll_tree_refs(context, NULL, 0); |
1886 | context->previous = NULL; | 1833 | audit_free_aux(context); |
1887 | audit_free_context(context); | 1834 | context->aux = NULL; |
1888 | tsk->audit_context = new_context; | 1835 | context->aux_pids = NULL; |
1889 | } else { | 1836 | context->target_pid = 0; |
1890 | audit_free_names(context); | 1837 | context->target_sid = 0; |
1891 | unroll_tree_refs(context, NULL, 0); | 1838 | context->sockaddr_len = 0; |
1892 | audit_free_aux(context); | 1839 | context->type = 0; |
1893 | context->aux = NULL; | 1840 | context->fds[0] = -1; |
1894 | context->aux_pids = NULL; | 1841 | if (context->state != AUDIT_RECORD_CONTEXT) { |
1895 | context->target_pid = 0; | 1842 | kfree(context->filterkey); |
1896 | context->target_sid = 0; | 1843 | context->filterkey = NULL; |
1897 | context->sockaddr_len = 0; | ||
1898 | context->type = 0; | ||
1899 | context->fds[0] = -1; | ||
1900 | if (context->state != AUDIT_RECORD_CONTEXT) { | ||
1901 | kfree(context->filterkey); | ||
1902 | context->filterkey = NULL; | ||
1903 | } | ||
1904 | tsk->audit_context = context; | ||
1905 | } | 1844 | } |
1845 | tsk->audit_context = context; | ||
1906 | } | 1846 | } |
1907 | 1847 | ||
1908 | static inline void handle_one(const struct inode *inode) | 1848 | static inline void handle_one(const struct inode *inode) |