Skip to content

Commit c36217b

Browse files
docs: add lua-lsm documentation and update references
Add design doc and CLI reference for Lua-LSM. Update README, top-level CLI reference, build-and-test guide, seharden docs, and profile format spec with lua-lsm mentions, benchmark metadata fields, and e2e test instructions.
1 parent 448a8ad commit c36217b

9 files changed

Lines changed: 183 additions & 10 deletions

File tree

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ profile-driven auditing, optional hardening actions, and RPM package file verifi
88
```sh
99
loongshield seharden --scan --config dengbao_3 --verbose
1010
loongshield rpm --verify nginx --config https://example.com/sbom.json
11+
loongshield lua-lsm status
1112
```
1213

1314
## Quick Start
@@ -47,12 +48,14 @@ make rpm-in-docker
4748
- Development, testing, and packaging workflows assume an RPM-based Linux environment.
4849
- `loongshield seharden` defaults to the bundled `cis_alinux_3` profile.
4950
- `loongshield rpm` defaults to the OpenAnolis SBOM service.
51+
- `loongshield lua-lsm` requires a kernel with Lua-LSM enabled and never auto-loads policies.
5052
- On other RPM-based distributions, expect to pass an explicit `--config` or `--sbom-url`.
5153

5254
## Project Scope
5355

5456
- Currently focused on host hardening and verification on RPM-based Linux with systemd.
5557
- The optional kernel module under `src/kmod/` is not required for normal userspace workflows.
58+
- Lua-LSM support manages a kernel-provided built-in LSM through securityfs;
5659
- The project is released under the [MIT License](LICENSE).
5760

5861
## Versioning And Compatibility
@@ -70,6 +73,7 @@ make rpm-in-docker
7073
- SEHarden usage: [docs/reference/seharden-cli.md](docs/reference/seharden-cli.md)
7174
- SEHarden profile format: [docs/reference/seharden-profile-format.md](docs/reference/seharden-profile-format.md)
7275
- RPM verification usage: [docs/reference/rpm-cli.md](docs/reference/rpm-cli.md)
76+
- Lua-LSM usage: [docs/reference/lua-lsm-cli.md](docs/reference/lua-lsm-cli.md)
7377
- Build and test: [docs/developer/build-and-test.md](docs/developer/build-and-test.md)
7478
- Docker workflow: [docs/developer/docker-development.md](docs/developer/docker-development.md)
7579
- Submodule source policy: [docs/developer/submodule-sources.md](docs/developer/submodule-sources.md)

docs/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This tree is split by audience, not by implementation detail. Public caller docs
88
- SEHarden operators and profile authors: [reference/seharden-cli.md](./reference/seharden-cli.md)
99
- AgentOS baseline automation: [skill/agent-sec-seharden.md](./skill/agent-sec-seharden.md)
1010
- RPM verification users: [reference/rpm-cli.md](./reference/rpm-cli.md)
11+
- Lua-LSM operators: [reference/lua-lsm-cli.md](./reference/lua-lsm-cli.md)
1112
- Contributors: [developer/build-and-test.md](./developer/build-and-test.md)
1213
- Maintainer roadmap: [developer/roadmap.md](./developer/roadmap.md)
1314
- Community and process: [../CONTRIBUTING.md](../CONTRIBUTING.md), [../SECURITY.md](../SECURITY.md), [../SUPPORT.md](../SUPPORT.md), [../CODE_OF_CONDUCT.md](../CODE_OF_CONDUCT.md), [../CHANGELOG.md](../CHANGELOG.md), [../RELEASING.md](../RELEASING.md)
@@ -23,12 +24,14 @@ docs/
2324
seharden-cli.md
2425
seharden-profile-format.md
2526
rpm-cli.md
27+
lua-lsm-cli.md
2628
skill/
2729
agent-sec-seharden.md
2830
design/
2931
runtime-architecture.md
3032
boot-and-runtime-flow.md
3133
clean-architecture.md
34+
lua-lsm-native-support.md
3235
agentos-seharden-design.md
3336
seharden-enforcer-guidelines.md
3437
rpm-verification-design.md

