Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Override os.rename, os.remove, os.execute for sandbox lua
Baptiste Daroussin committed 6 years ago
commit 5a470d4cfb491396fbbace8b40f8a9c8dd2a62f2
parent 6fbb16c
2 files changed +137 -2
modified libpkg/lua_scripts.c
@@ -46,6 +46,7 @@
#include <lfs.h>
#include <fcntl.h>
#include <err.h>
+
#include <stdio.h>

#include "pkg.h"
#include "private/pkg.h"
@@ -158,17 +159,58 @@ lua_io_open(lua_State *L)
	luaL_argcheck(L, checkflags(md, &oflags), 2, "invalid mode");
	int fd = openat(pkg->rootfd, RELATIVE_PATH(filename), oflags, DEFFILEMODE);
	if (fd == -1)
-
		return (1);
+
		return (luaL_fileresult(L, 0, filename));
	p->f = fdopen(fd, mode);
	return ((p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1);
}

+
static int
+
lua_os_remove(lua_State *L) {
+
	const char *filename = RELATIVE_PATH(luaL_checkstring(L, 1));
+
	lua_getglobal(L, "package");
+
	struct pkg *pkg = lua_touserdata(L, -1);
+
	int flag = 0;
+
	struct stat st;
+

+
	if (fstatat(pkg->rootfd, filename, &st, AT_SYMLINK_NOFOLLOW) == -1)
+
		return (luaL_fileresult(L, 1, NULL));
+

+
	if (S_ISDIR(st.st_mode))
+
		flag = AT_REMOVEDIR;
+

+
	return (luaL_fileresult(L, unlinkat(pkg->rootfd, filename, flag) == 0, NULL));
+
}
+

+
static int
+
lua_os_rename(lua_State *L)
+
{
+
	const char *fromname = RELATIVE_PATH(luaL_checkstring(L, 1));
+
	const char *toname = RELATIVE_PATH(luaL_checkstring(L, 2));
+
	lua_getglobal(L, "package");
+
	struct pkg *pkg = lua_touserdata(L, -1);
+
	return luaL_fileresult(L, renameat(pkg->rootfd, fromname, pkg->rootfd, toname) == 0, NULL);
+
}
+

+
static int
+
lua_os_execute(lua_State *L)
+
{
+
	return (luaL_error(L, "os.execute not available"));
+
}
+

static void
lua_override_ios(lua_State *L)
{
	lua_getglobal(L, "io");
	lua_pushcfunction(L, lua_io_open);
	lua_setfield(L, -2, "open");
+

+
	lua_getglobal(L, "os");
+
	lua_pushcfunction(L, lua_os_remove);
+
	lua_setfield(L, -2, "remove");
+
	lua_pushcfunction(L, lua_os_rename);
+
	lua_setfield(L, -2, "rename");
+
	lua_pushcfunction(L, lua_os_execute);
+
	lua_setfield(L, -2, "execute");
}

int
modified tests/frontend/lua.sh
@@ -5,7 +5,10 @@
tests_init \
	script_basic \
	script_message \
-
	script_rooteddir
+
	script_rooteddir \
+
	script_remove \
+
	script_execute \
+
	script_rename

script_basic_body() {
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
@@ -96,3 +99,93 @@ EOF
		cat ${TMPDIR}/target/file.txt

}
+

+
script_remove_body() {
+
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat << EOF >> test.ucl
+
lua_scripts: {
+
  post-install: [ <<EOS
+
os.remove("/file")
+
EOS
+
,
+
  ]
+
}
+
EOF
+

+
	atf_check \
+
		-o empty \
+
		-e empty \
+
		-s exit:0 \
+
		pkg create -M test.ucl
+

+
	mkdir -p ${TMPDIR}/target/file
+
	atf_check \
+
		-e empty \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR=/dev/null -r ${TMPDIR}/target install -qfy ${TMPDIR}/test-1.txz
+
	test -d ${TMPDIR}/target/file && atf_fail "directory not removed"
+

+
	touch ${TMPDIR}/target/file
+
	atf_check \
+
		-e empty \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR=/dev/null -r ${TMPDIR}/target install -qfy ${TMPDIR}/test-1.txz
+
	test -f ${TMPDIR}/target/file && atf_fail "file not removed"
+
	return 0
+
}
+

+
script_rename_body() {
+
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat << EOF >> test.ucl
+
lua_scripts: {
+
  post-install: [ <<EOS
+
os.rename("/file","/plop")
+
EOS
+
,
+
  ]
+
}
+
EOF
+

+
	atf_check \
+
		-o empty \
+
		-e empty \
+
		-s exit:0 \
+
		pkg create -M test.ucl
+
	mkdir -p ${TMPDIR}/target
+
	touch ${TMPDIR}/target/file
+
	atf_check \
+
		-e inline:"${ERR}" \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR=/dev/null -r ${TMPDIR}/target install -qfy ${TMPDIR}/test-1.txz
+
	test -f ${TMPDIR}/target/file && atf_fail "File not renamed"
+
	test -f ${TMPDIR}/target/plop || atf_fail "File not renamed"
+
	return 0
+
}
+

+
script_execute_body() {
+
	atf_check -s exit:0 sh ${RESOURCEDIR}/test_subr.sh new_pkg "test" "test" "1"
+
	cat << EOF >> test.ucl
+
lua_scripts: {
+
  post-install: [ <<EOS
+
os.execute("echo yeah")
+
EOS
+
,
+
  ]
+
}
+
EOF
+

+
ERR="pkg: Failed to execute lua script: [string \"os.execute(\"echo yeah\")\"]:1: os.execute not available
+
pkg: lua script failed\n"
+

+

+
	atf_check \
+
		-o empty \
+
		-e empty \
+
		-s exit:0 \
+
		pkg create -M test.ucl
+
	mkdir -p ${TMPDIR}/target
+
	atf_check \
+
		-e inline:"${ERR}" \
+
		-s exit:0 \
+
		pkg -o REPOS_DIR=/dev/null -r ${TMPDIR}/target install -qfy ${TMPDIR}/test-1.txz
+
}