load vuln fixed, sudo fixed

This commit is contained in:
2026-02-23 22:43:12 -06:00
parent 6694711423
commit b015d5880a
6 changed files with 50 additions and 25 deletions

View File

@@ -31,7 +31,7 @@ for j = i + 1, #cmdArgs do restArgs[#restArgs + 1] = cmdArgs[j] end
local currentUid = syscall.getuid() local currentUid = syscall.getuid()
local currentUser = syscall.getUsername(currentUid) or tostring(currentUid) local currentUser = syscall.getUsername(currentUid) or tostring(currentUid)
local targetUid = syscall.getuid(targetUser) local targetUid = syscall.getuidbyname(targetUser)
if not targetUid then if not targetUid then
print("sudo: user '" .. targetUser .. "' does not exist") print("sudo: user '" .. targetUser .. "' does not exist")
syscall.exit(1) syscall.exit(1)
@@ -39,7 +39,7 @@ if not targetUid then
end end
if currentUid ~= 0 then if currentUid ~= 0 then
printInline("[sudo] password for " .. currentUser .. ": ") printInline("[sudo] password for root: ")
local pw = "" local pw = ""
while true do while true do
local ch = syscall.read(0) local ch = syscall.read(0)
@@ -55,7 +55,7 @@ if currentUid ~= 0 then
end end
end end
local ok, err = syscall.elevate(currentUser, pw) local ok, err = syscall.elevate("root", pw)
if not ok then if not ok then
sleep(1) sleep(1)
print("sudo: Authentication failure") print("sudo: Authentication failure")
@@ -63,7 +63,7 @@ if currentUid ~= 0 then
return return
end end
if targetUid ~= 0 then if targetUid ~= currentUid then
syscall.setuid(targetUid) syscall.setuid(targetUid)
end end
else else

View File

@@ -37,7 +37,7 @@ function peripheral.isPresent(name)
end end
function peripheral.getType(peripheral) function peripheral.getType(peripheral)
if type(peripheral) == "string" then -- Peripheral name passed if type(peripheral) == "string" then
if native.isPresent(peripheral) then if native.isPresent(peripheral) then
return native.getType(peripheral) return native.getType(peripheral)
end end
@@ -58,7 +58,7 @@ function peripheral.getType(peripheral)
end end
function peripheral.hasType(peripheral, peripheral_type) function peripheral.hasType(peripheral, peripheral_type)
if type(peripheral) == "string" then -- Peripheral name passed if type(peripheral) == "string" then
if native.isPresent(peripheral) then if native.isPresent(peripheral) then
return native.hasType(peripheral, peripheral_type) return native.hasType(peripheral, peripheral_type)
end end

View File

