forked from Hyperion/HyperionOS
2 potential vulnerability fixes
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
-- :Minify:--
|
||||
local kernel = ...
|
||||
kernel.allowGlobalOverwrites = true
|
||||
|
||||
function string.hasSuffix(str, suffix)
|
||||
return string.sub(str, #suffix + 1) == suffix
|
||||
end
|
||||
@@ -68,30 +71,24 @@ end
|
||||
local function serialize(tbl, seen)
|
||||
seen = seen or {}
|
||||
|
||||
-- If we've seen this table before, return a placeholder to prevent infinite loops
|
||||
if seen[tbl] then return '"[Circular Reference]"' end
|
||||
|
||||
-- Mark this table as seen
|
||||
seen[tbl] = true
|
||||
|
||||
local output = "{"
|
||||
local first = true
|
||||
|
||||
for i, v in pairs(tbl) do
|
||||
-- Handle comma placement more cleanly
|
||||
if not first then output = output .. "," end
|
||||
first = false
|
||||
|
||||
-- Serialize Key
|
||||
if type(i) == "string" then
|
||||
output = output .. "[\"" .. i .. "\"]="
|
||||
elseif type(i) == "number" then
|
||||
output = output .. "[" .. tostring(i) .. "]="
|
||||
end
|
||||
|
||||
-- Serialize Value
|
||||
if type(v) == "table" then
|
||||
-- Pass the 'seen' table down to the recursive call
|
||||
output = output .. serialize(v, seen)
|
||||
elseif type(v) == "string" then
|
||||
output = output .. "[=[" .. v .. "]=]"
|
||||
|
||||
@@ -60,21 +60,18 @@ local function parseMetafile(raw)
|
||||
local etype, owner, group, perms, cmeta
|
||||
|
||||
if version == 0x02 then
|
||||
-- v2: etype(1) + owner(2) + group(2) + perms(2) = 7 bytes
|
||||
if p + 6 > #raw then break end
|
||||
etype = raw:byte(p); p = p + 1
|
||||
owner = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
group = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
perms = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
elseif version == 0x01 then
|
||||
-- v1: etype(1) + owner(1) + group(1) + perms(2) = 5 bytes
|
||||
if p + 4 > #raw then break end
|
||||
etype = raw:byte(p); p = p + 1
|
||||
owner = raw:byte(p); p = p + 1
|
||||
group = raw:byte(p); p = p + 1
|
||||
perms = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||
else
|
||||
-- v0: owner(1) + group(1) + perms(1) = 3 bytes
|
||||
if p + 2 > #raw then break end
|
||||
etype = 0x00
|
||||
owner = raw:byte(p); p = p + 1
|
||||
@@ -114,6 +111,22 @@ local function makeMetafile(meta)
|
||||
return out
|
||||
end
|
||||
|
||||
local function validateComponent(part)
|
||||
if part == "" then
|
||||
error("EINVAL: empty path component", 2)
|
||||
end
|
||||
if part:sub(1, 2) == ".." then
|
||||
error("EINVAL: illegal path component '" .. part .. "'", 2)
|
||||
end
|
||||
if part:find("\0", 1, true) then
|
||||
error("EINVAL: null byte in path component", 2)
|
||||
end
|
||||
if part:find("/", 1, true) then
|
||||
error("EINVAL: slash in path component", 2)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function normalizePath(path)
|
||||
local task = kernel.currentTask
|
||||
local cwd = task.cwd or "/"
|
||||
@@ -122,7 +135,9 @@ local function normalizePath(path)
|
||||
for part in path:gmatch("[^/]+") do
|
||||
if part == ".." then
|
||||
if #parts > 0 then table.remove(parts) end
|
||||
elseif part ~= "." and part ~= "" then
|
||||
elseif part == "." or part == "" then
|
||||
else
|
||||
validateComponent(part)
|
||||
table.insert(parts, part)
|
||||
end
|
||||
end
|
||||
@@ -164,7 +179,6 @@ local function resolveMount(normalPath)
|
||||
return vfs.disks[mountId], diskPath
|
||||
end
|
||||
|
||||
-- Expose parser for use by other modules (e.g. permissions seeder)
|
||||
vfs._parseMetafile = parseMetafile
|
||||
|
||||
local function readMetaEntry(disk, parentDiskPath, filename)
|
||||
@@ -181,7 +195,6 @@ local function readMetaEntry(disk, parentDiskPath, filename)
|
||||
local raw = f.read(65535)
|
||||
if f.close then f.close() end
|
||||
|
||||
-- Auto-upgrade: if this .meta file is not v2, rewrite it as v2 now
|
||||
if raw and #raw > 0 and raw:byte(1) ~= META_VERSION then
|
||||
local upgraded = makeMetafile(parseMetafile(raw))
|
||||
local wok, wf = pcall(function() return disk:open(mp, "w") end)
|
||||
@@ -440,7 +453,6 @@ function vfs.open(path, mode)
|
||||
if type(handle) ~= "table" then error("ENFILE") end
|
||||
end
|
||||
|
||||
-- If this is a newly created file, stamp it with the creating user's ownership
|
||||
if isNew then
|
||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||
local egid = (task and task.gid) or 0
|
||||
@@ -629,7 +641,6 @@ function vfs.mkdir(path)
|
||||
checkperms(parentMeta, "w")
|
||||
local disk, diskPath = resolvePath(path)
|
||||
disk:makeDirectory(diskPath)
|
||||
-- Stamp the new directory with the creating user's ownership
|
||||
local task = kernel.currentTask
|
||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||
local egid = (task and task.gid) or 0
|
||||
|
||||
@@ -50,10 +50,8 @@ local function readonly(tbl)
|
||||
__metatable = false
|
||||
})
|
||||
end
|
||||
--local origLoad = load
|
||||
local origLoad = load
|
||||
|
||||
kernel._U = readonly(kernel._G)
|
||||
kernel.allowGlobalOverwrites = true
|
||||
kernel._U._G = kernel._U
|
||||
--kernel._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end
|
||||
kernel.allowGlobalOverwrites = false
|
||||
kernel._U.load = function(a, b, c, d) return origLoad(a, b, c, d or kernel._U) end
|
||||
@@ -1,5 +1,2 @@
|
||||
local args = {...}
|
||||
local kernel = args[1]
|
||||
|
||||
local origLoad = load
|
||||
--kernel._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end
|
||||
local kernel = ...
|
||||
kernel.allowGlobalOverwrites = false
|
||||
Reference in New Issue
Block a user