Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Override io.open for lua scripts and capsicumize
Baptiste Daroussin committed 6 years ago
commit 58733408725a566b28fe7946fa6671287c1521e2
parent ae4843a
4 files changed +173 -3
modified libpkg/Makefile.autosetup
@@ -40,7 +40,8 @@ SRCS= backup.c \
	pkg_jobs.c \
	pkg_repo_create.c \
	pkg_version.c \
-
	rcscripts.c
+
	rcscripts.c \
+
	flags.c

LOCAL_CFLAGS=	-I$(top_srcdir)/compat \
		-I$(top_srcdir)/external/blake2 \
added libpkg/flags.c
@@ -0,0 +1,115 @@
+
/*-
+
 * SPDX-License-Identifier: BSD-3-Clause
+
 *
+
 * Copyright (c) 1990, 1993
+
 *	The Regents of the University of California.  All rights reserved.
+
 *
+
 * This code is derived from software contributed to Berkeley by
+
 * Chris Torek.
+
 *
+
 * Redistribution and use in source and binary forms, with or without
+
 * modification, are permitted provided that the following conditions
+
 * are met:
+
 * 1. Redistributions of source code must retain the above copyright
+
 *    notice, this list of conditions and the following disclaimer.
+
 * 2. Redistributions in binary form must reproduce the above copyright
+
 *    notice, this list of conditions and the following disclaimer in the
+
 *    documentation and/or other materials provided with the distribution.
+
 * 3. Neither the name of the University nor the names of its contributors
+
 *    may be used to endorse or promote products derived from this software
+
 *    without specific prior written permission.
+
 *
+
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+
 * SUCH DAMAGE.
+
 */
+

+
#if defined(LIBC_SCCS) && !defined(lint)
+
static char sccsid[] = "@(#)flags.c	8.1 (Berkeley) 6/4/93";
+
#endif /* LIBC_SCCS and not lint */
+
#include <sys/cdefs.h>
+
__FBSDID("$FreeBSD: head/lib/libc/stdio/flags.c 326025 2017-11-20 19:49:47Z pfg $");
+

+
#include <sys/types.h>
+
#include <sys/file.h>
+
#include <stdio.h>
+
#include <errno.h>
+

+
/*
+
 * Return the (stdio) flags for a given mode.  Store the flags
+
 * to be passed to an _open() syscall through *optr.
+
 * Return 1 on error.
+
 */
+
int
+
checkflags(const char *mode, int *optr)
+
{
+
	int ret, m, o, known;
+
	ret = 0;
+

+
	switch (*mode++) {
+

+
	case 'r':	/* open for reading */
+
		ret = 1;
+
		m = O_RDONLY;
+
		o = 0;
+
		break;
+

+
	case 'w':	/* open for writing */
+
		ret = 1;
+
		m = O_WRONLY;
+
		o = O_CREAT | O_TRUNC;
+
		break;
+

+
	case 'a':	/* open for appending */
+
		ret = 1;
+
		m = O_WRONLY;
+
		o = O_CREAT | O_APPEND;
+
		break;
+

+
	default:	/* illegal mode */
+
		ret = 0;
+
		errno = EINVAL;
+
		return (0);
+
	}
+

+
	do {
+
		known = 1;
+
		switch (*mode++) {
+
		case 'b':
+
			/* 'b' (binary) is ignored */
+
			break;
+
		case '+':
+
			/* [rwa][b]\+ means read and write */
+
			ret = 1;
+
			m = O_RDWR;
+
			break;
+
		case 'x':
+
			/* 'x' means exclusive (fail if the file exists) */
+
			o |= O_EXCL;
+
			break;
+
		case 'e':
+
			/* set close-on-exec */
+
			o |= O_CLOEXEC;
+
			break;
+
		default:
+
			known = 0;
+
			break;
+
		}
+
	} while (known);
+

+
	if ((o & O_EXCL) != 0 && m == O_RDONLY) {
+
		errno = EINVAL;
+
		return (1);
+
	}
+

+
	*optr = m | o;
+
	return (ret);
+
}
modified libpkg/lua_scripts.c
@@ -39,6 +39,7 @@
#include <lauxlib.h>
#include <lualib.h>
#include <lfs.h>
+
#include <fcntl.h>

#include "pkg.h"
#include "private/pkg.h"
@@ -104,8 +105,6 @@ lua_prefix_path(lua_State *L)
	char path[MAXPATHLEN];
	path[0] = '\0';

-
	if (ctx.pkg_rootdir != NULL && strcmp(ctx.pkg_rootdir, "/") != 0)
-
		strlcat(path, ctx.pkg_rootdir, MAXPATHLEN);
	if (*str == '/') {
		strlcat(path, str, MAXPATHLEN);
	} else {
@@ -118,6 +117,54 @@ lua_prefix_path(lua_State *L)
	return (1);
}

+
/*
+
 * this is a copy of lua code to be able to override open
+
 * merge of newprefile and newfile
+
 */
+

+
static int
+
my_iofclose(lua_State *L)
+
{
+
	luaL_Stream *p = ((luaL_Stream *)luaL_checkudata(L, 1, LUA_FILEHANDLE));
+
	int res = fclose(p->f);
+
	return (luaL_fileresult(L, (res == 0), NULL));
+
}
+

+
static luaL_Stream *
+
newfile(lua_State *L) {
+
	luaL_Stream *p = (luaL_Stream *)lua_newuserdata(L, sizeof(luaL_Stream));
+
	p->f = NULL;
+
	p->closef = &my_iofclose;
+
	luaL_setmetatable(L, LUA_FILEHANDLE);
+
	return (p);
+
}
+

+
static int
+
lua_io_open(lua_State *L)
+
{
+
	const char *filename = luaL_checkstring(L, 1);
+
	const char *mode = luaL_optstring(L, 2, "r");
+
	lua_getglobal(L, "package");
+
	struct pkg *pkg = lua_touserdata(L, -1);
+
	int oflags;
+
	luaL_Stream *p = newfile(L);
+
	const char *md = mode;
+
	luaL_argcheck(L, checkflags(md, &oflags), 2, "invalid mode");
+
	int fd = openat(pkg->rootfd, RELATIVE_PATH(filename), oflags);
+
	if (fd == -1)
+
		return (1);
+
	p->f = fdopen(fd, mode);
+
	return ((p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1);
+
}
+

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

int
pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type)
{
@@ -179,6 +226,12 @@ pkg_lua_script_run(struct pkg * const pkg, pkg_lua_script type)
			luaL_requiref(L, "lfs", luaopen_lfs, 1);
			luaL_newlib(L, pkg_lib);
			lua_setglobal(L, "pkg");
+
			lua_override_ios(L);
+
#ifdef HAVE_CAPSICUM
+
			if (cap_enter() < 0 && errno != ENOSYS) {
+
				err(1, "cap_enter failed");
+
			}
+
#endif

			pkg_debug(3, "Scripts: executing lua\n--- BEGIN ---\n%s\nScripts: --- END ---", lscript->script);
			if (luaL_dostring(L, lscript->script)) {
modified libpkg/private/utils.h
@@ -100,5 +100,6 @@ int merge_3way(char *pivot, char *v1, char *v2, UT_string *out);
bool string_end_with(const char *path, const char *str);
bool mkdirat_p(int fd, const char *path);
int get_socketpair(int *);
+
int checkflags(const char *mode, int *optr);

#endif