From: Greg Kroah-Hartman Date: Thu, 6 Feb 2014 23:08:30 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.4.80~89 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f53b1952c2d67fdda5eaa8ce1fa3524ee4317063;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: audit-correct-a-type-mismatch-in-audit_syscall_exit.patch ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch intel-iommu-fix-off-by-one-in-pagetable-freeing.patch selinux-fix-memory-leak-upon-loading-policy.patch --- diff --git a/queue-3.4/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch b/queue-3.4/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch new file mode 100644 index 00000000000..2332de838f4 --- /dev/null +++ b/queue-3.4/audit-correct-a-type-mismatch-in-audit_syscall_exit.patch @@ -0,0 +1,39 @@ +From 06bdadd7634551cfe8ce071fe44d0311b3033d9e Mon Sep 17 00:00:00 2001 +From: AKASHI Takahiro +Date: Mon, 13 Jan 2014 13:33:09 -0800 +Subject: audit: correct a type mismatch in audit_syscall_exit() + +From: AKASHI Takahiro + +commit 06bdadd7634551cfe8ce071fe44d0311b3033d9e upstream. + +audit_syscall_exit() saves a result of regs_return_value() in intermediate +"int" variable and passes it to __audit_syscall_exit(), which expects its +second argument as a "long" value. This will result in truncating the +value returned by a system call and making a wrong audit record. + +I don't know why gcc compiler doesn't complain about this, but anyway it +causes a problem at runtime on arm64 (and probably most 64-bit archs). + +Signed-off-by: AKASHI Takahiro +Cc: Al Viro +Cc: Eric Paris +Signed-off-by: Andrew Morton +Signed-off-by: Eric Paris +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/audit.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/include/linux/audit.h ++++ b/include/linux/audit.h +@@ -487,7 +487,7 @@ static inline void audit_syscall_exit(vo + { + if (unlikely(current->audit_context)) { + int success = is_syscall_success(pt_regs); +- int return_code = regs_return_value(pt_regs); ++ long return_code = regs_return_value(pt_regs); + + __audit_syscall_exit(success, return_code); + } diff --git a/queue-3.4/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch b/queue-3.4/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch new file mode 100644 index 00000000000..5cfd1709e34 --- /dev/null +++ b/queue-3.4/ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch @@ -0,0 +1,184 @@ +From 23a8e8441a0a74dd612edf81dc89d1600bc0a3d1 Mon Sep 17 00:00:00 2001 +From: "Steven Rostedt (Red Hat)" +Date: Mon, 13 Jan 2014 10:30:23 -0500 +Subject: ftrace: Have function graph only trace based on global_ops filters + +From: "Steven Rostedt (Red Hat)" + +commit 23a8e8441a0a74dd612edf81dc89d1600bc0a3d1 upstream. + +Doing some different tests, I discovered that function graph tracing, when +filtered via the set_ftrace_filter and set_ftrace_notrace files, does +not always keep with them if another function ftrace_ops is registered +to trace functions. + +The reason is that function graph just happens to trace all functions +that the function tracer enables. When there was only one user of +function tracing, the function graph tracer did not need to worry about +being called by functions that it did not want to trace. But now that there +are other users, this becomes a problem. + +For example, one just needs to do the following: + + # cd /sys/kernel/debug/tracing + # echo schedule > set_ftrace_filter + # echo function_graph > current_tracer + # cat trace +[..] + 0) | schedule() { + ------------------------------------------ + 0) -0 => rcu_pre-7 + ------------------------------------------ + + 0) ! 2980.314 us | } + 0) | schedule() { + ------------------------------------------ + 0) rcu_pre-7 => -0 + ------------------------------------------ + + 0) + 20.701 us | } + + # echo 1 > /proc/sys/kernel/stack_tracer_enabled + # cat trace +[..] + 1) + 20.825 us | } + 1) + 21.651 us | } + 1) + 30.924 us | } /* SyS_ioctl */ + 1) | do_page_fault() { + 1) | __do_page_fault() { + 1) 0.274 us | down_read_trylock(); + 1) 0.098 us | find_vma(); + 1) | handle_mm_fault() { + 1) | _raw_spin_lock() { + 1) 0.102 us | preempt_count_add(); + 1) 0.097 us | do_raw_spin_lock(); + 1) 2.173 us | } + 1) | do_wp_page() { + 1) 0.079 us | vm_normal_page(); + 1) 0.086 us | reuse_swap_page(); + 1) 0.076 us | page_move_anon_rmap(); + 1) | unlock_page() { + 1) 0.082 us | page_waitqueue(); + 1) 0.086 us | __wake_up_bit(); + 1) 1.801 us | } + 1) 0.075 us | ptep_set_access_flags(); + 1) | _raw_spin_unlock() { + 1) 0.098 us | do_raw_spin_unlock(); + 1) 0.105 us | preempt_count_sub(); + 1) 1.884 us | } + 1) 9.149 us | } + 1) + 13.083 us | } + 1) 0.146 us | up_read(); + +When the stack tracer was enabled, it enabled all functions to be traced, which +now the function graph tracer also traces. This is a side effect that should +not occur. + +To fix this a test is added when the function tracing is changed, as well as when +the graph tracer is enabled, to see if anything other than the ftrace global_ops +function tracer is enabled. If so, then the graph tracer calls a test trampoline +that will look at the function that is being traced and compare it with the +filters defined by the global_ops. + +As an optimization, if there's no other function tracers registered, or if +the only registered function tracers also use the global ops, the function +graph infrastructure will call the registered function graph callback directly +and not go through the test trampoline. + +Fixes: d2d45c7a03a2 "tracing: Have stack_tracer use a separate list of functions" +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ftrace.c | 45 ++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 44 insertions(+), 1 deletion(-) + +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -222,6 +222,12 @@ static void update_global_ops(void) + global_ops.func = func; + } + ++#ifdef CONFIG_FUNCTION_GRAPH_TRACER ++static void update_function_graph_func(void); ++#else ++static inline void update_function_graph_func(void) { } ++#endif ++ + static void update_ftrace_function(void) + { + ftrace_func_t func; +@@ -270,6 +276,8 @@ static int remove_ftrace_ops(struct ftra + { + struct ftrace_ops **p; + ++ update_function_graph_func(); ++ + /* + * If we are removing the last function, then simply point + * to the ftrace_stub. +@@ -4404,6 +4412,7 @@ int ftrace_graph_entry_stub(struct ftrac + trace_func_graph_ret_t ftrace_graph_return = + (trace_func_graph_ret_t)ftrace_stub; + trace_func_graph_ent_t ftrace_graph_entry = ftrace_graph_entry_stub; ++static trace_func_graph_ent_t __ftrace_graph_entry = ftrace_graph_entry_stub; + + /* Try to assign a return stack array on FTRACE_RETSTACK_ALLOC_SIZE tasks. */ + static int alloc_retstack_tasklist(struct ftrace_ret_stack **ret_stack_list) +@@ -4544,6 +4553,30 @@ static struct ftrace_ops fgraph_ops __re + .flags = FTRACE_OPS_FL_GLOBAL, + }; + ++static int ftrace_graph_entry_test(struct ftrace_graph_ent *trace) ++{ ++ if (!ftrace_ops_test(&global_ops, trace->func, NULL)) ++ return 0; ++ return __ftrace_graph_entry(trace); ++} ++ ++/* ++ * The function graph tracer should only trace the functions defined ++ * by set_ftrace_filter and set_ftrace_notrace. If another function ++ * tracer ops is registered, the graph tracer requires testing the ++ * function against the global ops, and not just trace any function ++ * that any ftrace_ops registered. ++ */ ++static void update_function_graph_func(void) ++{ ++ if (ftrace_ops_list == &ftrace_list_end || ++ (ftrace_ops_list == &global_ops && ++ global_ops.next == &ftrace_list_end)) ++ ftrace_graph_entry = __ftrace_graph_entry; ++ else ++ ftrace_graph_entry = ftrace_graph_entry_test; ++} ++ + int register_ftrace_graph(trace_func_graph_ret_t retfunc, + trace_func_graph_ent_t entryfunc) + { +@@ -4568,7 +4601,16 @@ int register_ftrace_graph(trace_func_gra + } + + ftrace_graph_return = retfunc; +- ftrace_graph_entry = entryfunc; ++ ++ /* ++ * Update the indirect function to the entryfunc, and the ++ * function that gets called to the entry_test first. Then ++ * call the update fgraph entry function to determine if ++ * the entryfunc should be called directly or not. ++ */ ++ __ftrace_graph_entry = entryfunc; ++ ftrace_graph_entry = ftrace_graph_entry_test; ++ update_function_graph_func(); + + ret = ftrace_startup(&fgraph_ops, FTRACE_START_FUNC_RET); + +@@ -4587,6 +4629,7 @@ void unregister_ftrace_graph(void) + ftrace_graph_active--; + ftrace_graph_return = (trace_func_graph_ret_t)ftrace_stub; + ftrace_graph_entry = ftrace_graph_entry_stub; ++ __ftrace_graph_entry = ftrace_graph_entry_stub; + ftrace_shutdown(&fgraph_ops, FTRACE_STOP_FUNC_RET); + unregister_pm_notifier(&ftrace_suspend_notifier); + unregister_trace_sched_switch(ftrace_graph_probe_sched_switch, NULL); diff --git a/queue-3.4/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch b/queue-3.4/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch new file mode 100644 index 00000000000..bdb01bd27ec --- /dev/null +++ b/queue-3.4/intel-iommu-fix-off-by-one-in-pagetable-freeing.patch @@ -0,0 +1,61 @@ +From 08336fd218e087cc4fcc458e6b6dcafe8702b098 Mon Sep 17 00:00:00 2001 +From: Alex Williamson +Date: Tue, 21 Jan 2014 15:48:18 -0800 +Subject: intel-iommu: fix off-by-one in pagetable freeing + +From: Alex Williamson + +commit 08336fd218e087cc4fcc458e6b6dcafe8702b098 upstream. + +dma_pte_free_level() has an off-by-one error when checking whether a pte +is completely covered by a range. Take for example the case of +attempting to free pfn 0x0 - 0x1ff, ie. 512 entries covering the first +2M superpage. + +The level_size() is 0x200 and we test: + + static void dma_pte_free_level(... + ... + + if (!(0 > 0 || 0x1ff < 0 + 0x200)) { + ... + } + +Clearly the 2nd test is true, which means we fail to take the branch to +clear and free the pagetable entry. As a result, we're leaking +pagetables and failing to install new pages over the range. + +This was found with a PCI device assigned to a QEMU guest using vfio-pci +without a VGA device present. The first 1M of guest address space is +mapped with various combinations of 4K pages, but eventually the range +is entirely freed and replaced with a 2M contiguous mapping. +intel-iommu errors out with something like: + + ERROR: DMA PTE for vPFN 0x0 already set (to 5c2b8003 not 849c00083) + +In this case 5c2b8003 is the pointer to the previous leaf page that was +neither freed nor cleared and 849c00083 is the superpage entry that +we're trying to replace it with. + +Signed-off-by: Alex Williamson +Cc: David Woodhouse +Cc: Joerg Roedel +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel-iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -913,7 +913,7 @@ static void dma_pte_free_level(struct dm + + /* If range covers entire pagetable, free it */ + if (!(start_pfn > level_pfn || +- last_pfn < level_pfn + level_size(level))) { ++ last_pfn < level_pfn + level_size(level) - 1)) { + dma_clear_pte(pte); + domain_flush_cache(domain, pte, sizeof(*pte)); + free_pgtable_page(level_pte); diff --git a/queue-3.4/selinux-fix-memory-leak-upon-loading-policy.patch b/queue-3.4/selinux-fix-memory-leak-upon-loading-policy.patch new file mode 100644 index 00000000000..d840398aa94 --- /dev/null +++ b/queue-3.4/selinux-fix-memory-leak-upon-loading-policy.patch @@ -0,0 +1,79 @@ +From 8ed814602876bec9bad2649ca17f34b499357a1c Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 6 Jan 2014 21:28:15 +0900 +Subject: SELinux: Fix memory leak upon loading policy + +From: Tetsuo Handa + +commit 8ed814602876bec9bad2649ca17f34b499357a1c upstream. + +Hello. + +I got below leak with linux-3.10.0-54.0.1.el7.x86_64 . + +[ 681.903890] kmemleak: 5538 new suspected memory leaks (see /sys/kernel/debug/kmemleak) + +Below is a patch, but I don't know whether we need special handing for undoing +ebitmap_set_bit() call. +---------- +>>From fe97527a90fe95e2239dfbaa7558f0ed559c0992 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Mon, 6 Jan 2014 16:30:21 +0900 +Subject: SELinux: Fix memory leak upon loading policy + +Commit 2463c26d "SELinux: put name based create rules in a hashtable" did not +check return value from hashtab_insert() in filename_trans_read(). It leaks +memory if hashtab_insert() returns error. + + unreferenced object 0xffff88005c9160d0 (size 8): + comm "systemd", pid 1, jiffies 4294688674 (age 235.265s) + hex dump (first 8 bytes): + 57 0b 00 00 6b 6b 6b a5 W...kkk. + backtrace: + [] kmemleak_alloc+0x4e/0xb0 + [] kmem_cache_alloc_trace+0x12e/0x360 + [] policydb_read+0xd1d/0xf70 + [] security_load_policy+0x6c/0x500 + [] sel_write_load+0xac/0x750 + [] vfs_write+0xc0/0x1f0 + [] SyS_write+0x4c/0xa0 + [] system_call_fastpath+0x16/0x1b + [] 0xffffffffffffffff + +However, we should not return EEXIST error to the caller, or the systemd will +show below message and the boot sequence freezes. + + systemd[1]: Failed to load SELinux policy. Freezing. + +Signed-off-by: Tetsuo Handa +Acked-by: Eric Paris +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + security/selinux/ss/policydb.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/security/selinux/ss/policydb.c ++++ b/security/selinux/ss/policydb.c +@@ -1914,7 +1914,19 @@ static int filename_trans_read(struct po + if (rc) + goto out; + +- hashtab_insert(p->filename_trans, ft, otype); ++ rc = hashtab_insert(p->filename_trans, ft, otype); ++ if (rc) { ++ /* ++ * Do not return -EEXIST to the caller, or the system ++ * will not boot. ++ */ ++ if (rc != -EEXIST) ++ goto out; ++ /* But free memory to avoid memory leak. */ ++ kfree(ft); ++ kfree(name); ++ kfree(otype); ++ } + } + hash_eval(p->filename_trans, "filenametr"); + return 0; diff --git a/queue-3.4/series b/queue-3.4/series new file mode 100644 index 00000000000..079f8587be5 --- /dev/null +++ b/queue-3.4/series @@ -0,0 +1,4 @@ +selinux-fix-memory-leak-upon-loading-policy.patch +ftrace-have-function-graph-only-trace-based-on-global_ops-filters.patch +intel-iommu-fix-off-by-one-in-pagetable-freeing.patch +audit-correct-a-type-mismatch-in-audit_syscall_exit.patch