docs/design/clean-architecture.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ The optional `sysmon` kernel module sits at the edge for cases where kernel-leve
154154

155155
That is a good design choice for a security tool that still needs to be buildable, deployable, and operable on ordinary hosts. Kernel code is higher cost and higher risk, so Loongshield keeps it optional instead of making it a hard dependency for everything.
156156

157+
Lua-LSM follows the same boundary from the Loongshield side. The kernel owns the built-in LSM and `/sys/kernel/security/lua` ABI, while Loongshield only manages readiness checks, policy validation, and explicit securityfs load/unload operations.
158+
157159
## Why Testing Is Layered This Way
158160

159161
The test layout matches the architecture:
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Lua-LSM Native Support
2+
3+
Lua-LSM is a kernel-provided built-in Linux Security Module. Loongshield treats
4+
it as a runtime capability exposed through securityfs, not as another
5+
out-of-tree kernel module under `src/kmod/`.
6+
7+
## Boundary
8+
9+
Loongshield owns:
10+
11+
- readiness checks for the running kernel
12+
- policy validation before explicit load
13+
- securityfs read/write orchestration
14+
- operator CLI and packaging of example policies
15+
- fake-securityfs tests for normal CI
16+
17+
The kernel owns:
18+
19+
- `CONFIG_LUA`
20+
- `CONFIG_SECURITY_LUA_LSM`
21+
- LSM hook registration
22+
- `/sys/kernel/security/lua/*`
23+
- policy execution inside the kernel Lua VM
24+
25+
## Runtime ABI
26+
27+
The userspace manager talks to these securityfs files:
28+
29+
- `version`
30+
- `register`
31+
- `unregister`
32+
- `modules`
33+
- `stats`
34+
- `lsm_funcs`
35+
36+
Only `register` and `unregister` are written. The CLI checks effective
37+
`CAP_MAC_ADMIN` before writes so operators get a clear userspace error before
38+
the kernel rejects the write.
39+
40+
## Package Layout
41+
42+
Bundled example policies are installed under:
43+
44+
```text
45+
/etc/loongshield/lua-lsm/policies.d/
46+
```
47+
48+
The example manifest is informational and does not trigger autoload:
49+
50+
```text
51+
profiles/lua-lsm/manifest.yml
52+
```
53+
54+
## Safety Gate
55+
56+
The feature remains experimental because the inspected Lua-LSM source tree has
57+
documented high-risk audit findings, including memory lifetime, refcount, RCU,
58+
and hook contract issues. Loongshield therefore does not auto-load policies and
59+
marks the CLI surface as experimental in status/help/docs.
60+
61+
Before production use, either fix the kernel audit blockers or enforce a
62+
conservative policy allowlist in Loongshield that only permits audited hook
63+
wrappers.
64+
65+
## Test Strategy
66+
67+
Normal CI uses a fake securityfs root through
68+
`LOONGSHIELD_LUA_LSM_SECURITYFS_ROOT` or direct module options. That covers
69+
status, doctor, list, load, unload, stats, and hooks behavior without requiring
70+
privileged kernel state.
71+
72+
Privileged end-to-end coverage should run in a VM with:
73+
74+
```text
75+
CONFIG_SECURITY=y
76+
CONFIG_SECURITYFS=y
77+
CONFIG_LUA=y
78+
CONFIG_SECURITY_LUA_LSM=y
79+
CONFIG_LSM=...,lua,...
80+
```
81+
82+
The VM test should load a narrow policy, prove the target hook behavior, unload
83+
the policy, and verify the behavior is gone.

docs/developer/build-and-test.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ You can also install packages directly with `dnf` or `yum`:
4242

