move all our stuff into /lkmc in guest

Motivation: userland is getting several new subdirectories, it would be
too insane to just dump all of that in the guest root filesystem.

To alleviate the cd pain, .profile puts user inside /lkmc by default.
This commit is contained in:
Ciro Santilli 六四事件 法轮功
2019-05-05 00:00:00 +00:00
parent 42f8de774a
commit 146e568db8
63 changed files with 369 additions and 338 deletions

View File

@@ -0,0 +1 @@
https://github.com/cirosantilli/linux-kernel-module-cheat#rootfs_overlay

View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
insmod anonymous_inode.ko
[ "$(/anonymous_inode.out /sys/kernel/debug/lkmc_anonymous_inode 3)" = "$(printf '1\n10\n100')" ]
rmmod anonymous_inode

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
insmod character_device.ko
/mknoddev.sh lkmc_character_device
[ "$(cat /dev/lkmc_character_device)" = 'abcd' ]
rm /dev/lkmc_character_device
rmmod character_device

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
insmod character_device_create.ko
dev='/dev/lkmc_character_device_create_dev'
[ "$(cat "$dev")" = abcd ]
rmmod character_device_create
[ ! -e "$dev" ]

3
rootfs_overlay/lkmc/conf.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#find-the-kernel-config
zcat /proc/config.gz | grep -Ei "${1:-}"

9
rootfs_overlay/lkmc/count.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
# Count to infinity with 1 second sleep between each increment.
# Generate infinitely many system calls :-)
i=0
while true; do
echo "$i"
i=$(($i+1))
sleep 1
done

13
rootfs_overlay/lkmc/debugfs.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
set -e
d=/debugfs
mkdir -p "$d"
mount -t debugfs none "$d"
insmod debugfs.ko
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 42 ]
echo 13 > "${d}/lkmc_debugfs/myfile"
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 13 ]
echo 666 > "${d}/lkmc_debugfs_file"
[ "$(cat "${d}/lkmc_debugfs/myfile")" = 666 ]
rmmod debugfs
umount "$d"

27
rootfs_overlay/lkmc/dep.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_dep
f2=/sys/kernel/debug/lkmc_dep2
insmod dep.ko
insmod dep2.ko
# Initial value.
[ "$(cat "$f")" = 0 ]
# Changhing dep2 also changes dep.
printf 1 > "$f2"
[ "$(cat "$f")" = 1 ]
# Changhing dep also changes dep2.
printf 2 > "$f"
[ "$(cat "$f2")" = 2 ]
# sysfs shows us that the module has dependants.
[ "$(cat /sys/module/dep/refcnt)" = 1 ]
[ "$(ls /sys/module/dep/holders)" = dep2 ]
rmmod dep2.ko
[ "$(cat /sys/module/dep/refcnt)" = 0 ]
[ -z "$(ls /sys/module/dep/holders)" ]
rmmod dep.ko

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#replace-init
cd "$lkmc_home"
eval "$(printf "$lkmc_eval" | base64 -d)"

2
rootfs_overlay/lkmc/fb.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
cat /dev/urandom > "/dev/fb${1:-0}"

30
rootfs_overlay/lkmc/fops.sh Executable file
View File

@@ -0,0 +1,30 @@
#!/bin/sh
set -e
# Setup
f=/sys/kernel/debug/lkmc_fops
insmod fops.ko
# read
[ "$(cat "$f")" = abcd ]
# write
printf 01 > "$f"
[ "$(cat "$f")" = 01cd ]
# ENOSPC
printf abcd > "$f"
set +e
printf 12345 > "$f"
exit_status="$?"
set -e
[ "$exit_status" -eq 8 ]
[ "$(cat "$f")" = abcd ]
# seek
printf 1234 > "$f"
printf z | dd bs=1 of="$f" seek=2
[ "$(cat "$f")" = 12z4 ]
# Teardown
rmmod fops

View File

@@ -0,0 +1,3 @@
#!/bin/sh
/sbin/ifup -a
gdbserver :45455 "$@"

