diff --git a/CMakeLists.txt b/CMakeLists.txt index 54717ff..3d49f85 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -68,6 +68,20 @@ if(NOT ANDROID) add_library(j1939 STATIC libj1939.c ) + + install(PROGRAMS + tests/j1939/j1939_ac_100k_dual_can.sh + tests/j1939/j1939_ac_100k_local0.sh + tests/j1939/j1939_ac_1k_local0.sh + tests/j1939/j1939_ac_1m_local0.sh + tests/j1939/j1939_ac_8b_local0.sh + tests/j1939/j1939_multisock_dualack_100k.sh + tests/j1939/j1939_multisock_dualack_1k.sh + tests/j1939/j1939_multisock_timeout_100k.sh + tests/j1939/run_all.sh + DESTINATION ${CMAKE_INSTALL_LIBEXECDIR} + ) + endif() add_library(can STATIC @@ -91,5 +105,4 @@ foreach(name ${PROGRAMS}) install(TARGETS ${name} DESTINATION ${CMAKE_INSTALL_BINDIR}) endforeach() - ADD_CUSTOM_TARGET(uninstall "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/make_uninstall.cmake") diff --git a/GNUmakefile.am b/GNUmakefile.am index 013c8ed..a2b9652 100644 --- a/GNUmakefile.am +++ b/GNUmakefile.am @@ -69,6 +69,17 @@ bin_PROGRAMS = \ slcanpty \ testj1939 +libexec_SCRIPTS = \ + $(srcdir)/tests/j1939/j1939_ac_100k_dual_can.sh \ + $(srcdir)/tests/j1939/j1939_ac_100k_local0.sh \ + $(srcdir)/tests/j1939/j1939_ac_1k_local0.sh \ + $(srcdir)/tests/j1939/j1939_ac_1m_local0.sh \ + $(srcdir)/tests/j1939/j1939_ac_8b_local0.sh \ + $(srcdir)/tests/j1939/j1939_multisock_dualack_100k.sh \ + $(srcdir)/tests/j1939/j1939_multisock_dualack_1k.sh \ + $(srcdir)/tests/j1939/j1939_multisock_timeout_100k.sh \ + $(srcdir)/tests/j1939/run_all.sh + jacd_LDADD = libj1939.la jcat_LDADD = libj1939.la jspy_LDADD = libj1939.la @@ -81,7 +92,17 @@ EXTRA_DIST = \ README.md \ autogen.sh \ can-j1939-kickstart.md \ - can-j1939.md + can-j1939.md \ + tests/j1939/README.md \ + tests/j1939/j1939_ac_100k_dual_can.sh \ + tests/j1939/j1939_ac_100k_local0.sh \ + tests/j1939/j1939_ac_1k_local0.sh \ + tests/j1939/j1939_ac_1m_local0.sh \ + tests/j1939/j1939_ac_8b_local0.sh \ + tests/j1939/j1939_multisock_dualack_100k.sh \ + tests/j1939/j1939_multisock_dualack_1k.sh \ + tests/j1939/j1939_multisock_timeout_100k.sh \ + tests/j1939/run_all.sh MAINTAINERCLEANFILES = \ configure \ diff --git a/tests/j1939/README.md b/tests/j1939/README.md new file mode 100644 index 0000000..653077b --- /dev/null +++ b/tests/j1939/README.md @@ -0,0 +1,11 @@ +### SAE J1939 Tests + +J1939 tests are collection of scripts which was written to reproduce +one or another bug. + +### Requirements + +- jcat and jacd should be installed on the DUT +- DUT should have at least two CAN interfaces named can0 and can1 + connected to each other. Interfaces should be pre-configured + and in the UP state. diff --git a/tests/j1939/j1939_ac_100k_dual_can.sh b/tests/j1939/j1939_ac_100k_dual_can.sh new file mode 100755 index 0000000..b7d564d --- /dev/null +++ b/tests/j1939/j1939_ac_100k_dual_can.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +# This test was written to reproduce following bug, where +# remote address was keeping local priv allocated. Even if no other +# local users was keeping the stack. +# To run this test DUT should have at least two CAN interfaces named can0 +# and can1. +# +# ========================= +# WARNING: held lock freed! +# 5.1.0-00164-g683bec30accc-dirty #410 Not tainted +# ------------------------- +# jacd/10810 is freeing memory e8ced000-e8cedfff, with a lock still held there! +# ca540dc3 (&priv->lock#4){++--}, at: j1939_ac_recv+0x9c/0x1cc +# 6 locks held by jacd/10810: +# #0: 8cae1b05 (sb_writers#6){.+.+}, at: vfs_write+0xb0/0x184 +# #1: 61f77435 (&sb->s_type->i_mutex_key#10){+.+.}, at: generic_file_write_iter+0x50/0x20c +# #2: 724fe4e2 (rcu_read_lock){....}, at: get_mem_cgroup_from_mm+0x34/0x35c +# #3: 724fe4e2 (rcu_read_lock){....}, at: netif_receive_skb_internal+0x78/0x3d4 +# #4: 724fe4e2 (rcu_read_lock){....}, at: can_receive+0x94/0x1d0 +# #5: ca540dc3 (&priv->lock#4){++--}, at: j1939_ac_recv+0x9c/0x1cc +# +# stack backtrace: +# CPU: 0 PID: 10810 Comm: jacd Not tainted 5.1.0-00164-g683bec30accc-dirty #410 +# Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +# Backtrace: +# [] (dump_backtrace) from [] (show_stack+0x20/0x24) +# r7:c15cc630 r6:00000000 r5:60010193 r4:c15cc630 +# [] (show_stack) from [] (dump_stack+0xa0/0xcc) +# [] (dump_stack) from [] (debug_check_no_locks_freed+0x110/0x12c) +# r9:e8ced008 r8:e8cedfff r7:20010193 r6:e91cb180 r5:e8ced000 r4:e91cb7c8 +# [] (debug_check_no_locks_freed) from [] (kfree+0x2e8/0x430) +# r8:60010113 r7:ebc950a0 r6:e8ced000 r5:c0b34cc4 r4:e8001700 +# [] (kfree) from [] (j1939_priv_put+0xa8/0xb0) +# r9:e8ced008 r8:e9254200 r7:e8ced000 r6:e9872840 r5:e86f0000 r4:e8ced000 +# [] (j1939_priv_put) from [] (j1939_ecu_put+0x64/0x68) +# r5:e8ced000 r4:e9254200 +# [] (j1939_ecu_put) from [] (j1939_ac_recv+0x160/0x1cc) +# r5:00000000 r4:11223340 +# [] (j1939_ac_recv) from [] (j1939_can_recv+0x118/0x144) +# r10:e9bbb9fc r9:0000012b r8:e86f08c0 r7:e9872240 r6:e8ced008 r5:e8ced000 +# r4:e9872840 r3:e9bba000 +# [] (j1939_can_recv) from [] (can_rcv_filter+0xfc/0x21c) +# r7:e9872240 r6:98eefffe r5:00000001 r4:e80311b0 +# [] (can_rcv_filter) from [] (can_receive+0x130/0x1d0) +# r9:0000012b r8:00000000 r7:e86f0000 r6:c15b00c0 r5:e8951040 r4:e9872240 +# [] (can_receive) from [] (can_rcv+0x8c/0x94) + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +dmesg -c > /dev/null + +echo "generate random data for the test" +dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 + +echo "start jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223344.jacd 11223344 ${CAN0} & +PID_JACD0=$! +echo $PID_JACD0 +sleep 2 +jcat ${CAN0}:,,0x11223344 -r > /tmp/blup & +PID_JCAT0=$! +echo $PID_JCAT0 + +echo "start jacd and jcat on ${CAN1}" +jacd -r 100,80-120 -c /tmp/11223340.jacd 11223340 ${CAN1} & +sleep 2 +jcat -i /tmp/test_100k ${CAN1}:,,0x11223340 :,,0x11223344 +sleep 3 + +echo "kill all users on ${CAN0}" +# At this step all local user will be removed. All address cache should +# be dropped as well. +kill $PID_JACD0 +kill $PID_JCAT0 +echo "kill all users on ${CAN1}" +# If stack is buggy, kernel will explode somewhere here. +killall jacd + +if dmesg | grep -i backtra; then + echo test failed; + exit 1; +fi diff --git a/tests/j1939/j1939_ac_100k_local0.sh b/tests/j1939/j1939_ac_100k_local0.sh new file mode 100755 index 0000000..440daaf --- /dev/null +++ b/tests/j1939/j1939_ac_100k_local0.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 + +echo "start rx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223344.jacd 11223344 ${CAN0} & +PID_JACD0=$! +echo $PID_JACD0 +sleep 2 +jcat ${CAN0}:,,0x11223344 -r > /tmp/blup & +PID_JCAT0=$! +echo $PID_JCAT0 + +echo "start tx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223340.jacd 11223340 ${CAN0} & +PID_JACD1=$! +sleep 2 +jcat -i /tmp/test_100k ${CAN0}:,,0x11223340 :,,0x11223344 +sleep 2 + +echo "kill all users on ${CAN0}" +kill $PID_JACD0 +kill $PID_JCAT0 +kill $PID_JACD1 + +cmp /tmp/test_100k /tmp/blup + +exit $? diff --git a/tests/j1939/j1939_ac_1k_local0.sh b/tests/j1939/j1939_ac_1k_local0.sh new file mode 100755 index 0000000..ad7ceda --- /dev/null +++ b/tests/j1939/j1939_ac_1k_local0.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +echo "generate random data for the test" +dd if=/dev/urandom of=/tmp/test_1k bs=1K count=1 + +echo "start rx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223344.jacd 11223344 ${CAN0} & +PID_JACD0=$! +echo $PID_JACD0 +sleep 2 +jcat ${CAN0}:,,0x11223344 -r > /tmp/blup & +PID_JCAT0=$! +echo $PID_JCAT0 + +echo "start tx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223340.jacd 11223340 ${CAN0} & +PID_JACD1=$! +sleep 2 +jcat -i /tmp/test_1k ${CAN0}:,,0x11223340 :,,0x11223344 +sleep 2 + +echo "kill all users on ${CAN0}" +kill $PID_JACD0 +kill $PID_JCAT0 +kill $PID_JACD1 + +cmp /tmp/test_1k /tmp/blup +exit $? diff --git a/tests/j1939/j1939_ac_1m_local0.sh b/tests/j1939/j1939_ac_1m_local0.sh new file mode 100755 index 0000000..8b699c2 --- /dev/null +++ b/tests/j1939/j1939_ac_1m_local0.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +echo "generate random data for the test" +dd if=/dev/urandom of=/tmp/test_1m bs=1M count=1 + +echo "start rx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223344.jacd 11223344 ${CAN0} & +PID_JACD0=$! +echo $PID_JACD0 +sleep 2 +jcat ${CAN0}:,,0x11223344 -r > /tmp/blup & +PID_JCAT0=$! +echo $PID_JCAT0 + +echo "start tx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223340.jacd 11223340 ${CAN0} & +PID_JACD1=$! +sleep 2 +jcat -i /tmp/test_1m ${CAN0}:,,0x11223340 :,,0x11223344 +sleep 2 + +echo "kill all users on ${CAN0}" +kill $PID_JACD0 +kill $PID_JCAT0 +kill $PID_JACD1 + +cmp /tmp/test_1m /tmp/blup +exit $? diff --git a/tests/j1939/j1939_ac_8b_local0.sh b/tests/j1939/j1939_ac_8b_local0.sh new file mode 100755 index 0000000..bf2d637 --- /dev/null +++ b/tests/j1939/j1939_ac_8b_local0.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +echo "generate random data for the test" +dd if=/dev/urandom of=/tmp/test_8b bs=8 count=1 + +echo "start rx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223344.jacd 11223344 ${CAN0} & +PID_JACD0=$! +echo $PID_JACD0 +sleep 2 +jcat ${CAN0}:,,0x11223344 -r > /tmp/blup & +PID_JCAT0=$! +echo $PID_JCAT0 + +echo "start tx jacd and jcat on ${CAN0}" +jacd -r 100,80-120 -c /tmp/11223340.jacd 11223340 ${CAN0} & +PID_JACD1=$! +sleep 2 +jcat -i /tmp/test_8b ${CAN0}:,,0x11223340 :,,0x11223344 +sleep 2 + +echo "kill all users on ${CAN0}" +kill $PID_JACD0 +kill $PID_JCAT0 +kill $PID_JACD1 + +cmp /tmp/test_8b /tmp/blup +exit $? diff --git a/tests/j1939/j1939_multisock_dualack_100k.sh b/tests/j1939/j1939_multisock_dualack_100k.sh new file mode 100755 index 0000000..4bdc5bd --- /dev/null +++ b/tests/j1939/j1939_multisock_dualack_100k.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 + +dmesg -c > /dev/null + +jcat ${CAN0}:0x90 -r > /dev/null & +jcat ${CAN1}:0x90 -r > /dev/null & + +for i in `seq 1 100`; +do + echo start round $i + jcat -i /tmp/test_100k -R 100 ${CAN0}:0x80 :0x90,0x12300 & +done + +killall jcat + +if dmesg | grep -i backtra; then + echo test failed; + exit 1; +fi diff --git a/tests/j1939/j1939_multisock_dualack_1k.sh b/tests/j1939/j1939_multisock_dualack_1k.sh new file mode 100755 index 0000000..148eacc --- /dev/null +++ b/tests/j1939/j1939_multisock_dualack_1k.sh @@ -0,0 +1,28 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +dd if=/dev/urandom of=/tmp/test_1k bs=1K count=1 + +dmesg -c > /dev/null + +jcat ${CAN0}:0x90 -r > /dev/null & +jcat ${CAN1}:0x90 -r > /dev/null & + +for i in `seq 1 100`; +do + echo start round $i + jcat -i /tmp/test_1k -R 100 ${CAN0}:0x80 :0x90,0x12300 & +done + +killall jcat + +if dmesg | grep -i backtra; then + echo test failed; + exit 1; +fi diff --git a/tests/j1939/j1939_multisock_timeout_100k.sh b/tests/j1939/j1939_multisock_timeout_100k.sh new file mode 100755 index 0000000..ce562fb --- /dev/null +++ b/tests/j1939/j1939_multisock_timeout_100k.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-only +# Copyright (c) 2019 Oleksij Rempel + +set -e + +CAN0=${1:-can0} +CAN1=${2:-can1} + +dd if=/dev/urandom of=/tmp/test_100k bs=100K count=1 + +dmesg -c > /dev/null + +for i in `seq 1 100`; +do + echo start round $i + jcat -i /tmp/test_100k -R 100 ${CAN0}:0x80 :0x90,0x12300 & +done + +if dmesg | grep -i backtra; then + echo test failed; + exit 1; +fi diff --git a/tests/j1939/run_all.sh b/tests/j1939/run_all.sh new file mode 100755 index 0000000..8f04cb4 --- /dev/null +++ b/tests/j1939/run_all.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +set -e + +for f in j1939*.sh; do + echo "##############################################" + echo "run: $f" + ./$f "${@}" + echo "done: $f" + echo "##############################################" +done