luad

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit a747b0c8d3871483ee64f865d57dc10ccd828ec0
Author: Daniel Barlow <dan@telent.net>
Date:   Wed, 29 Apr 2026 19:04:02 +0100

initial commit

Diffstat:
ACargo.lock | 267+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ACargo.toml | 9+++++++++
Arust-toolchain.toml | 2++
Arustup.nix | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/bin/luac.rs | 36++++++++++++++++++++++++++++++++++++
Asrc/main.rs | 105+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 471 insertions(+), 0 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -0,0 +1,267 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[package]] +name = "bstr" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "cc" +version = "1.2.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fork" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcc4b4161e53d499e41af904acb23950adf85682c772921ef3957cf1ecc98b3" +dependencies = [ + "libc", +] + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "luad" +version = "0.1.0" +dependencies = [ + "fork", + "libc", + "mlua", +] + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "mlua" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccd36acfa49ce6ee56d1307a061dd302c564eee757e6e4cd67eb4f7204846fab" +dependencies = [ + "bstr", + "either", + "libc", + "mlua-sys", + "num-traits", + "parking_lot", + "rustc-hash", + "rustversion", +] + +[[package]] +name = "mlua-sys" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f1c3a7fc7580227ece249fd90aa2fa3b39eb2b49d3aec5e103b3e85f2c3dfc8" +dependencies = [ + "cc", + "cfg-if", + "libc", + "pkg-config", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" diff --git a/Cargo.toml b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "luad" +version = "0.1.0" +edition = "2024" + +[dependencies] +fork = "0.7.0" +libc = "0.2.186" +mlua = { version = "0.11.6", features = ["lua53"] } diff --git a/rust-toolchain.toml b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/rustup.nix b/rustup.nix @@ -0,0 +1,52 @@ +{ pkgs ? import <nixpkgs> {} }: + let + overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml)); + libPath = with pkgs; lib.makeLibraryPath [ + # load external libraries that you need in your rust project here + ]; + python = (pkgs.python3.withPackages (python-pkgs: [ + python-pkgs.pynacl + python-pkgs.zeroconf + python-pkgs.bleak + ])); + in + pkgs.mkShell rec { + nativeBuildInputs= with pkgs; [ + openssl + rustup + lua5_3 + pkg-config +# sops + ]; + buildInputs = with pkgs; [ + clang + # Replace llvmPackages with llvmPackages_X, where X is the latest LLVM version (at the time of writing, 16) + llvmPackages.bintools + rustup + ]; + RUSTC_VERSION = overrides.toolchain.channel; + # https://github.com/rust-lang/rust-bindgen#environment-variables + LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ]; + shellHook = '' + export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin + export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/ + ''; + # Add precompiled library to rustc search path + RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [ + # add libraries here (e.g. pkgs.libvmi) + ]); + LD_LIBRARY_PATH = libPath; + # Add glibc, clang, glib, and other headers to bindgen search path + BINDGEN_EXTRA_CLANG_ARGS = + # Includes normal include path + (builtins.map (a: ''-I"${a}/include"'') [ + # add dev libraries here (e.g. pkgs.libvmi.dev) + pkgs.glibc.dev + ]) + # Includes with special directory paths + ++ [ + ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"'' + ''-I"${pkgs.glib.dev}/include/glib-2.0"'' + ''-I${pkgs.glib.out}/lib/glib-2.0/include/'' + ]; + } diff --git a/src/bin/luac.rs b/src/bin/luac.rs @@ -0,0 +1,36 @@ +#![feature(unix_socket_ancillary_data)] + +use std::{ + os::unix::net::{ + UnixDatagram, + SocketAncillary, + AncillaryData + }, + env, + io::IoSlice +}; + +fn main() { + let mut payload = "".to_string(); + let mut argv = env::args(); + let _ = argv.next(); + for a in argv { + payload.push_str(&a); + payload.push_str("\0"); + } + let payload = payload.into_bytes(); + let Ok(sock_path) = env::var("LUAD_SOCKET_PATH") else { + panic!("need to set LUAD_SOCKET_PATH env var"); + }; + let sock = UnixDatagram::unbound().expect("socket"); + sock.connect(sock_path).expect("connect"); + let fds = [0, 1, 2]; + let mut ancillary_buffer = [0; 128]; + let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); + ancillary.add_fds(&fds[..]); + let buf = IoSlice::new(&payload); + sock.send_vectored_with_ancillary(&[buf], &mut ancillary).expect("send failed"); + + + println!("heyt"); +} diff --git a/src/main.rs b/src/main.rs @@ -0,0 +1,105 @@ +#![feature(unix_socket_ancillary_data)] + +use mlua::Lua; +use std::{ + env, + io, + io::IoSliceMut, + path::Path, + process::exit, + collections::HashMap +}; + +use std::os::unix::net::{ + UnixDatagram, + SocketAncillary, + AncillaryData +}; + +use libc::WEXITSTATUS; +use fork::{Fork, fork, waitpid}; + +// if we use SCM_RIGHTS to pass fds from client, we also need to +// write the client as we can't do that with socat + +fn run_lua(lua : &Lua, path : &Path) { + let chunk = lua.load(path); + match chunk.exec() { + Ok(()) => { println!("lua returned ok"); }, + Err(e) => { + println!("lua error {:?}", e); + exit(1); + }, + }; + exit(0); +} + +fn main() -> std::io::Result<()> { + let Ok(sock_path) = env::var("LUAD_SOCKET_PATH") else { + panic!("need to set LUAD_SOCKET_PATH env var"); + }; + + let lua = unsafe { Lua::unsafe_new() }; + + let sock = UnixDatagram::bind(sock_path)?; + + // listen for datagrams. each time we get one, fork a child + // to run lua script with the datagram payload and its stdio + // connected to the passed fds. when the lua subprocess exits, + // write the exit status back to the peer + // this implies we need a map of child pid -> peer address + + loop { + let mut buf = [0u8; 1024]; + let mut bufs = [ + IoSliceMut::new(&mut buf), + ]; + let mut ancillary_buffer = [0; 128]; + let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); + match sock.recv_vectored_with_ancillary(&mut bufs, &mut ancillary) { + Ok((size, truncated)) => { + let mut fds : Vec<i32> = Vec::new(); + for ancillary_result in ancillary.messages() { + if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() { + for fd in scm_rights { + println!("receive file descriptor: {fd}"); + fds.push(fd); + } + } + } + println!("data {:?}, len {:?}", buf, size); + println!("fds {:?}", fds); + + }, + Err(e) => { + println!("error reading: {:?}", e); + } + } + } + + // for pathname in io::stdin().lines() { + // let pathname = pathname.unwrap(); + // let path = Path::new(&pathname); + // match fork() { + // Ok(Fork::Parent(pid)) => { + // // println!("parent {:?} {:?}", pid, result); + // match waitpid(pid) { + // Ok(status) => { + // println!("exited {:?}", WEXITSTATUS(status)); + // }, + // Err(e) => { + // println!("waitpid failed {:?}", e); + // } + // } + // }, + // Ok(Fork::Child) => { + // run_lua(&lua, &path); + // } + // Err(e) => { + // println!("fork error {:?}", e); + // exit(1); + // } + // } + // }; + // Ok(()) +}