6
rootfs_overlay/lkmc/gem5.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#gem5-restore-new-scrip
m5 checkpoint
m5 resetstats
m5 readfile | sh
m5 exit

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# To be able to do init=/gem5_exit.sh, since kernel CLI argument passing is too messy:
# https://github.com/cirosantilli/linux-kernel-module-cheat#init-arguments
m5 exit

27
rootfs_overlay/lkmc/gpio.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -e
cd /sys/class/gpio
echo 480 > export
echo 481 > export
echo 482 > export
echo 488 > export
echo 496 > export
echo out > gpio480/direction
echo out > gpio481/direction
echo out > gpio482/direction
echo out > gpio488/direction
echo out > gpio496/direction
v=1
while true; do
echo $v > gpio480/value
echo $v > gpio481/value
echo $v > gpio482/value
echo $v > gpio488/value
echo $v > gpio496/value
if [ $v -eq 1 ]; then
v=0
else
v=1
fi
sleep 1
done

View File

@@ -0,0 +1,6 @@
#!/bin/sh
# Failed attempt at debugging /init, because:
# init must be run as pid 1
# Is this just a random BusyBox sanity check?
# - https://stackoverflow.com/questions/35019995/strace-init-process-pid-1-in-linux
/sbin/init "$@"

View File

@@ -0,0 +1,30 @@
#!/bin/sh
# This is an attempt to replace /etc/inittab with a single shell file,
# in order to to make everything explicit and sane.
#
# The rationale is that it will make it easier to port our setup to any image
# if our minimal init is contained in a single portable file.
#
# Of course, packages that rely on extra init may start failing at any
# point with this minimized setup, but this is a risk worth taking, especially
# because gem5 is slow and basically mandates a minimal init.
#
# Here we try to some basic common init tasks that will cover what the large
# majority of software will need.
#
# We don't care about shutdown commands since we focus on stateless disks.
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
mount -t proc proc /proc
mkdir -p /dev/pts
mkdir -p /dev/shm
# TODO do mounts direclty here. fstab only adds the fschk as extra functionality,
# but we don't care since our disks are stateless.
mount -a
login=/tmp/login
printf '#!/bin/sh
exec /bin/login root
' > "$login"
chmod +x "$login"
exec /sbin/getty -n -L -l "$login" console 0 vt100

View File

@@ -0,0 +1,4 @@
#!/bin/sh
set -e
insmod init_module.ko
rmmod init_module

13
rootfs_overlay/lkmc/insrm.sh Executable file
View File

@@ -0,0 +1,13 @@
#!/bin/sh
# Insert and remove a module n times to check for spurious errors / deadlocks.
set -e
mod="$1"
n="${2:-1}"
i=0
while [ $i -lt $n ]; do
echo "insmod $i"
insmod "/$mod.ko"
echo "rmmod $i"
rmmod "$mod"
i=$(($i+1))
done

7
rootfs_overlay/lkmc/ioctl.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_ioctl
insmod ioctl.ko
[ "$(/ioctl.out "$f" 0 1)" = 2 ]
[ "$(/ioctl.out "$f" 1 1 1)" = '2 0' ]
rmmod ioctl

2
rootfs_overlay/lkmc/kgdb.sh Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
echo g > /proc/sysrq-trigger

8
rootfs_overlay/lkmc/kstrto.sh Executable file
View File

@@ -0,0 +1,8 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_kstrto
insmod kstrto.ko
printf 123 > "$f"
[ "$(cat "$f")" = 124 ]
echo foobar > "$f" && exit 1
rmmod kstrto

View File

@@ -0,0 +1,3 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#tty
exec /bin/login root

View File

@@ -0,0 +1,4 @@
#!/bin/sh
dev="$1"
major="$(awk -F ' ' '$2 == "'"$dev"'" { print $1 }' /proc/devices)"
mknod "/dev/$dev" c "$major" 0

5
rootfs_overlay/lkmc/mmap.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
insmod mmap.ko
./mmap.out /proc/lkmc_mmap 2>&1 1>/dev/null
rmmod mmap.ko

7
rootfs_overlay/lkmc/netlink.sh Executable file
View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
insmod netlink.ko
[ "$(/netlink.out)" = 0 ]
[ "$(/netlink.out)" = 1 ]
[ "$(/netlink.out)" = 2 ]
rmmod netlink

