Last active
November 27, 2018 19:31
-
-
Save ducktype/fe1d67ed5ad1e79cc6f058566ee8f680 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//NOTE: we need to change this cast in: zig/lib/zig/std/os/linux/index.twig | |
//pub fn geteuid() u32 { | |
// return @intCast(u32,syscall0(SYS_geteuid)); | |
//} | |
// | |
//pub fn getegid() u32 { | |
// return @intCast(u32,syscall0(SYS_getegid)); | |
//} | |
//pub fn mount(special: [*]const u8, dir: [*]const u8, fstype: ?[*]const u8, flags: u32, data: usize) usize { | |
// return syscall5(SYS_mount, @ptrToInt(special), @ptrToInt(dir), @ptrToInt(fstype), flags, data); | |
//} | |
//TODO: avoid Dir.scan multiple times | |
const std = @import("std"); | |
const allocator = std.debug.global_allocator; | |
//const allocator = std.heap.c_allocator; //requires C compiler installed to build? | |
pub fn main() !void { | |
//var args = std.os.args(); | |
var stdout = &(try std.io.getStdOut()).outStream().stream; | |
var ex_dir = try std.os.selfExeDirPathAlloc(allocator); | |
var app_rootdir = try std.os.path.join(allocator,ex_dir,"approot"); | |
var ofs_dir = try std.os.path.join(allocator,ex_dir,"ofs"); | |
try stdout.print("start!\n"); | |
try stdout.print("ex_dir = {}\n",ex_dir); | |
try stdout.print("app_rootdir = {}\n",app_rootdir); | |
try stdout.print("ofs_dir = {}\n",ofs_dir); | |
//get euid/egid | |
var real_euid = @intCast(u32,std.os.linux.geteuid()); | |
try stdout.print("euid: {}\n",real_euid); | |
var real_egid = @intCast(u32,std.os.linux.getegid()); | |
try stdout.print("egid: {}\n",real_egid); | |
//set process dumpable | |
//std.os.linux.syscall5(std.os.linux.SYS_prctl,PR_SET_DUMPABLE, 1, 0, 0, 0); | |
//var retd = std.os.linux.syscall5(std.os.linux.SYS_prctl,4,1,0,0,0); | |
//try stdout.print("dumpable: {}\n",retd); | |
//unshare current process | |
var ret = std.os.linux.unshare(std.os.linux.CLONE_NEWUSER|std.os.linux.CLONE_NEWNS|std.os.linux.CLONE_NEWPID); | |
try stdout.print("unshare: {}\n",ret); | |
//map uid/gid to root | |
var pssg = "/proc/self/setgroups"; | |
var psum = "/proc/self/uid_map"; | |
var psgm = "/proc/self/gid_map"; | |
var pssg_value = "deny"; | |
var psum_value = try std.fmt.allocPrint(allocator,"0 {} 1",real_euid); | |
var psgm_value = try std.fmt.allocPrint(allocator,"0 {} 1",real_egid); | |
try std.io.writeFile(pssg,pssg_value); | |
try stdout.print("setgroups: {}\n",pssg_value); | |
try std.io.writeFile(psum,psum_value); | |
try stdout.print("uid_map: {}\n",psum_value); | |
try std.io.writeFile(psgm,psgm_value); | |
try stdout.print("gid_map: {}\n",psgm_value); | |
//set root propagation | |
//ret = std.os.linux.mount(c"none",c"/",@intToPtr([*]const u8,0),std.os.linux.MS_REC|std.os.linux.MS_PRIVATE,0); | |
ret = std.os.linux.mount(c"none",c"/",null,std.os.linux.MS_REC|std.os.linux.MS_PRIVATE,0); | |
try stdout.print("make root private: {}\n",ret); | |
//mount overlayfs merge | |
var dir = try std.os.Dir.open(allocator,app_rootdir); | |
defer dir.close(); | |
while (try dir.next()) |entry| { | |
if(entry.kind!=std.os.Dir.Entry.Kind.Directory){ | |
continue; | |
} | |
var dir_name = entry.name; | |
var overlay_lower = try std.fmt.allocPrint(allocator,"/{}",dir_name); | |
var overlay_upper = try std.os.path.join(allocator,app_rootdir,dir_name); | |
var overlay_merge = try std.os.path.join(allocator,ofs_dir,dir_name); | |
var overlay_work = try std.fmt.allocPrint(allocator,"{}.work",overlay_merge); | |
try std.os.makePath(allocator,overlay_merge); | |
try std.os.makePath(allocator,overlay_work); | |
var mount_options = try std.fmt.allocPrint(allocator,"lowerdir={},upperdir={},workdir={}",overlay_lower,overlay_upper,overlay_work); | |
const c_overlay_merge = try std.cstr.addNullByte(allocator,overlay_merge); | |
const c_mount_options = try std.cstr.addNullByte(allocator,mount_options); | |
ret = std.os.linux.mount(c"none",c_overlay_merge.ptr,c"overlay",0,@ptrToInt(c_mount_options.ptr)); | |
try stdout.print("mount ofs: {} {} {}\n",entry.name,overlay_merge,mount_options); | |
try stdout.print("ret: {}\n",ret); | |
} | |
//mount bind overlayfs merge | |
var dir2 = try std.os.Dir.open(allocator,app_rootdir); | |
defer dir2.close(); | |
while (try dir2.next()) |entry| { | |
if(entry.kind!=std.os.Dir.Entry.Kind.Directory){ | |
continue; | |
} | |
var dir_name = entry.name; | |
var mount_bind = try std.fmt.allocPrint(allocator,"/{}",dir_name); | |
var mount_merge = try std.os.path.join(allocator,ofs_dir,dir_name); | |
const c_mount_merge = try std.cstr.addNullByte(allocator,mount_merge); | |
const c_mount_bind = try std.cstr.addNullByte(allocator,mount_bind); | |
var ret2 = std.os.linux.mount(c_mount_merge.ptr,c_mount_bind.ptr,c"bind",std.os.linux.MS_BIND,0); | |
try stdout.print("mount bind: {} {} {}\n",entry.name,mount_merge,mount_bind); | |
try stdout.print("ret: {}\n",ret2); | |
//var ret3 = std.os.linux.mount(c"none",c_mount_bind.ptr,@intToPtr([*]const u8,0),std.os.linux.MS_PRIVATE,0); | |
var ret3 = std.os.linux.mount(c"none",c_mount_bind.ptr,null,std.os.linux.MS_PRIVATE,0); | |
try stdout.print("mount bind private: {} {}\n",entry.name,mount_bind); | |
try stdout.print("ret: {}\n",ret3); | |
} | |
//exec command (default to busybox) | |
var shell_path = try std.os.path.join(allocator,ex_dir,"sash"); | |
var exec_argv = ([][]u8{shell_path})[0..]; | |
var exec_envs = std.BufMap.init(allocator); | |
try exec_envs.set("PS1","-[alone]- # "); | |
//const child = std.os.ChildProcess.init(exec_argv,allocator) catch unreachable; | |
//child.env_map = &exec_envs; | |
//defer child.deinit(); | |
//var first_arg = args.next(allocator); | |
//var second_arg = args.next(allocator); | |
//var first_arg = args.nextPosix(); | |
//var second_arg = args.nextPosix(); | |
var args = try std.os.argsAlloc(allocator); | |
defer std.os.argsFree(allocator,args); | |
if(args.len>1){ | |
//TODO: convert ArgIterator to []const []const u8 | |
//exec_argv = []const []const u8 {second_arg.?}; | |
exec_argv = args[1..]; | |
exec_envs = std.BufMap.init(allocator); | |
} | |
try stdout.print("exec: {}\n",exec_argv[0]); | |
//std.os.linux.execve(exec_argv0,exec_args,exec_envs); | |
//try child.spawn(); | |
var ret_exec = std.os.posixExecve(exec_argv, &exec_envs, allocator); | |
try stdout.print("ret: {}\n",ret_exec); | |
//findmnt -R -o SOURCE,FSROOT,TARGET,MAJ:MIN,FSTYPE,PROPAGATION,OPTIONS | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment