This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
DeltaX's profile picture

Fake Root?

Started by DeltaX, 13 July 2014 - 12:33 PM
DeltaX #1
Posted 13 July 2014 - 02:33 PM
I'm making a sandboxing OS, and I want to know how to make programs think they are in root, so they will edit files in their directory, but they can still access the global filesystem if the user confirms.
Saldor010 #2
Posted 13 July 2014 - 03:05 PM
I don't know how to do that, but I suggest you take a look at the FS API ( Here! ), you might find your answer there.
Edited on 13 July 2014 - 01:06 PM
SquidDev #3
Posted 13 July 2014 - 03:41 PM
Hmmm. This code does the sandboxing bit:

Spoiler

local Root = "path/to/sandbox/" -- Need trailing slash for it to work

local function SanitisePath(Path)
  --Get rid of ../ es
  local Path = fs.combine('/', Path):gsub('%.%./?', '')
  local Path = fs.combine(Root, Path)

  --If it doesn''t start with root then:
  if string.sub(Path, 1, string.len(Root)) ~= Root then
    error("Bluuuuuuuuuurgh")
  end

  return Path
end

local Environment = {
  ['fs'] = {
    ['open'] = function(Path, Type)
      return fs.open(SanitisePath(Path), Type)
    end
    --And so on for all other functions
  }

  --Might want to include shell and os.run as they also use these.
}
--Might want to do this so they can access everything
setmetatable(Environment, { __index = getfenv() } )

--Fail safe
Environment._G = Environment

local Func = loadfile("ToSandbox.lua")
setfenv(Func, Environment)
Func()

However getfenv does always end up ruining your sandbox:


local ParentEnv = getfenv(fs.open)
--I can now open files in the root directory!
local Handle = ParentEnv.fs.open("startup", "w")

I've never been able to get beyond this step (Ok, I haven't tried much). It is very hard to prevent getfenv being able to at least get a hint of the parent environment and so be able to access the original file system (or whatever).
Edited on 13 July 2014 - 01:43 PM
DeltaX #4
Posted 13 July 2014 - 04:34 PM
Hmmm. This code does the sandboxing bit:
Spoiler
 local Root = "path/to/sandbox/" -- Need trailing slash for it to work local function SanitisePath(Path) --Get rid of ../ es local Path = fs.combine('/', Path):gsub('%.%./?', '') local Path = fs.combine(Root, Path) --If it doesn''t start with root then: if string.sub(Path, 1, string.len(Root)) ~= Root then error("Bluuuuuuuuuurgh") end return Path end local Environment = { ['fs'] = { ['open'] = function(Path, Type) return fs.open(SanitisePath(Path), Type) end --And so on for all other functions } --Might want to include shell and os.run as they also use these. } --Might want to do this so they can access everything setmetatable(Environment, { __index = getfenv() } ) --Fail safe Environment._G = Environment local Func = loadfile("ToSandbox.lua") setfenv(Func, Environment) Func() 
However getfenv does always end up ruining your sandbox:
 local ParentEnv = getfenv(fs.open) --I can now open files in the root directory! local Handle = ParentEnv.fs.open("startup", "w") 
I've never been able to get beyond this step (Ok, I haven't tried much). It is very hard to prevent getfenv being able to at least get a hint of the parent environment and so be able to access the original file system (or whatever).

Thanks! I'm currently adding extra functions to the enviroment, and I added a arguments system :P/>
DeltaX #5
Posted 13 July 2014 - 05:20 PM
A small flaw.

The ROM can not be accessed in fake root.