20
rootfs_overlay/lkmc/params.sh Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/sh
set -e
d=/sys/module/params/parameters
i="${d}/i"
j="${d}/j"
f=/sys/kernel/debug/lkmc_params
insmod params.ko
[ "$(cat "$i")" = 0 ]
[ "$(cat "$j")" = 0 ]
[ "$(cat "$f")" = '0 0' ]
printf 1 > "$i"
[ "$(cat "$f")" = '1 0' ]
printf 2 > "$j"
[ "$(cat "$f")" = '1 2' ]
rmmod params
insmod params.ko i=3 j=4
[ "$(cat "$f")" = '3 4' ]
rmmod params

View File

@@ -0,0 +1,2 @@
#!/bin/sh
echo 1 > /sys/bus/pci/rescan

4
rootfs_overlay/lkmc/pmccntr.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
insmod pmccntr.ko
cd /sys/kernel/debug
cat lkmc_pmccntr

5
rootfs_overlay/lkmc/poll.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
insmod poll.ko
./poll.out /sys/kernel/debug/lkmc_poll
#rmmod poll

View File

@@ -0,0 +1,3 @@
#!/bin/sh
echo 8 > /proc/sys/kernel/printk
echo 'file kernel/module.c +p' > /sys/kernel/debug/dynamic_debug/control

5
rootfs_overlay/lkmc/procfs.sh Executable file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
set -e
insmod procfs.ko
[ "$(cat "/proc/lkmc_procfs")" = abcd ]
rmmod procfs

4
rootfs_overlay/lkmc/psa.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
# Show All possible ps fields to get better process visibility.
# TODO for some reason nothing shows after args, so we put it last.
ps -o user,group,comm,pid,ppid,sid,pgid,tty,vsz,rss,stat,args

56
rootfs_overlay/lkmc/qemu_edu.sh Executable file
View File

@@ -0,0 +1,56 @@
#!/bin/sh
set -ex
# Our modules does not the PCI device yet.
lspci -k
# => 00:04.0 Class 00ff: 1234:11e8 lkmc_pci
# Interrupt counts before we generate our interrupts.
cat /proc/interrupts
# Setup.
insmod qemu_edu.ko
/mknoddev.sh lkmc_pci
# Shows that this module owns the PCI device.
lspci -k
# => 00:04.0 Class 00ff: 1234:11e8 lkmc_pci
# Identifiction: just returns some fixed magic bytes.
dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=0 | od -An -t x1
# => 010000ed
# Negator. Sanity check that the hardware is getting updated.
dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=1 | od -An -t x1
printf '\xF0\xF0\xF0\xF0' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=1
dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=1 | od -An -t x1
# => 0F0F0F0F
# Factorial calculator.
# Request interrupt when the computation is over.
printf '\x80\x00\x00\x00' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=8
# factorial(0xC) = 0x1c8cfc00
printf '\x0C\x00\x00\x00' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=2
# => irq_handler .*
# Yes, we should use the interrupt to notify poll, but lazy.
sleep 1
dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=2 | od -An -t x1
dd bs=4 status=none if=/dev/lkmc_pci count=1 skip=8 | od -An -t x1
# => 1c8cfc00
# Manual IRQ raising.
printf '\x04\x03\x02\x01' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=24
# => irq_handler .*
sleep 1
printf '\x08\x07\x06\x05' | dd bs=4 status=none of=/dev/lkmc_pci count=1 seek=24
# => irq_handler .*
sleep 1
# Teardown.
rm /dev/lkmc_pci
rmmod qemu_edu
# Interrupt counts after we generate our interrupts.
# Compare with before.
cat /proc/interrupts

View File

@@ -0,0 +1,12 @@
#!/bin/sh
set -ex
./rand_check.out
# Check if network is being replayed.
# https://superuser.com/questions/635020/how-to-know-current-time-from-internet-from-command-line-in-linux
# https://tf.nist.gov/tf-cgi/servers.cgi
#echo | nc 129.6.15.28 13
# busybox's poweroff panics, TODO why. Likely tries to kill shell.
# So just use our super raw command.
./poweroff.out