4343
```sh
4444
dnf install -y \
45-
git cmake gcc gcc-c++ make \
46-
perl perl-IPC-Cmd perl-FindBin which \
47-
audit-libs-devel dbus-devel elfutils-libelf-devel \
48-
libarchive-devel libattr-devel \
49-
libcurl-devel libmount-devel libpsl-devel libyaml-devel \
50-
libcap-devel libzstd-devel openssl-devel rpm-devel \
51-
systemd-devel xz-devel
45+
audit-libs-devel cmake dbus-devel elfutils-libelf-devel \
46+
gcc gcc-c++ git libarchive-devel libattr-devel \
47+
libcap-devel libcurl-devel libmount-devel libpsl-devel \
48+
libyaml-devel libzstd-devel make openssl-devel \
49+
perl-ExtUtils-MakeMaker perl-FindBin perl-IPC-Cmd \
50+
rpm-build rpm-devel rpmdevtools systemd systemd-devel \
51+
which xz-devel
5252
```
5353

5454
Then initialize submodules and build:
@@ -68,17 +68,19 @@ submodules that still intentionally point at public forks.
6868
make
6969
make test
7070
make test-quick
71+
make test-e2e
7172
make rpm
7273
make rpm-in-docker
7374
```
7475

75-
`make test` builds first and then runs the full Lua suite. `make test-quick` reuses the current build output and is the fastest way to rerun the full test suite after Lua-only or documentation changes.
76+
`make test` builds first and then runs the full Lua suite. `make test-quick` reuses the current build output and reruns only the source-loaded unit and integration tests; use `make test` or `make test-e2e` after changes that affect the embedded `loongshield` binary.
77+
`make test-e2e` builds first and then runs only the process-level CLI suite under `tests/e2e/`. Real bundled-profile scans require root privileges and are skipped by the test process when it is not running as root.
7678

7779
## Test Layout
7880

7981
- `tests/unit/`: fast isolated module tests
8082
- `tests/integration/`: filesystem and system-behavior tests
81-
- `tests/e2e/`: reserved for full-flow suites; some revisions may not yet carry checked-in e2e cases
83+
- `tests/e2e/`: process-level full-flow suites that drive the built `loongshield` CLI
8284
- `tests/run.lua`: custom test discovery and runner
8385

8486
## Documentation Layout

docs/reference/loongshield-cli.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ Local builds produce the binary at `build/src/daemon/loongshield`. Installed sys
2323
- `version`: print the build version and commit.
2424
- `seharden`: audit or reinforce a security profile.
2525
- `rpm`: verify an installed RPM against a remote SBOM.
26+
- `lua-lsm`: inspect and manage Lua-LSM policies through securityfs.
2627

2728
Run subcommand help directly:
2829

2930
```sh
3031
loongshield seharden --help
3132
loongshield rpm --help
33+
loongshield lua-lsm --help
3234
```
3335

3436
## Typical Usage Examples
@@ -37,10 +39,12 @@ loongshield rpm --help
3739
loongshield version
3840
loongshield seharden --config agentos_baseline
3941
loongshield rpm --verify bash
42+
loongshield lua-lsm status
4043
```
4144

4245
## Documentation Map
4346

4447
- SEHarden usage: [seharden-cli.md](./seharden-cli.md)
4548
- SEHarden profile format: [seharden-profile-format.md](./seharden-profile-format.md)
4649
- RPM verification usage: [rpm-cli.md](./rpm-cli.md)
50+
- Lua-LSM usage: [lua-lsm-cli.md](./lua-lsm-cli.md)

