lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Rena once stated:
> On Mon, Oct 7, 2013 at 9:25 PM, Sean Conner <sean@conman.org> wrote:
> 
> > It was thus said that the Great Rena once stated:
> > > Does anyone have experience running Lua safely as root? What environment
> > > variables, files, and behaviours to watch out for to avoid creating a
> > > security flaw or potentially breaking something? I recall hearing about
> > Lua
> > > being used in the BSD kernel, so I think it should be possible.
> >
> >   I do.  I've written a few programs in Lua that I run as root, but they
> > have a well defined function, and none of the programs execute arbitrary
> > Lua code (in other words, I know the code being run as root).
> >
> >   But I'm not sure what you are asking in particular.  It's easy to
> > create a Lua jail (I've done that too), but if you are running as root,
> > it's because you want to do something that root can only do, so my
> > question to you is: what are you trying to do?
> >
> In particular I'm interested in reading a lot of system information from
> /proc and making it available to another program in a somewhat saner
> /format for display. Some things in /proc can only be read by root.

  If you are doing something like that, the advice typically given is to do
the absolute minimum as root, then switch credentials to lesser priviledges. 
In this case, it's opening a file under /proc.  As root, I would do
something like:

	-- we don't accept filenames directly---we map given keys to
	-- the data file we want.  This way, we can limit the files read
	-- using priviledged credentials.
	
	files = 
	{
	  "somekey" = "/proc/some/protected/file",
	  "someotherkey" = "/proc/another/protected/file"
	}
	
	-- check to see if we have at least one argument

	if #arg == 0 then
	  io.stderr:write("some usage text\n")
	  os.exit(1)
	end

	-- read the key, and translate it to a file to open.

	filetoopen = files[arg[1]]
	if filetoopen == nil then
	  io.stderr:write("naughty naughty, can't see that\n")
	  os.exit(1)
	end

	-- attempt to open the file 

	fp = io.open(filetoopen,"r")
	if fp == nil then
	  io.stderr:write("can't open data\n")
	  os.exit(1)
	end

	-- we have the file open
	-- now we drop privs

	setgid('nobody')
	setuid('nobody')

	-- now the rest of the code

  This is just an example, but again, you want to do the minimum required of
root, then drop the priviledges (once a file is open as root, you still have
access to the files (or sockets) you've opened).  The less you trust user
input, the better.  If you are going to execute programs and not give an
absolute or relative path (just a program name, like 'ls') then you'll
probably want to use a restricted $PATH, or just hardcode the absolute
filepath.  Be wary if you find $LD_LIBRARY_PATH set (again, if you are
executing programs from your script as root).

  -spc