10
rootfs_overlay/lkmc/seq_file.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_seq_file
insmod seq_file.ko
[ "$(cat "$f")" = "$(printf '0\n1\n2\n')" ]
[ "$(cat "$f")" = "$(printf '0\n1\n2\n')" ]
[ "$(dd if="$f" bs=1 count=2 skip=0 status=none)" = "$(printf '0\n')" ]
[ "$(dd if="$f" bs=1 count=2 skip=2 status=none)" = "$(printf '1\n')" ]
[ "$(dd if="$f" bs=4 count=1 skip=0 status=none)" = "$(printf '0\n1\n')" ]
rmmod seq_file

View File

@@ -0,0 +1,7 @@
#!/bin/sh
set -e
f=/sys/kernel/debug/lkmc_seq_file_single_open
insmod seq_file_single_open.ko
[ "$(cat "$f")" = "$(printf 'ab\ncd\n')" ]
[ "$(dd if="$f" bs=1 count=3 skip=1)" = "$(printf "b\nc\n")" ]
rmmod seq_file_single_open

4
rootfs_overlay/lkmc/sshd.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
/sbin/ifup -a
/usr/bin/ssh-keygen -A
/usr/sbin/sshd

11
rootfs_overlay/lkmc/sysfs.sh Executable file
View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
insmod sysfs.ko
f=/sys/kernel/lkmc_sysfs/foo
# write
printf 12345 > "$f"
# read
[ "$(cat "$f")" = 1234 ]
# seek
[ "$(dd if="$f" bs=1 count=2 skip=1 status=none)" = 23 ]
rmmod sysfs

27
rootfs_overlay/lkmc/test_all.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
test_dir="${1:-.}"
for test in \
anonymous_inode.sh \
character_device.sh \
character_device_create.sh \
debugfs.sh \
dep.sh \
fops.sh \
init_module.sh \
ioctl.sh \
kstrto.sh \
mmap.sh \
netlink.sh \
params.sh \
procfs.sh \
seq_file.sh \
seq_file_single_open.sh \
sysfs.sh \
; do
if ! "${test_dir}/${test}"; then
echo "Test failed: ${test}"
./test_fail.sh
exit 1
fi
done
echo 'All tests passed.'

View File

@@ -0,0 +1,3 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#magic-failure-string
echo lkmc_test_fail

17
rootfs_overlay/lkmc/uio_read.sh Executable file
View File

@@ -0,0 +1,17 @@
#!/bin/sh
# https://github.com/cirosantilli/linux-kernel-module-cheat#uio
set -e
modprobe uio_pci_generic
# pci_min device
echo '1234 11e9' > /sys/bus/pci/drivers/uio_pci_generic/new_id
./uio_read.out &
# Helper to observe interrupts.
insmod irq.ko
base="$(setpci -d 1234:11e9 BASE_ADDRESS_0)"
# Start generating interrupt.
devmem "0x${base}" w 0x12345678
# Stop generating interrupt.
devmem "0x$(($base + 4))" w 0x12345678
devmem "0x${base}" w 0x12345678
devmem "0x$(($base + 4))" w 0x12345678
modprobe -r uio_pci_generic

View File

@@ -0,0 +1,4 @@
#!/bin/sh
set -e
insmod vermagic.ko
rmmod vermagic

View File

@@ -0,0 +1,17 @@
#!/bin/sh
set -ex
insmod virt_to_phys.ko
cd /sys/kernel/debug
cat lkmc_virt_to_phys
# k = 0x12345678
# i = 0x12345678
addr=$(awk '$1 == "virt_to_phys_k" { print $2 }' lkmc_virt_to_phys)
devmem "$addr"
devmem "$addr" w 0x9ABCDEF0
addr=$(awk '$1 == "virt_to_phys_i" { print $2 }' lkmc_virt_to_phys)
devmem "$addr"
devmem "$addr" w 0x9ABCDEF0
cat lkmc_virt_to_phys
# k = 0x9ABCDEF0
# i = 0x12345678
rmmod virt_to_phys