docs/reference/lua-lsm-cli.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Lua-LSM CLI
2+
3+
`loongshield lua-lsm` manages Lua-LSM policies through the kernel securityfs
4+
ABI at `/sys/kernel/security/lua`.
5+
6+
Lua-LSM support is experimental. Loongshield does not auto-load policies during
7+
install or startup. Loading a policy is always an explicit operator action.
8+
9+
## Syntax
10+
11+
```sh
12+
loongshield lua-lsm <command> [options]
13+
```
14+
15+
## Commands
16+
17+
- `status`: show whether the Lua-LSM securityfs ABI is present.
18+
- `doctor`: run readiness checks for securityfs, active LSM order, and kernel config.
19+
- `list`: show loaded Lua-LSM modules.
20+
- `load <policy.lua>`: validate policy metadata and write the policy to `register`.
21+
- `unload <name>`: write the module name to `unregister`.
22+
- `hooks`: print `lsm_funcs` when `CONFIG_SECURITY_LUA_LSM_STATS=y`.
23+
- `stats`: print VM/cache stats when `CONFIG_SECURITY_LUA_LSM_STATS=y`.
24+
25+
## Options
26+
27+
- `--root <path>`: override the Lua-LSM securityfs root.
28+
- `--config <path>`: override the kernel config path used by `doctor`.
29+
- `--no-validate`: skip userspace metadata validation before `load`.
30+
- `--log-level <level>`: set log level.
31+
- `-h`, `--help`: show command help.
32+
33+
## Environment
34+
35+
- `LOONGSHIELD_LUA_LSM_SECURITYFS_ROOT`: defaults to `/sys/kernel/security/lua`.
36+
- `LOONGSHIELD_LUA_LSM_SECURITYFS_MOUNT`: defaults to the parent of the root.
37+
- `LOONGSHIELD_LUA_LSM_CONFIG_FILE`: kernel config used by `doctor`.
38+
- `LOONGSHIELD_LUA_LSM_ASSUME_CAP_MAC_ADMIN`: test-only capability bypass.
39+
40+
## Kernel Requirements
41+
42+
The running kernel must provide:
43+
44+
```text
45+
CONFIG_SECURITY=y
46+
CONFIG_SECURITYFS=y
47+
CONFIG_LUA=y
48+
CONFIG_SECURITY_LUA_LSM=y
49+
CONFIG_LSM=...,lua,...
50+
```
51+
52+
The `load` and `unload` commands require effective `CAP_MAC_ADMIN`, matching the
53+
kernel-side securityfs write check.
54+
55+
## Examples
56+
57+
```sh
58+
loongshield lua-lsm doctor
59+
loongshield lua-lsm status
60+
loongshield lua-lsm list
61+
loongshield lua-lsm load /etc/loongshield/lua-lsm/policies.d/deny_tmp_marker.lua
62+
loongshield lua-lsm unload deny_tmp_marker
63+
```
64+
65+
## Exit Codes
66+
67+
- `0`: command completed successfully.
68+
- `1`: CLI error, readiness failure, missing ABI file, validation failure, missing capability, or kernel write failure.

docs/reference/seharden-cli.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
`seharden` audits a host against a YAML profile and can optionally apply reinforce actions for failed rules.
44

5-
The default bundled profile is `cis_alinux_3`, which is aimed at Alibaba Cloud Linux 3 and similar OpenAnolis-style hosts. On other RPM-based systems, pick an explicit profile with `--config`.
5+
The default bundled profile is `cis_alinux_3`, which targets the CIS Alibaba Cloud Linux 3 Benchmark v2.0.0 and similar OpenAnolis-style hosts. On other RPM-based systems, pick an explicit profile with `--config`.
66

77
## Syntax
88

docs/reference/seharden-profile-format.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ Profiles are YAML documents consumed by `loongshield seharden`. They define leve
77
- `id`: stable profile identifier, for example `agentos_baseline`.
88
- `title` or `policy`: human-readable name.
99
- `version`: profile version string.
10+
- `source`: optional upstream benchmark or policy source URL.
11+
- `benchmark_version`: optional upstream benchmark version when the profile tracks an external benchmark.
12+
- `benchmark_workbench_source`: optional upstream WorkBench artifact URL.
13+
- `benchmark_pdf_source`: optional upstream benchmark PDF URL.
14+
- `benchmark_build_kit_source`: optional upstream benchmark build-kit URL.
15+
- `benchmark_update_source`: optional upstream release or update note URL.
16+
- `coverage`: optional short coverage label, for example `automated_subset`.
1017
- `levels`: ordered level list. Levels may use `inherits_from`.
1118
- `default_level`: optional level ID used when the caller omits `--level`.
1219
- `manual_review_required`: optional list of operator review items that stay outside automated host checks.

0 commit comments

Comments
 (0)