openwrt / openwrt/rpcd

[BUG] rpcd service does not process all states correctly

Open
#26 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C
Stars
15
Forks
28
PR merge metrics
No merged PRs in 30d

Description

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: https://github.com/remittor-pr/rpcd/commit/57e08ec37fc33a9b79b547ebd65550e68cceba60

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided rpctest.sh reproduction and trace the rpcd file.exec request path. Use the linked forum discussion and fix commit as investigation references, then rerun the script to confirm repeated requests no longer return the [7] error response.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
api, backend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.