Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab1e847d1c | |||
| 62a03bfe6b | |||
| e77a8b3636 | |||
| 6bb7f03a3e | |||
| 8798a2f4fe |
@@ -33,7 +33,6 @@ local host_str = syscall.getHost() or "Unknown"
|
|||||||
local cc_ver = host_str:match("ComputerCraft ([%d%.]+)") or host_str
|
local cc_ver = host_str:match("ComputerCraft ([%d%.]+)") or host_str
|
||||||
|
|
||||||
local info = {
|
local info = {
|
||||||
-- {label, value} label=nil means print value as-is (userhost / separator)
|
|
||||||
{nil, userhost},
|
{nil, userhost},
|
||||||
{nil, string.rep("-", #userhost)},
|
{nil, string.rep("-", #userhost)},
|
||||||
{"OS", syscall.version() or "Unknown"},
|
{"OS", syscall.version() or "Unknown"},
|
||||||
@@ -42,7 +41,7 @@ local info = {
|
|||||||
{"Uptime", formatUptime(syscall.getUptime() or 0)},
|
{"Uptime", formatUptime(syscall.getUptime() or 0)},
|
||||||
{"Tasks", tostring(#(syscall.getTasks() or {}))},
|
{"Tasks", tostring(#(syscall.getTasks() or {}))},
|
||||||
{"Shell", syscall.getEnviron("SHELL") or "Unknown"},
|
{"Shell", syscall.getEnviron("SHELL") or "Unknown"},
|
||||||
{"Terminal", "TTY1"},
|
{"Terminal", "tty1"},
|
||||||
{"UID", tostring(syscall.getuid())},
|
{"UID", tostring(syscall.getuid())},
|
||||||
{"Packages", "n/a (spm)"},
|
{"Packages", "n/a (spm)"},
|
||||||
}
|
}
|
||||||
@@ -71,15 +70,12 @@ local lines = math.max(#logo, #info)
|
|||||||
for i = 1, lines do
|
for i = 1, lines do
|
||||||
local logo_str = logo[i] or string.rep(" ", 36)
|
local logo_str = logo[i] or string.rep(" ", 36)
|
||||||
|
|
||||||
-- print logo segment in cyan
|
|
||||||
c(C_LOGO)
|
c(C_LOGO)
|
||||||
printInline(logo_str)
|
printInline(logo_str)
|
||||||
|
|
||||||
-- print separator pipe
|
|
||||||
c(C_LABEL)
|
c(C_LABEL)
|
||||||
printInline("| ")
|
printInline("| ")
|
||||||
|
|
||||||
-- print info segment
|
|
||||||
local row = info[i]
|
local row = info[i]
|
||||||
if row then
|
if row then
|
||||||
if row[1] == nil and i == 1 then
|
if row[1] == nil and i == 1 then
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--:Minify:--
|
--:Minify:--
|
||||||
syscall.open("/dev/tty/TTY1","r") --stdin (Device 0)
|
syscall.open("/dev/tty/tty1","r") --stdin (Device 0)
|
||||||
syscall.open("/dev/tty/TTY1","w") --stdout (Device 1)
|
syscall.open("/dev/tty/tty1","w") --stdout (Device 1)
|
||||||
syscall.open("/dev/null","w") --stderr (device 2)
|
syscall.open("/dev/null","w") --stderr (device 2)
|
||||||
|
|
||||||
local success, errorMsg = xpcall(function()
|
local success, errorMsg = xpcall(function()
|
||||||
@@ -957,8 +957,8 @@ local function runCommand(command)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local proc = syscall.spawn(function(...)
|
local proc = syscall.spawn(function(...)
|
||||||
syscall.open("/dev/tty/TTY1","r")
|
syscall.open("/dev/tty/tty1","r")
|
||||||
syscall.open("/dev/tty/TTY1","w")
|
syscall.open("/dev/tty/tty1","w")
|
||||||
syscall.open("/dev/null","w")
|
syscall.open("/dev/null","w")
|
||||||
local ok2, msg = pcall(program, ...)
|
local ok2, msg = pcall(program, ...)
|
||||||
if not ok2 then printError(progName, msg) end
|
if not ok2 then printError(progName, msg) end
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--:Minify:--
|
--:Minify:--
|
||||||
syscall.open("/dev/tty/TTY1","r")
|
syscall.open("/dev/tty/tty1","r")
|
||||||
syscall.open("/dev/tty/TTY1","w")
|
syscall.open("/dev/tty/tty1","w")
|
||||||
syscall.open("/dev/null","r")
|
syscall.open("/dev/null","r")
|
||||||
syscall.devctl(1,"clear")
|
syscall.devctl(1,"clear")
|
||||||
syscall.devctl(1,"sfgc",1)
|
syscall.devctl(1,"sfgc",1)
|
||||||
@@ -57,8 +57,8 @@ while true do
|
|||||||
printInline("> ")
|
printInline("> ")
|
||||||
end
|
end
|
||||||
proc = syscall.spawn(function(...)
|
proc = syscall.spawn(function(...)
|
||||||
syscall.open("/dev/tty/TTY1","r")
|
syscall.open("/dev/tty/tty1","r")
|
||||||
syscall.open("/dev/tty/TTY1","w")
|
syscall.open("/dev/tty/tty1","w")
|
||||||
syscall.open("/dev/null","w")
|
syscall.open("/dev/null","w")
|
||||||
program(...)
|
program(...)
|
||||||
end, path, nil, {table.unpack(split, 2)})
|
end, path, nil, {table.unpack(split, 2)})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
--:Minify:--
|
--:Minify:--
|
||||||
syscall.open("/dev/tty/TTY1", "r") --stdin (fd 0)
|
syscall.open("/dev/tty/tty1", "r") --stdin (fd 0)
|
||||||
syscall.open("/dev/tty/TTY1", "w") --stdout (fd 1)
|
syscall.open("/dev/tty/tty1", "w") --stdout (fd 1)
|
||||||
syscall.open("/dev/null", "w") --stderr (fd 2)
|
syscall.open("/dev/null", "w") --stderr (fd 2)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -184,9 +184,16 @@ end
|
|||||||
|
|
||||||
kernel.log("Gathering modules")
|
kernel.log("Gathering modules")
|
||||||
for _, i in ipairs(ifs.list("/lib/modules")) do
|
for _, i in ipairs(ifs.list("/lib/modules")) do
|
||||||
for _,v in ipairs(ifs.list("/lib/modules/"..i)) do
|
local modlist = ifs.list("/lib/modules/"..i)
|
||||||
local prior=tonumber(v:sub(1,2))
|
if not modlist then
|
||||||
modules[prior+1][#modules[prior+1]+1]="/lib/modules/"..i.."/"..v
|
kernel.log("WARNING: could not list /lib/modules/"..i.." (skipping)", "WARN", 8)
|
||||||
|
else
|
||||||
|
for _,v in ipairs(modlist) do
|
||||||
|
local prior=tonumber(v:sub(1,2))
|
||||||
|
if prior then
|
||||||
|
modules[prior+1][#modules[prior+1]+1]="/lib/modules/"..i.."/"..v
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,214 +0,0 @@
|
|||||||
-- :Minify:--
|
|
||||||
local kernel = ...
|
|
||||||
|
|
||||||
local P = kernel.vfs.P
|
|
||||||
local PERM = kernel.vfs.PERM
|
|
||||||
|
|
||||||
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
|
|
||||||
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
|
|
||||||
+ P.GROUP_R + P.GROUP_X
|
|
||||||
+ P.WORLD_R + P.WORLD_X
|
|
||||||
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
|
|
||||||
local RW____ = P.OWNER_R + P.OWNER_W
|
|
||||||
local RWXRWXRWX = PERM.RWXRWXRWX
|
|
||||||
local SUID_755 = PERM.SUID_755
|
|
||||||
|
|
||||||
local META_VERSION = 0x02
|
|
||||||
local rootDisk = kernel.disks["$"]
|
|
||||||
|
|
||||||
local function makeEntry(name, etype, owner, group, perms, cmeta)
|
|
||||||
cmeta = cmeta or ""
|
|
||||||
local plo = perms % 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
|
|
||||||
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
|
|
||||||
.. string.char(#cmeta) .. cmeta
|
|
||||||
end
|
|
||||||
|
|
||||||
local function writeMeta(dir, entries)
|
|
||||||
local diskDir = dir
|
|
||||||
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
|
|
||||||
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
|
|
||||||
|
|
||||||
local data = string.char(META_VERSION)
|
|
||||||
for _, e in ipairs(entries) do
|
|
||||||
data = data .. makeEntry(e[1], e[2] or 0x00, e[3], e[4], e[5], e[6])
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok, err = pcall(function()
|
|
||||||
local f = rootDisk:open(metaPath, "w")
|
|
||||||
f.write(data)
|
|
||||||
f.close()
|
|
||||||
end)
|
|
||||||
if not ok then
|
|
||||||
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local REG = 0x00
|
|
||||||
|
|
||||||
-- All known /bin entries with their permissions
|
|
||||||
local BIN_ENTRIES = {
|
|
||||||
{"cat", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"chattr", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"chgrp", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"chmod", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"chown", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"chroot", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"clear", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"echo", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"hfetch", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"help", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"hysh", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"hyshex", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"id", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"install", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"ln", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"login", REG, 0, 0, SUID_755 },
|
|
||||||
{"loimgcreate", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"looptest", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"losetup", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"ls", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"lsusers", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"lua", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"luaold", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"micro", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"mkdir", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"mount", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"passwd", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"ps", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"pwd", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"readlink", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"sed", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"socktest", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"spm", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"su", REG, 0, 0, SUID_755 },
|
|
||||||
{"sudo", REG, 0, 0, SUID_755 },
|
|
||||||
{"sysdump", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"umount", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"useradd", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"userdel", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"usermod", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"whoami", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"yes", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"startup", REG, 0, 0, RWX_RX_RX},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Merge entries: always ensure all known entries exist with correct permissions.
|
|
||||||
-- This handles both fresh installs and upgrades (adds missing entries, upgrades
|
|
||||||
-- the on-disk format to v2 by rewriting).
|
|
||||||
local function mergeMeta(dir, entries)
|
|
||||||
local diskDir = dir
|
|
||||||
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
|
|
||||||
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
|
|
||||||
|
|
||||||
-- Read existing meta (may be v1 or v2)
|
|
||||||
local existing = {}
|
|
||||||
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
|
|
||||||
if rok and rf then
|
|
||||||
local raw = rf.read(65535)
|
|
||||||
if rf.close then rf.close() end
|
|
||||||
-- Parse using the VFS parser (handles v0/v1/v2)
|
|
||||||
existing = kernel.vfs and kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw) or {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add any missing entries (don't overwrite existing customised perms)
|
|
||||||
for _, e in ipairs(entries) do
|
|
||||||
if not existing[e[1]] then
|
|
||||||
existing[e[1]] = {
|
|
||||||
etype = e[2] or 0x00,
|
|
||||||
owner = e[3] or 0,
|
|
||||||
group = e[4] or 0,
|
|
||||||
perms = e[5] or RWX_RX_RX,
|
|
||||||
cmeta = e[6] or "",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Write back as v2
|
|
||||||
local data = string.char(META_VERSION)
|
|
||||||
for name, m in pairs(existing) do
|
|
||||||
data = data .. makeEntry(name, m.etype or 0x00, m.owner or 0, m.group or 0, m.perms or RWX_RX_RX, m.cmeta or "")
|
|
||||||
end
|
|
||||||
|
|
||||||
local ok, err = pcall(function()
|
|
||||||
local f = rootDisk:open(metaPath, "w")
|
|
||||||
f.write(data)
|
|
||||||
f.close()
|
|
||||||
end)
|
|
||||||
if not ok then
|
|
||||||
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local freshInstall = not rootDisk:fileExists(".meta")
|
|
||||||
|
|
||||||
if freshInstall then
|
|
||||||
kernel.log("Seeding filesystem permissions...", "INFO")
|
|
||||||
|
|
||||||
-- / (only on fresh install — these dirs are stable)
|
|
||||||
writeMeta("/", {
|
|
||||||
{"bin", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"boot", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"dev", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"etc", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"home", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"lib", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"root", REG, 0, 0, RW____ },
|
|
||||||
{"sbin", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"tmp", REG, 0, 0, RWXRWXRWX},
|
|
||||||
{"usr", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"var", REG, 0, 0, RWX_RX_RX},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/bin/startup", {
|
|
||||||
{"test.lua", REG, 0, 0, RWX_RX_RX},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/etc", {
|
|
||||||
{"passwd", REG, 0, 0, RW_R_R},
|
|
||||||
{"shadow", REG, 0, 0, RW____},
|
|
||||||
{"pam.d", REG, 0, 0, RWX_RX_RX},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/etc/pam.d", {
|
|
||||||
{"secret", REG, 0, 0, RW____},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/sbin", {
|
|
||||||
{"init.lua", REG, 0, 0, RWX_RX_RX},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/boot", {
|
|
||||||
{"kernel.lua", REG, 0, 0, RW_R_R },
|
|
||||||
{"boot.cfg", REG, 0, 0, RW_R_R },
|
|
||||||
{"safeboot.cfg", REG, 0, 0, RW_R_R },
|
|
||||||
{"fstab", REG, 0, 0, RW_R_R },
|
|
||||||
{"initfs", REG, 0, 0, RW_R_R },
|
|
||||||
{"cct", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"oc", REG, 0, 0, RWX_RX_RX},
|
|
||||||
})
|
|
||||||
|
|
||||||
writeMeta("/lib", {
|
|
||||||
{"sys", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"modules", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"crypto", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"store", REG, 0, 0, RWX_RX_RX},
|
|
||||||
{"snip", REG, 0, 0, RW_R_R },
|
|
||||||
{"io", REG, 0, 0, RW_R_R },
|
|
||||||
{"bit32", REG, 0, 0, RW_R_R },
|
|
||||||
})
|
|
||||||
|
|
||||||
kernel.log("Filesystem permissions seeded.", "INFO")
|
|
||||||
else
|
|
||||||
kernel.log("Permissions already seeded, merging /bin updates...", "INFO")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Always merge /bin — adds missing entries and upgrades format to v2
|
|
||||||
mergeMeta("/bin", BIN_ENTRIES)
|
|
||||||
|
|
||||||
kernel.log("Permission module loaded.", "INFO")
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
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
|
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
-- :Minify:--
|
-- :Minify:--
|
||||||
|
local kernel = ...
|
||||||
|
kernel.allowGlobalOverwrites = true
|
||||||
|
|
||||||
function string.hasSuffix(str, suffix)
|
function string.hasSuffix(str, suffix)
|
||||||
return string.sub(str, #suffix + 1) == suffix
|
return string.sub(str, #suffix + 1) == suffix
|
||||||
end
|
end
|
||||||
@@ -68,30 +71,24 @@ end
|
|||||||
local function serialize(tbl, seen)
|
local function serialize(tbl, seen)
|
||||||
seen = seen or {}
|
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
|
if seen[tbl] then return '"[Circular Reference]"' end
|
||||||
|
|
||||||
-- Mark this table as seen
|
|
||||||
seen[tbl] = true
|
seen[tbl] = true
|
||||||
|
|
||||||
local output = "{"
|
local output = "{"
|
||||||
local first = true
|
local first = true
|
||||||
|
|
||||||
for i, v in pairs(tbl) do
|
for i, v in pairs(tbl) do
|
||||||
-- Handle comma placement more cleanly
|
|
||||||
if not first then output = output .. "," end
|
if not first then output = output .. "," end
|
||||||
first = false
|
first = false
|
||||||
|
|
||||||
-- Serialize Key
|
|
||||||
if type(i) == "string" then
|
if type(i) == "string" then
|
||||||
output = output .. "[\"" .. i .. "\"]="
|
output = output .. "[\"" .. i .. "\"]="
|
||||||
elseif type(i) == "number" then
|
elseif type(i) == "number" then
|
||||||
output = output .. "[" .. tostring(i) .. "]="
|
output = output .. "[" .. tostring(i) .. "]="
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Serialize Value
|
|
||||||
if type(v) == "table" then
|
if type(v) == "table" then
|
||||||
-- Pass the 'seen' table down to the recursive call
|
|
||||||
output = output .. serialize(v, seen)
|
output = output .. serialize(v, seen)
|
||||||
elseif type(v) == "string" then
|
elseif type(v) == "string" then
|
||||||
output = output .. "[=[" .. v .. "]=]"
|
output = output .. "[=[" .. v .. "]=]"
|
||||||
@@ -60,21 +60,18 @@ local function parseMetafile(raw)
|
|||||||
local etype, owner, group, perms, cmeta
|
local etype, owner, group, perms, cmeta
|
||||||
|
|
||||||
if version == 0x02 then
|
if version == 0x02 then
|
||||||
-- v2: etype(1) + owner(2) + group(2) + perms(2) = 7 bytes
|
|
||||||
if p + 6 > #raw then break end
|
if p + 6 > #raw then break end
|
||||||
etype = raw:byte(p); p = p + 1
|
etype = raw:byte(p); p = p + 1
|
||||||
owner = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
owner = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||||
group = 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
|
perms = raw:byte(p) + raw:byte(p+1) * 256; p = p + 2
|
||||||
elseif version == 0x01 then
|
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
|
||||||
@@ -114,25 +111,58 @@ local function makeMetafile(meta)
|
|||||||
return out
|
return out
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local SAFE_COMPONENT_PATTERN = "^[A-Za-z0-9_.+%-%@%(%)%[%]]+$"
|
||||||
|
|
||||||
local function normalizePath(path)
|
local function normalizePath(path)
|
||||||
local task = kernel.currentTask
|
local task = kernel.currentTask
|
||||||
local cwd = task.cwd or "/"
|
local cwd = task.cwd or "/"
|
||||||
if path:sub(1,1) ~= "/" then path = cwd .. "/" .. path end
|
|
||||||
local parts = {}
|
if path:sub(1, 1) ~= "/" then
|
||||||
for part in path:gmatch("[^/]+") do
|
path = cwd .. "/" .. path
|
||||||
if part == ".." then
|
end
|
||||||
if #parts > 0 then table.remove(parts) end
|
|
||||||
elseif part ~= "." and part ~= "" then
|
local stack = {}
|
||||||
table.insert(parts, part)
|
local i = 1
|
||||||
|
local len = #path
|
||||||
|
while i <= len do
|
||||||
|
local j = path:find("/", i, true)
|
||||||
|
local comp
|
||||||
|
if j then
|
||||||
|
comp = path:sub(i, j - 1)
|
||||||
|
i = j + 1
|
||||||
|
else
|
||||||
|
comp = path:sub(i)
|
||||||
|
i = len + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
comp = comp:match("^%s*(.-)%s*$")
|
||||||
|
|
||||||
|
if comp == "" or comp == "." then
|
||||||
|
elseif comp == ".." then
|
||||||
|
if #stack > 0 then
|
||||||
|
table.remove(stack)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
comp = comp:lower()
|
||||||
|
if not comp:match(SAFE_COMPONENT_PATTERN) then
|
||||||
|
error("EINVAL: illegal characters in path component: " .. comp, 2)
|
||||||
|
end
|
||||||
|
if comp == ".meta" then
|
||||||
|
error("EINVAL: reserved path component: " .. comp, 2)
|
||||||
|
end
|
||||||
|
table.insert(stack, comp)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local result = "/" .. table.concat(parts, "/")
|
|
||||||
|
local result = "/" .. table.concat(stack, "/")
|
||||||
|
|
||||||
local root = task and task.root
|
local root = task and task.root
|
||||||
if root and root ~= "/" then
|
if root and root ~= "/" then
|
||||||
if result ~= root and result:sub(1, #root + 1) ~= root .. "/" then
|
if result ~= root and result:sub(1, #root + 1) ~= root .. "/" then
|
||||||
result = root
|
result = root
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -164,11 +194,10 @@ local function resolveMount(normalPath)
|
|||||||
return vfs.disks[mountId], diskPath
|
return vfs.disks[mountId], diskPath
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Expose parser for use by other modules (e.g. permissions seeder)
|
|
||||||
vfs._parseMetafile = parseMetafile
|
vfs._parseMetafile = parseMetafile
|
||||||
|
|
||||||
local function readMetaEntry(disk, parentDiskPath, filename)
|
local function readMetaEntry(disk, parentDiskPath, filename)
|
||||||
if filename == ".meta" then error("Cannot open metafile") end
|
if filename == ".meta" then error("EACCES: Cannot open metafile") end
|
||||||
local mp
|
local mp
|
||||||
if parentDiskPath == "/" then
|
if parentDiskPath == "/" then
|
||||||
mp = ".meta"
|
mp = ".meta"
|
||||||
@@ -181,7 +210,6 @@ local function readMetaEntry(disk, parentDiskPath, filename)
|
|||||||
local raw = f.read(65535)
|
local raw = f.read(65535)
|
||||||
if f.close then f.close() end
|
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
|
if raw and #raw > 0 and raw:byte(1) ~= META_VERSION then
|
||||||
local upgraded = makeMetafile(parseMetafile(raw))
|
local upgraded = makeMetafile(parseMetafile(raw))
|
||||||
local wok, wf = pcall(function() return disk:open(mp, "w") end)
|
local wok, wf = pcall(function() return disk:open(mp, "w") end)
|
||||||
@@ -440,7 +468,6 @@ function vfs.open(path, mode)
|
|||||||
if type(handle) ~= "table" then error("ENFILE") end
|
if type(handle) ~= "table" then error("ENFILE") end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If this is a newly created file, stamp it with the creating user's ownership
|
|
||||||
if isNew then
|
if isNew then
|
||||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||||
local egid = (task and task.gid) or 0
|
local egid = (task and task.gid) or 0
|
||||||
@@ -629,7 +656,6 @@ function vfs.mkdir(path)
|
|||||||
checkperms(parentMeta, "w")
|
checkperms(parentMeta, "w")
|
||||||
local disk, diskPath = resolvePath(path)
|
local disk, diskPath = resolvePath(path)
|
||||||
disk:makeDirectory(diskPath)
|
disk:makeDirectory(diskPath)
|
||||||
-- Stamp the new directory with the creating user's ownership
|
|
||||||
local task = kernel.currentTask
|
local task = kernel.currentTask
|
||||||
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
local euid = (task and (task.euid or task.uid)) or kernel.uid
|
||||||
local egid = (task and task.gid) or 0
|
local egid = (task and task.gid) or 0
|
||||||
@@ -385,11 +385,11 @@ kernel.processes.cctmond = function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
newtty(apis.term, "TTY1", fifo.pop)
|
newtty(apis.term, "tty1", fifo.pop)
|
||||||
|
|
||||||
|
|
||||||
for i,v in ipairs({peripheral.find("monitor")}) do
|
for i,v in ipairs({peripheral.find("monitor")}) do
|
||||||
v.setTextScale(.5)
|
v.setTextScale(.5)
|
||||||
v.write("Initializing...")
|
v.write("Initializing...")
|
||||||
newtty(v,"TTY"..tostring(i+1),function () end)
|
newtty(v,"tty"..tostring(i+1),function () end)
|
||||||
end
|
end
|
||||||
@@ -21,7 +21,7 @@ local function readonly(tbl)
|
|||||||
error("Attempt to modify global variable '" .. k .. "'", 2)
|
error("Attempt to modify global variable '" .. k .. "'", 2)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
__pairs = function()
|
__pairs = function(self)
|
||||||
local function iter(_, key)
|
local function iter(_, key)
|
||||||
local nextKey, value = next(tbl, key)
|
local nextKey, value = next(tbl, key)
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
@@ -29,7 +29,7 @@ local function readonly(tbl)
|
|||||||
end
|
end
|
||||||
return nextKey, value
|
return nextKey, value
|
||||||
end
|
end
|
||||||
return iter, tbl, nil
|
return iter, self, nil
|
||||||
end,
|
end,
|
||||||
|
|
||||||
__ipairs = function()
|
__ipairs = function()
|
||||||
@@ -50,10 +50,8 @@ local function readonly(tbl)
|
|||||||
__metatable = false
|
__metatable = false
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
--local origLoad = load
|
local origLoad = load
|
||||||
|
|
||||||
kernel._U = readonly(kernel._G)
|
kernel._U = readonly(kernel._G)
|
||||||
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._U.load = function(a,b,c,d) return origLoad(a,b,c,d or kernel._U) end
|
||||||
kernel.allowGlobalOverwrites = false
|
|
||||||
@@ -5,6 +5,8 @@ local sys = {}
|
|||||||
local nextpid = 2
|
local nextpid = 2
|
||||||
kernel.exitMain = false
|
kernel.exitMain = false
|
||||||
|
|
||||||
|
local resumeWithTimeout = coroutine.resumeWithTimeout
|
||||||
|
|
||||||
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
|
||||||
end
|
end
|
||||||
@@ -206,10 +208,14 @@ function sys.kill(pid)
|
|||||||
return false, "Task does not exist"
|
return false, "Task does not exist"
|
||||||
elseif task.status == "Z" then
|
elseif task.status == "Z" then
|
||||||
return false, "Task is already dead"
|
return false, "Task is already dead"
|
||||||
else
|
|
||||||
task.status = "Z"
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
local caller = kernel.currentTask
|
||||||
|
local ceuid = caller and (caller.euid or caller.uid) or kernel.uid
|
||||||
|
if ceuid ~= 0 and task.uid ~= (caller and caller.uid or kernel.uid) then
|
||||||
|
return false, "EPERM"
|
||||||
|
end
|
||||||
|
task.status = "Z"
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function sys.stop(pid)
|
function sys.stop(pid)
|
||||||
@@ -352,7 +358,7 @@ function kernel.main()
|
|||||||
if task.sigq and #task.sigq ~= 0 and task.sigh then
|
if task.sigq and #task.sigq ~= 0 and task.sigh then
|
||||||
local coro = coroutine.create(task.sigh)
|
local coro = coroutine.create(task.sigh)
|
||||||
if kernel.config.preempt then
|
if kernel.config.preempt then
|
||||||
coroutine.resumeWithTimeout(coro, task.timeSlice, table.remove(task.sigq, 1))
|
resumeWithTimeout(coro, task.timeSlice, table.remove(task.sigq, 1))
|
||||||
else
|
else
|
||||||
coroutine.resume(coro, table.remove(task.sigq, 1))
|
coroutine.resume(coro, table.remove(task.sigq, 1))
|
||||||
end
|
end
|
||||||
@@ -363,7 +369,7 @@ function kernel.main()
|
|||||||
local ret
|
local ret
|
||||||
|
|
||||||
if kernel.config.preempt then
|
if kernel.config.preempt then
|
||||||
ret = { coroutine.resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
|
ret = { resumeWithTimeout(task.coro, task.timeSlice, table.unpack(task.syscallReturn)) }
|
||||||
else
|
else
|
||||||
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
|
ret = { coroutine.resume(task.coro, table.unpack(task.syscallReturn)) }
|
||||||
end
|
end
|
||||||
233
Src/Hyperion-kernel/lib/modules/hyperion/92_permissions.kmod
Normal file
233
Src/Hyperion-kernel/lib/modules/hyperion/92_permissions.kmod
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
-- :Minify:--
|
||||||
|
local kernel = ...
|
||||||
|
|
||||||
|
local P = kernel.vfs.P
|
||||||
|
local PERM = kernel.vfs.PERM
|
||||||
|
|
||||||
|
local RW_R_R = P.OWNER_R + P.OWNER_W + P.GROUP_R + P.WORLD_R
|
||||||
|
local RWX_RX_RX = P.OWNER_R + P.OWNER_W + P.OWNER_X
|
||||||
|
+ P.GROUP_R + P.GROUP_X
|
||||||
|
+ P.WORLD_R + P.WORLD_X
|
||||||
|
local RW_R__ = P.OWNER_R + P.OWNER_W + P.GROUP_R
|
||||||
|
local RW____ = P.OWNER_R + P.OWNER_W
|
||||||
|
local RWXRWXRWX = PERM.RWXRWXRWX
|
||||||
|
local SUID_755 = PERM.SUID_755
|
||||||
|
|
||||||
|
local META_VERSION = 0x02
|
||||||
|
local rootDisk = kernel.disks["$"]
|
||||||
|
|
||||||
|
local function makeEntry(name, etype, owner, group, perms, cmeta)
|
||||||
|
cmeta = cmeta or ""
|
||||||
|
local plo = perms % 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
|
||||||
|
.. string.char(etype, olo, ohi, glo, ghi, plo, phi)
|
||||||
|
.. string.char(#cmeta) .. cmeta
|
||||||
|
end
|
||||||
|
|
||||||
|
local REG = 0x00
|
||||||
|
|
||||||
|
local function mergeMeta(dir, entries)
|
||||||
|
local diskDir = dir
|
||||||
|
if diskDir:sub(1,1) == "/" then diskDir = diskDir:sub(2) end
|
||||||
|
local metaPath = (diskDir == "" and ".meta" or diskDir .. "/.meta")
|
||||||
|
|
||||||
|
local existing = {}
|
||||||
|
local rok, rf = pcall(function() return rootDisk:open(metaPath, "r") end)
|
||||||
|
if rok and rf then
|
||||||
|
local raw = rf.read(65535)
|
||||||
|
if rf.close then rf.close() end
|
||||||
|
existing = (kernel.vfs._parseMetafile and kernel.vfs._parseMetafile(raw)) or {}
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, e in ipairs(entries) do
|
||||||
|
local name = e[1]
|
||||||
|
local etype = e[2] or REG
|
||||||
|
local owner = e[3] or 0
|
||||||
|
local group = e[4] or 0
|
||||||
|
local perms = e[5] or RWX_RX_RX
|
||||||
|
local cmeta = e[6] or ""
|
||||||
|
existing[name] = {
|
||||||
|
etype = etype,
|
||||||
|
owner = owner,
|
||||||
|
group = group,
|
||||||
|
perms = perms,
|
||||||
|
cmeta = cmeta,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local data = string.char(META_VERSION)
|
||||||
|
for name, m in pairs(existing) do
|
||||||
|
data = data .. makeEntry(
|
||||||
|
name,
|
||||||
|
m.etype or REG,
|
||||||
|
m.owner or 0,
|
||||||
|
m.group or 0,
|
||||||
|
m.perms or RWX_RX_RX,
|
||||||
|
m.cmeta or ""
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
local ok, err = pcall(function()
|
||||||
|
local f = rootDisk:open(metaPath, "w")
|
||||||
|
f.write(data)
|
||||||
|
f.close()
|
||||||
|
end)
|
||||||
|
if not ok then
|
||||||
|
kernel.log("permissions: failed to write " .. metaPath .. ": " .. tostring(err), "WARN", 8)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
kernel.log("Seeding filesystem permissions...", "INFO")
|
||||||
|
|
||||||
|
mergeMeta("/", {
|
||||||
|
{"bin", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"boot", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"dev", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"etc", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"home", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"lib", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"root", REG, 0, 0, RW____ },
|
||||||
|
{"sbin", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"tmp", REG, 0, 0, RWXRWXRWX},
|
||||||
|
{"usr", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"var", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/boot", {
|
||||||
|
{"kernel.lua", REG, 0, 0, RW_R_R },
|
||||||
|
{"boot.cfg", REG, 0, 0, RW_R_R },
|
||||||
|
{"safeboot.cfg", REG, 0, 0, RW_R_R },
|
||||||
|
{"fstab", REG, 0, 0, RW_R_R },
|
||||||
|
{"initfs", REG, 0, 0, RW_R_R },
|
||||||
|
{"cct", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"oc", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/boot/cct", {
|
||||||
|
{"boot.lua", REG, 0, 0, RW_R_R},
|
||||||
|
{"initdisks", REG, 0, 0, RW_R_R},
|
||||||
|
{"eeprom", REG, 0, 0, RW_R_R},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/boot/oc", {
|
||||||
|
{"boot.lua", REG, 0, 0, RW_R_R},
|
||||||
|
{"initfs.lua",REG, 0, 0, RW_R_R},
|
||||||
|
{"eeprom", REG, 0, 0, RW_R_R},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/sbin", {
|
||||||
|
{"init.lua", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/bin", {
|
||||||
|
{"cat", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"chattr", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"chgrp", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"chmod", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"chown", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"chroot", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"clear", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"echo", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"hfetch", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"help", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"hysh", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"hyshex", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"id", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"install", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"ln", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"login", REG, 0, 0, SUID_755 },
|
||||||
|
{"loimgcreate", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"looptest", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"losetup", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"ls", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"lsusers", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"lua", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"luaold", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"micro", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"mkdir", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"mount", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"passwd", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"ps", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"pwd", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"readlink", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"sed", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"socktest", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"spm", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"startup", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"su", REG, 0, 0, SUID_755 },
|
||||||
|
{"sudo", REG, 0, 0, SUID_755 },
|
||||||
|
{"sysdump", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"umount", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"useradd", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"userdel", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"usermod", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"whoami", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"yes", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/bin/startup", {
|
||||||
|
{"test.lua", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/lib", {
|
||||||
|
{"sys", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"modules", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"crypto", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"store", REG, 0, 0, RWX_RX_RX},
|
||||||
|
{"snip", REG, 0, 0, RW_R_R },
|
||||||
|
{"io", REG, 0, 0, RW_R_R },
|
||||||
|
{"bit32", REG, 0, 0, RW_R_R },
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/lib/sys", {
|
||||||
|
{"fs", REG, 0, 0, RW_R_R},
|
||||||
|
{"hpv", REG, 0, 0, RW_R_R},
|
||||||
|
{"ipc", REG, 0, 0, RW_R_R},
|
||||||
|
{"term", REG, 0, 0, RW_R_R},
|
||||||
|
{"init", REG, 0, 0, RW_R_R},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/lib/modules", {
|
||||||
|
{"hyperion", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/lib/modules/hyperion", {
|
||||||
|
{"01_stdlib.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"10_vfs.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"11_require.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"12_devfs.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"12_tmpfs.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"13_loopdev.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"14_keventd.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"19_fstab.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"20_signals.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"20_socket.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"26_tty.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"30_userspace.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"40_auth.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"45_hypervisor.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"47_dbg.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"50_gpio.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"70_stdlibadv.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"90_init.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"91_login.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"92_permissions.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
{"99_final.kmod", REG, 0, 0, RW_R_R},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/etc", {
|
||||||
|
{"passwd", REG, 0, 0, RW_R_R },
|
||||||
|
{"shadow", REG, 0, 0, RW____ },
|
||||||
|
{"pam.d", REG, 0, 0, RWX_RX_RX},
|
||||||
|
})
|
||||||
|
|
||||||
|
mergeMeta("/etc/pam.d", {
|
||||||
|
{"secret", REG, 0, 0, RW____},
|
||||||
|
})
|
||||||
|
|
||||||
|
kernel.log("Filesystem permissions seeded.", "INFO")
|
||||||
2
Src/Hyperion-kernel/lib/modules/hyperion/99_final.kmod
Normal file
2
Src/Hyperion-kernel/lib/modules/hyperion/99_final.kmod
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
local kernel = ...
|
||||||
|
kernel.allowGlobalOverwrites = false
|
||||||
4
build.py
4
build.py
@@ -203,7 +203,7 @@ def _make_firstboot_kmod(users):
|
|||||||
|
|
||||||
lines.append("do")
|
lines.append("do")
|
||||||
lines.append(" local ok, err = pcall(function()")
|
lines.append(" local ok, err = pcall(function()")
|
||||||
lines.append(" kernel.vfs.remove('/lib/modules/Hyperion/50_firstboot_users.kmod')")
|
lines.append(" kernel.vfs.remove('/lib/modules/hyperion/50_firstboot_users.kmod')")
|
||||||
lines.append(" end)")
|
lines.append(" end)")
|
||||||
lines.append(" if not ok then")
|
lines.append(" if not ok then")
|
||||||
lines.append(" kernel.log('FIRSTBOOT: could not self-delete: ' .. tostring(err), 'WARN')")
|
lines.append(" kernel.log('FIRSTBOOT: could not self-delete: ' .. tostring(err), 'WARN')")
|
||||||
@@ -215,7 +215,7 @@ def _make_firstboot_kmod(users):
|
|||||||
|
|
||||||
def inject_makeusers(users, arch):
|
def inject_makeusers(users, arch):
|
||||||
base = BUILD_ROOT / "$" if arch else BUILD_ROOT
|
base = BUILD_ROOT / "$" if arch else BUILD_ROOT
|
||||||
kmod_path = base / "lib" / "modules" / "Hyperion" / "50_firstboot_users.kmod"
|
kmod_path = base / "lib" / "modules" / "hyperion" / "50_firstboot_users.kmod"
|
||||||
kmod_path.parent.mkdir(parents=True, exist_ok=True)
|
kmod_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
kmod_path.write_text(_make_firstboot_kmod(users), encoding="utf-8")
|
kmod_path.write_text(_make_firstboot_kmod(users), encoding="utf-8")
|
||||||
print(" Wrote first-boot user setup -> " + str(kmod_path.relative_to(BUILD_ROOT)))
|
print(" Wrote first-boot user setup -> " + str(kmod_path.relative_to(BUILD_ROOT)))
|
||||||
|
|||||||
Reference in New Issue
Block a user