Skip to content

[BUG] rpcd service does not process all states correctly #26

@remittor

Description

@remittor

Test script:

rpctest.sh
#!/bin/sh

EXE_DIR=$( cd "$(dirname "$0")" 2>/dev/null && pwd )

RPC_URL="http://127.0.0.1/ubus"

usage() {
	echo "Usage:"
	echo "  $0 -p <password> -c <command> [-s]"
	echo
	echo "Options:"
	echo "  -p  root password"
	echo "  -c  command string (no quotes inside!)"
	echo "  -s  run via 'sh -c'"
	echo "  -T  run test with N iterations"
	exit 1
}

PASSWORD=""
CMDLINE=""
USE_SH=0
TEST_MAX=0

while getopts "p:c:sT:" opt; do
	case "$opt" in
		p) PASSWORD="$OPTARG" ;;
		c) CMDLINE="$OPTARG" ;;
		s) USE_SH=1 ;;
		T) TEST_MAX="$OPTARG" ;;
		*) usage ;;
	esac
done

[ "$PASSWORD" = "@" ] && PASSWORD=xxxxxxxxxxx
[ -z "$PASSWORD" ] && usage
[ -z "$CMDLINE" ] && usage

LOGIN_JSON=$( cat <<EOF
{
	"jsonrpc": "2.0",
	"id": 1,
	"method": "call",
	"params": [
		"00000000000000000000000000000000",
		"session",
		"login",
		{
			"username": "root",
			"password": "$PASSWORD"
		}
	]
}
EOF
)

LOGIN_REPLY=$( curl -s "$RPC_URL" -H 'Content-Type: application/json' -d "$LOGIN_JSON" )

SESSION=$( echo "$LOGIN_REPLY" | sed -n 's/.*"ubus_rpc_session"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' )

if [ -z "$SESSION" ]; then
	echo "ERROR: login failed"
	echo "$LOGIN_REPLY"
	exit 2
fi

if [ "$USE_SH" -eq 1 ]; then
	# sh -c "string"
	CMD="/bin/sh"
	PARAMS_JSON="\"-c\",\"$CMDLINE\""
else
	# split by spaces
	set -- $CMDLINE
	CMD="$1"
	shift
	PARAMS_JSON=""
	for a in "$@"; do
		PARAMS_JSON="$PARAMS_JSON,\"$a\""
	done
	PARAMS_JSON="${PARAMS_JSON#,}"
fi

EXEC_JSON=$( cat <<EOF
{
	"jsonrpc": "2.0",
	"id": 2,
	"method": "call",
	"params": [
		"$SESSION",
		"file",
		"exec",
		{
			"command": "$CMD",
			"params": [ $PARAMS_JSON ]
		}
	]
}
EOF
)

TEST_ITER=0
while true; do
	TEST_ITER=$((TEST_ITER + 1))
	TEST_RESP=$( curl -s "$RPC_URL" -H 'Content-Type: application/json' -d "$EXEC_JSON" )
	echo "$TEST_RESP"
	if ! echo "$TEST_RESP" | grep -q '"result":\[0' ; then
		echo "ERROR: response with error code. Iteration = $TEST_ITER"
		exit 1
	fi
	[ $TEST_ITER -ge $TEST_MAX ] && break
done

echo ""

After running the script, you need to wait for a collision to occur:

> ./rpctest.sh -p @ -s -c '( exec >/dev/null 2>&1 ; echo 123 ) & ' -T 3000000
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
.....
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
{"jsonrpc":"2.0","id":2,"result":[0,{"code":0}]}
{"jsonrpc":"2.0","id":2,"result":[7]}
ERROR: response with error code. Iteration = 2178

A full description of the cause of the error and a fix can be found here: https://forum.openwrt.org/t/245914

Fix: remittor-pr@57e08ec

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions