Skip to content

Commit

Permalink
add mount ns support to nsutil (litmuschaos#499)
Browse files Browse the repository at this point in the history
Signed-off-by: Shubham Chaudhary <[email protected]>
  • Loading branch information
ispeakc0de committed May 17, 2024
1 parent f887e23 commit 9cea95d
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 10 deletions.
28 changes: 24 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ name: release

on:
workflow_dispatch:
inputs:
inputs:
release_tag:
description: 'release tag'
required: true
release_title:
description: 'release title'
required: false
release_notes:
description: 'release notes'
description: 'release notes'
required: false
default: ''

Expand All @@ -22,6 +22,11 @@ jobs:
steps:
- uses: actions/checkout@v2

- name: Set up QEMU
uses: docker/setup-qemu-action@v1
with:
qemu-version: '6.0.0'

- name: Build go binary for pause
run : ./../../build/go-multiarch-build.sh "go build -o ./../../build/_output/pause-linux"
working-directory: custom/pause
Expand All @@ -30,15 +35,30 @@ jobs:
run : ./../../build/go-multiarch-build.sh "go build -o ./../../build/_output/nsutil-linux"
working-directory: custom/nsutil

- name: Build shared libraries for nsutil amd64
run: gcc -shared -fPIC nsutil.c -o ./../../build/_output/nsutil_amd64.so
working-directory: custom/nsutil

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Build arm64 Docker image
run: docker buildx build --platform linux/arm64 -t myapp-arm64 --load .
working-directory: custom/nsutil

- name: Extract compiled binary
run: docker create --name myapp-arm64-container myapp-arm64 && docker cp myapp-arm64-container:/app/nsutil.so ./../../build/_output/nsutil_arm64.so
working-directory: custom/nsutil

- name: Build go binary for promql-cli
run : |
cp custom/promql-cli/promql-linux-amd64 build/_output/
cp custom/promql-cli/promql-linux-arm64 build/_output/
- name: Build go binary for dns_interceptor
run : go build -o ./../../build/_output/dns_interceptor
working-directory: custom/dns_interceptor

- name: create release along with artifact
uses: ncipollo/release-action@v1
with:
Expand Down
3 changes: 3 additions & 0 deletions custom/hardened-alpine/experiment/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ RUN curl -L https://github.com/chaosnative/promql-cli/releases/download/3.0.0-be
#Installing nsutil cli binaries
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/nsutil-linux-${TARGETARCH} --output /usr/local/bin/nsutil && chmod +x /usr/local/bin/nsutil

#Installing nsutil shared lib
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/nsutil-${TARGETARCH}.so --output /usr/local/lib/nsutil.so && chmod +x /usr/local/lib/nsutil.so

#Installing pause cli binaries
RUN curl -L https://github.com/litmuschaos/test-tools/releases/download/${LITMUS_VERSION}/pause-linux-${TARGETARCH} --output /usr/local/bin/pause && chmod +x /usr/local/bin/pause

Expand Down
13 changes: 13 additions & 0 deletions custom/nsutil/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM arm64v8/ubuntu:latest

# Install gcc for compiling C code
RUN apt-get update && apt-get install -y gcc

# Set the working directory
WORKDIR /app

# Copy your C code into the container
COPY nsutil.c /app

# Compile the C code
RUN gcc -shared -fPIC nsutil.c -o nsutil.so
17 changes: 12 additions & 5 deletions custom/nsutil/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ import (
)

// user and mnt ns not supported
var ns = []string{"net", "pid", "cgroup", "uts", "ipc"}
var nsSelected = make([]bool, 6)

var t int // target pid
var (
ns = []string{"net", "pid", "cgroup", "uts", "ipc", "mnt"}
nsSelected = make([]bool, 7)
t int // target pid
libPath string
)

// rootCmd represents the base command
var rootCmd = &cobra.Command{
Expand All @@ -41,7 +43,9 @@ func init() {
rootCmd.PersistentFlags().BoolVarP(&nsSelected[2], "cgroup", "c", false, "cgroup namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[3], "uts", "u", false, "uts namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[4], "ipc", "i", false, "ipc namespace to enter")
rootCmd.PersistentFlags().BoolVarP(&nsSelected[5], "mnt", "m", false, "mnt namespace to enter")
rootCmd.PersistentFlags().IntVarP(&t, "target", "t", 0, "target process id (required)")
rootCmd.PersistentFlags().StringVar(&libPath, "lib-path", "/usr/local/lib/nsutil.so", "shared library path to be preloaded")
err := rootCmd.MarkPersistentFlagRequired("target")
if err != nil {
log.WithError(err).Fatal("Failed to mark required flag")
Expand All @@ -55,6 +59,9 @@ func nsutil(cmd *cobra.Command, args []string) {
// target command
nCmd := exec.Command(args[0], args[1:]...)
nCmd.Env = os.Environ()
if nsSelected[5] {
nCmd.Env = append(nCmd.Env, fmt.Sprintf("LD_PRELOAD=%s", libPath), fmt.Sprintf("MNT_PATH=%s", fmt.Sprintf("/proc/"+strconv.Itoa(t)+"/ns/mnt")))
}
nCmd.Stdin = os.Stdin
nCmd.Stdout = os.Stdout
nCmd.Stderr = os.Stderr
Expand Down Expand Up @@ -97,7 +104,7 @@ func nsutil(cmd *cobra.Command, args []string) {
func getNSFiles() map[string]*os.File {
nsMap := map[string]*os.File{}
for i, n := range ns {
if !nsSelected[i] {
if !nsSelected[i] || n == "mnt" {
continue
}
file, err := getFileFromNS("/proc/" + strconv.Itoa(t) + "/ns/" + n)
Expand Down
31 changes: 31 additions & 0 deletions custom/nsutil/nsutil.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/stat.h>

void nsenter() {
char *mnt_path = getenv("MNT_PATH");
if (mnt_path != NULL) {
int fd = open(mnt_path, O_RDONLY);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}

int ns = setns(fd, 0);
if (ns == -1) {
perror("setns");
exit(EXIT_FAILURE);
}
}

unsetenv("LD_PRELOAD");
}

__attribute__((constructor)) void ctor() {
nsenter();
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ require (
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 comments on commit 9cea95d

Please sign in to comment.