@@ -5,14 +5,14 @@ kernel.vfs = vfs
vfs.mounts = {["$"] = "/"} vfs.mounts = {["$"] = "/"}
vfs.disks = kernel.disks vfs.disks = kernel.disks
-- Metafile format (version 1) -- Metafile format (version 2)
-- File header: 1 byte = version (0x01) -- File header: 1 byte = version (0x02)
-- Per-entry: -- Per-entry:
-- 1 byte = name length -- 1 byte = name length
-- N bytes = name -- N bytes = name
-- 1 byte = entry type (0x00 = regular, 0x01 = symlink) -- 1 byte = entry type (0x00 = regular, 0x01 = symlink)
-- 1 byte = owner uid -- 2 bytes = owner uid (little-endian uint16)
-- 1 byte = group gid -- 2 bytes = group gid (little-endian uint16)
-- 2 bytes = perms (little-endian uint16) -- 2 bytes = perms (little-endian uint16)
-- bit 0 = world-write bit 1 = world-read -- bit 0 = world-write bit 1 = world-read
-- bit 2 = group-write bit 3 = group-read -- bit 2 = group-write bit 3 = group-read
@@ -24,12 +24,16 @@ vfs.disks = kernel.disks
-- 1 byte = cmeta length -- 1 byte = cmeta length
-- N bytes = cmeta (for symlinks: the link target path) -- N bytes = cmeta (for symlinks: the link target path)
-- --
-- Version 1:
-- 1 byte name len, N bytes name, 1 byte etype, 1 byte owner,
-- 1 byte group, 2 bytes perms (little-endian), 1 byte cmeta len, N bytes cmeta
--
-- Version 0: -- Version 0:
-- No file header. Per-entry: -- No file header. Per-entry:
-- 1 byte name len, N bytes name, 1 byte owner, 1 byte group, -- 1 byte name len, N bytes name, 1 byte owner, 1 byte group,
-- 1 byte perms (low 7 bits only), 1 byte cmeta len, N bytes cmeta -- 1 byte perms (low 7 bits only), 1 byte cmeta len, N bytes cmeta
local META_VERSION = 0x01 local META_VERSION = 0x02
local function bit_is_set(num, bit) local function bit_is_set(num, bit)
return math.floor(num / (2 ^ bit)) % 2 == 1 return math.floor(num / (2 ^ bit)) % 2 == 1
@@ -41,8 +45,9 @@ local function parseMetafile(raw)
local p = 1 local p = 1
local version = 0 local version = 0
if raw:byte(1) == META_VERSION then local firstByte = raw:byte(1)
version = META_VERSION if firstByte == 0x02 or firstByte == 0x01 then
version = firstByte
p = 2 p = 2
end end
@@ -54,13 +59,22 @@ local function parseMetafile(raw)
local etype, owner, group, perms, cmeta local etype, owner, group, perms, cmeta
if version == META_VERSION then 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 if p + 4 > #raw then break end
etype = raw:byte(p); p = p + 1 etype = raw:byte(p); p = p + 1
owner = raw:byte(p); p = p + 1 owner = raw:byte(p); p = p + 1
group = 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 perms = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
else else
-- v0: owner(1) + group(1) + perms(1) = 3 bytes
if p + 2 > #raw then break end if p + 2 > #raw then break end
etype = 0x00 etype = 0x00
owner = raw:byte(p); p = p + 1 owner = raw:byte(p); p = p + 1
@@ -85,12 +99,16 @@ end
local function makeMetafile(meta) local function makeMetafile(meta)
local out = string.char(META_VERSION) local out = string.char(META_VERSION)
for name, m in pairs(meta) do for name, m in pairs(meta) do
local plo = m.perms % 256 local plo = m.perms % 256
local phi = math.floor(m.perms / 256) % 256 local phi = math.floor(m.perms / 256) % 256
local olo = (m.owner or 0) % 256
local ohi = math.floor((m.owner or 0) / 256) % 256
local glo = (m.group or 0) % 256
local ghi = math.floor((m.group or 0) / 256) % 256
out = out out = out
.. string.char(#name) .. name .. string.char(#name) .. name
.. string.char(m.etype or 0x00) .. string.char(m.etype or 0x00)
.. string.char(m.owner, m.group, plo, phi) .. string.char(olo, ohi, glo, ghi, plo, phi)
.. string.char(#m.cmeta) .. m.cmeta .. string.char(#m.cmeta) .. m.cmeta
end end
return out return out

View File

@@ -3,6 +3,7 @@ local args = {...}
local kernel = args[1] local kernel = args[1]
kernel._G = _G kernel._G = _G
local function readonly(tbl) local function readonly(tbl)
return setmetatable({}, { return setmetatable({}, {
__index = function(_, key) __index = function(_, key)
@@ -49,8 +50,10 @@ local function readonly(tbl)
__metatable = false __metatable = false
}) })
end end
local origLoad = load
kernel._U = readonly(kernel._G) kernel._U = readonly(kernel._G)
kernel.allowGlobalOverwrites = true kernel.allowGlobalOverwrites = true
kernel._U._G = kernel._U 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.allowGlobalOverwrites = false

View File

@@ -591,13 +591,13 @@ function auth.elevate(targetUsername, password)
local task = kernel.currentTask local task = kernel.currentTask
local prevUid = task.uid local prevUid = task.uid
task.uid = uid task.uid = 0
task.euid = uid task.euid = 0
task.gid = tonumber(entry[2]) or uid task.gid = 0
task.egid = tonumber(entry[2]) or uid task.egid = 0
kernel.uid = uid kernel.uid = 0
kernel.log("AUTH: elevate uid=" .. tostring(prevUid) .. " -> " .. tostring(uid) .. " (" .. targetUsername .. ")") kernel.log("AUTH: elevate uid=" .. tostring(prevUid) .. " -> 0 (via " .. targetUsername .. ")")
return true, uid return true, uid
end end

View File

@@ -13,15 +13,19 @@ local RW____ = P.OWNER_R + P.OWNER_W
local RWXRWXRWX = PERM.RWXRWXRWX local RWXRWXRWX = PERM.RWXRWXRWX
local SUID_755 = PERM.SUID_755 local SUID_755 = PERM.SUID_755
local META_VERSION = 0x01 local META_VERSION = 0x02
local rootDisk = kernel.disks["$"] local rootDisk = kernel.disks["$"]
local function makeEntry(name, etype, owner, group, perms, cmeta) local function makeEntry(name, etype, owner, group, perms, cmeta)
cmeta = cmeta or "" cmeta = cmeta or ""
local plo = perms % 256 local plo = perms % 256
local phi = math.floor(perms / 256) % 256 local phi = math.floor(perms / 256) % 256
local olo = (owner or 0) % 256
local ohi = math.floor((owner or 0) / 256) % 256
local glo = (group or 0) % 256
local ghi = math.floor((group or 0) / 256) % 256
return string.char(#name) .. name return string.char(#name) .. name
.. string.char(etype, owner, group, plo, phi) .. string.char(etype, olo, ohi, glo, ghi, plo, phi)
.. string.char(#cmeta) .. cmeta .. string.char(#cmeta) .. cmeta
end end