Thursday, September 17, 2020

Re: luakit patch: use os.remove() instead of spawning rm(1) process

--- unveil.lua

-- ask loading unveil_wm.lua inside WebKitProcess
local wm = require_web_module("unveil_wm")

-- local extension for pledge(2) + unveil(2)
package.cpath = package.cpath .. ';/home/semarie/repos/lua-openbsd/openbsd.so'
local openbsd = require("openbsd")

-- in luakit process
print("unveil: luakit")
if openbsd.unveil("/", "rwc") ~= 0 or
openbsd.unveil("/usr/local/bin/luakit", "x") ~= 0 or
openbsd.unveil("/usr/local/libexec/webkit2gtk-4.0", "x") ~= 0 or
openbsd.unveil() ~= 0
then
print("unveil: oops unveil.lua (luakit)")
end
/*
* Copyright (c) 2018 Sebastien Marie <semarie@online.fr>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/*
* to compile:
* cc -Wall -shared -o openbsd.so $(pkg-config --cflags --libs luaXX)
*/

#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>

#include <errno.h>
#include <unistd.h>

static int ipledge(lua_State *L);
static int iunveil(lua_State *L);

/**
* Register functions
*/
int
luaopen_openbsd(lua_State *L)
{
lua_newtable(L);
lua_pushcfunction(L, &ipledge);
lua_setfield(L, -2, "pledge");

lua_pushcfunction(L, &iunveil);
lua_setfield(L, -2, "unveil");

return 1;
}

static int
ipledge(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
const char *promises = NULL;
const char *execpromises = NULL;
int ret;

/* check arguments */
if ((n > 2) ||
! (lua_isstring(L, 1) || lua_isnoneornil(L, 1)) ||
! (lua_isstring(L, 2) || lua_isnoneornil(L, 2))) {
lua_pushliteral(L, "incorrect argument");
lua_error(L);
}

/* get arguments */
if (lua_isstring(L, 1))
promises = lua_tostring(L, 1);
if (lua_isstring(L, 2))
execpromises = lua_tostring(L, 2);

/* call pledge(2) */
ret = pledge(promises, execpromises);

if (ret != 0)
lua_pushnumber(L, errno);
else
lua_pushnumber(L, 0);

return 1;
}

static int
iunveil(lua_State *L)
{
int n = lua_gettop(L); /* number of arguments */
const char *path;
const char *perm;
int ret;

/* check arguments */
if (n == 0) {
path = NULL;
perm = NULL;

} else if (n == 2) {
if (! lua_isstring(L, 1) ||
! lua_isstring(L, 2)) {
lua_pushliteral(L, "incorrect argument type");
lua_error(L);
}

/* get arguments */
path = lua_tostring(L, 1);
perm = lua_tostring(L, 2);

} else {
lua_pushliteral(L, "incorrect argument number");
lua_error(L);
}

/* call unveil(2) */
ret = unveil(path, perm);

if (ret != 0)
lua_pushnumber(L, errno);
else
lua_pushnumber(L, 0);

return 1;
}
--- unveil_wm.lua

local ui = ipc_channel("unveil_wm")

--- local extension for pledge(2) + unveil(2)
package.cpath = package.cpath .. ';/home/semarie/repos/lua-openbsd/openbsd.so'
local openbsd = require("openbsd")

-- in WebKitProcess
print("unveil: WebKitProcess")
if openbsd.unveil("/", "r") ~= 0 or
openbsd.unveil("/dev/drm0", "rw") ~= 0 or
openbsd.unveil("/dev/drmR128", "rw") ~= 0 or
openbsd.unveil("/tmp", "rwc") ~= 0 or
openbsd.unveil("/home", "") ~= 0 or
--openbsd.unveil("/usr/bin/lpr", "x") ~= 0 or
openbsd.unveil() ~= 0
then
print("unveil: oops unveil_wm.lua (WebKitProcess)")
end
On Thu, Sep 17, 2020 at 06:51:51PM +0200, Stefan Hagen wrote:
> Sebastien Marie wrote:
> > The following diff is a backport of
> > https://github.com/luakit/luakit/commit/4b22c18d5eb5594136091b7b615dc8f9ded0e32f
> > commit in order to avoid using rm(1) process to remove a file, but use
> > os.remove() lua function.
> >
> > It permits to me to remove a spawn call whereas I am looking to
> > properly unveil(2) luakit process.
> >
> > Comments or OK ?
>
> Looks good. OK from my side.
> Do you have an unveiled version already?

yes :-)

I am using/experimenting with the following (see attached files):

- unveil.lua : it unveils the luakit process.
currently, it is mostly used for removing execve(2) capability.

- unveil_wm.lua : it unveils the WebKitProcess (content process)
the filesystem is readonly except drm devices and /tmp

with lariza (another webkit based browser), WebKitProcess needs to
execve(2) "lpr" to print. here, I don't have test it for now so it
is still commented.

- openbsd.c : lua module for unveil(2) (and pledge(2)) binding


And finally my ~/.config/luakit/userconf.lua contains:

-- unveil luakit+WebKitProcess
require "unveil"


$ ps ux | grep -E '(luakit|WebKit)'
semarie 72835 0.0 0.3 80848 98032 ?? SU 1:45PM 0:05.09 luakit
semarie 19656 0.0 0.2 60880 54764 ?? I 1:45PM 0:01.20 /usr/local/libexec/webkit2gtk-4.0/WebKitNetworkProcess 3 17 (WebKitNetworkPro)
semarie 95077 0.0 0.5 88148 142776 ?? SU 1:45PM 0:04.81 /usr/local/libexec/webkit2gtk-4.0/WebKitWebProcess 11 24
semarie 82971 0.0 0.3 76284 99312 ?? SU 1:47PM 0:03.12 /usr/local/libexec/webkit2gtk-4.0/WebKitWebProcess 18 34

So, on the three process types used, only the WebKitNetworkProcess
isn't unveiled. But I am unsure if it supports plugins and so if I can
inject unveil(2) or pledge(2). Something to see later.

With the attached code, it should be also possible to play with
pledge(2). But I need a working browser first (I am on the way to
reimplement few plugins I am using with firefox).

Thanks.
--
Sebastien Marie

No comments:

Post a Comment