arm: kernel: Ignore KASan errors from unwind_frame
When a process A unwind the stack frame of process B, the stack of B can be modified and updated in other CPU concurrently. So KASan could examine stack address with out of date shadow mask value. To avoid this incorrect KASan report, disable KASan during unwinding a frame of a different task. Following is the Kasan error log for the reference. ================================================================== BUG: KASan: out of bounds access in unwind_frame+0x9c/0xf8 at addr ffffffc0462b76f0 Read of size 8 by task Signal Catcher/1282 page:ffffffbac7bdb260 count:0 mapcount:0 mapping: (null) index:0x0 flags: 0x0() page dumped because: kasan: bad access detected Call trace: [<ffffffc00008c010>] dump_backtrace+0x0/0x250 [<ffffffc00008c270>] show_stack+0x10/0x1c [<ffffffc001b6e628>] dump_stack+0x74/0xfc [<ffffffc0002dd7c4>] kasan_report_error+0x2b0/0x408 [<ffffffc0002dd9f8>] kasan_report+0x34/0x40 [<ffffffc0002dda78>] __asan_report_load8_noabort+0x14/0x20 [<ffffffc00008b984>] unwind_frame+0x98/0xf8 [<ffffffc00008ba14>] walk_stackframe+0x30/0x48 [<ffffffc00008bba4>] save_stack_trace_tsk+0x178/0x254 [<ffffffc0003a5bc4>] proc_pid_stack+0xf0/0x198 [<ffffffc0003a11b0>] proc_single_show+0xe8/0x130 [<ffffffc000330e0c>] seq_read+0x524/0xaf0 [<ffffffc0002e9c74>] vfs_read+0x120/0x270 [<ffffffc0002eb208>] SyS_read+0xec/0x198 Memory state around the buggy address: ffffffc0462b7580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffffffc0462b7600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >ffffffc0462b7680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^ ffffffc0462b7700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffffffc0462b7780: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 00 00 ================================================================== Change-Id: I0e35e6721417fa7a5bffb41be67443cd906e256a Signed-off-by: Se Wang (Patrick) Oh <sewango@codeaurora.org>
This commit is contained in:
parent
a1efe43c52
commit
dbd6607ac7
2 changed files with 10 additions and 0 deletions
|
@ -1,4 +1,5 @@
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
|
#include <linux/kasan.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/stacktrace.h>
|
#include <linux/stacktrace.h>
|
||||||
|
|
||||||
|
@ -35,11 +36,15 @@ int notrace unwind_frame(struct stackframe *frame)
|
||||||
if (fp < low + 12 || fp > high - 4)
|
if (fp < low + 12 || fp > high - 4)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
kasan_disable_current();
|
||||||
|
|
||||||
/* restore the registers from the stack frame */
|
/* restore the registers from the stack frame */
|
||||||
frame->fp = *(unsigned long *)(fp - 12);
|
frame->fp = *(unsigned long *)(fp - 12);
|
||||||
frame->sp = *(unsigned long *)(fp - 8);
|
frame->sp = *(unsigned long *)(fp - 8);
|
||||||
frame->pc = *(unsigned long *)(fp - 4);
|
frame->pc = *(unsigned long *)(fp - 4);
|
||||||
|
|
||||||
|
kasan_enable_current();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <linux/kasan.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/export.h>
|
#include <linux/export.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
@ -46,10 +47,14 @@ int notrace unwind_frame(struct stackframe *frame)
|
||||||
if (fp < low || fp > high - 0x18 || fp & 0xf)
|
if (fp < low || fp > high - 0x18 || fp & 0xf)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
kasan_disable_current();
|
||||||
|
|
||||||
frame->sp = fp + 0x10;
|
frame->sp = fp + 0x10;
|
||||||
frame->fp = *(unsigned long *)(fp);
|
frame->fp = *(unsigned long *)(fp);
|
||||||
frame->pc = *(unsigned long *)(fp + 8);
|
frame->pc = *(unsigned long *)(fp + 8);
|
||||||
|
|
||||||
|
kasan_enable_current();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue