⬢ DragonFlyBSD Kernel Audit
DF-2573 / gen_ngdpoc.sh
← back to finding ↓ download raw
#!/bin/sh
# gen_ngdpoc.sh -- (runs IN THE GUEST) generate netgraph/ng_device_poc.c:
#   shim prologue + ng_device.c (byte-verbatim EXCEPT one documented
#   compatibility line, see below) + epilogue.
#
# The ONE allowed transformation (asserted: exactly one line changed):
#   ng_device.c:203  "ng_device_cons(node_p node)"
#        ->         "ng_device_cons(node_p *node)"
# i.e. the node-constructor signature is aligned with the current
# ng_constructor_t ABI (netgraph.h:174, called with node_p* at
# ng_base.c:371).  The constructor only returns EINVAL and is NEVER invoked
# in any harness flow (the "device" node is created via ng_make_node_common,
# which bypasses constructors); the functions under test --
# ng_device_newhook (ng_device.c:263-312), ng_device_disconnect
# (ng_device.c:385-414) and get_free_unit -- are byte-identical.
set -e
cd /usr/src/sys/netgraph
SRC=ng_device.c
OUT=ng_device_poc.c
PRE=/tmp/ngdpoc_shim_prepend.h
APP=/tmp/ngdpoc_append.c

VSHA=$(sha256 -q $SRC)

# compatibility copy: exactly the one constructor-signature line
sed -e 's/^ng_device_cons(node_p node)$/ng_device_cons(node_p *node)/' \
    $SRC > /tmp/ngdpoc_compat.c
set -- $(diff $SRC /tmp/ngdpoc_compat.c | grep -c '^< ')
NCHANGED=$1
if [ "$NCHANGED" != "1" ]; then
	echo "NGDPOC: FATAL compat sed changed $NCHANGED lines (expected 1)"
	diff $SRC /tmp/ngdpoc_compat.c || true
	exit 1
fi
CSHA=$(sha256 -q /tmp/ngdpoc_compat.c)

gen() {
	printf '/* DF-2573/DF-2574 POC translation unit (GENERATED by gen_ngdpoc.sh) */\n'
	printf '#define NGDPOC_VSRC_SHA256 "%s"\n' "$VSHA"
	cat $PRE
	printf '\n/* ==== ng_device.c BEGIN (pristine sha256=%s; compat sha256=%s; ONE line: ng_device_cons signature) ==== */\n' "$VSHA" "$CSHA"
	cat /tmp/ngdpoc_compat.c
	printf '\n/* ==== ng_device.c END ==== */\n'
	cat $APP
}

gen > $OUT
gen > /tmp/ngdpoc_expected
cmp $OUT /tmp/ngdpoc_expected

# byte-exact proof: the lines strictly between the two markers must begin
# with the compat copy (plus the one blank line the generator layout emits
# before the END marker)
awk '
  index($0, "/* ==== ng_device.c BEGIN") == 1 { f = 1; next }
  index($0, "/* ==== ng_device.c END") == 1 { f = 0 }
  f { print }
' $OUT > /tmp/ngdpoc_region

set -- $(wc -l < /tmp/ngdpoc_compat.c); NSRC=$1
set -- $(wc -l < /tmp/ngdpoc_region); NREG=$1
if [ "$NREG" != "$((NSRC + 1))" ] || \
   ! head -n "$NSRC" /tmp/ngdpoc_region | cmp -s - /tmp/ngdpoc_compat.c || \
   [ -n "$(tail -n 1 /tmp/ngdpoc_region)" ]; then
	echo "NGDPOC: FATAL region mismatch (region=$NREG compat=$NSRC)"
	cmp /tmp/ngdpoc_region /tmp/ngdpoc_compat.c || true
	exit 1
fi

echo "NGDPOC: generated $OUT"
echo "NGDPOC: pristine  $SRC sha256 = $VSHA"
echo "NGDPOC: compat copy     sha256 = $CSHA  (1 line: ng_device_cons signature)"
echo "NGDPOC: $OUT sha256 = $(sha256 -q $OUT)"