Projects STRLCPY ebpfguard Commits bec2ad18
🤬
  • ■ ■ ■ ■ ■ ■
    COMMUNITY.md
     1 +# The Deepfence Community
     2 + 
     3 +Thank you for taking the time to look at Deepfence Ebpfguard. We sincerely hope it helps you to identify and prioritize vulnerable dependencies in your applications, and proves to be useful in protecting you and your users from breaches.
     4 + 
     5 +You are welcome to show your support for the project in several ways:
     6 + 
     7 + * ![GitHub stars](https://img.shields.io/github/stars/deepfence/ebpfguard) Please star Ebpfguard on GitHub - thank you!
     8 + * Get some great Deepfence SWAG by joining our [monthly SWAG raffle](https://go.deepfence.io/community-monthly-swag-sign-up)
     9 + * Join the [Deepfence Community Slack](https://join.slack.com/t/deepfence-community/shared_invite/zt-podmzle9-5X~qYx8wMaLt9bGWwkSdgQ), and share and answer questions
     10 + <!-- * Share your experiences with the wider community by leaving a review on any of the following locations:
     11 + * [Gartner Peer Insights](https://gtnr.io/b4L6DCx31)
     12 + * [G2 Product Reviews](https://www.g2.com/products/ebpfguard/reviews) -->
     13 + <!-- * [Stackshare](https://stackshare.io/deepfence-ebpfguard) -->
     14 + 
     15 +<!-- ## Contributing
     16 + 
     17 +If you'd like to contribute to the project, then [CONTRIBUTING.md](https://github.com/deepfence/ebpfguard/blob/master/CONTRIBUTING.md) is the place to start. -->
     18 + 
     19 +<!-- ## Writing, Blogging, Sharing
     20 + 
     21 +Please do! We have some [community resources](https://drive.google.com/drive/u/1/folders/1LWi4tl-RCuxSi6FyMBTFlT16wECk4HI0) that might be of help. -->
     22 + 
  • ■ ■ ■ ■ ■ ■
    EXAMPLES.md
     1 +# Examples
     2 + 
     3 +## Defining single policies
     4 + 
     5 +### `file_open`
     6 + 
     7 +The [file_open](https://github.com/deepfence/ebpfguard/tree/main/examples/file_open)
     8 +example shows how to define a policy for `file_open` LSM hook as Rust code.
     9 +It denies the given binary (or all processes, if none defined) from opening
     10 +the given directory.
     11 + 
     12 +To try it out, let's create a directory and a file inside it:
     13 + 
     14 +```bash
     15 +$ mkdir /tmp/test
     16 +$ echo "foo" > /tmp/test/test
     17 +```
     18 + 
     19 +Then run our example policy program with:
     20 + 
     21 +```bash
     22 +$ RUST_LOG=info cargo xtask run --example file_open -- --path-to-deny /tmp/test
     23 +```
     24 + 
     25 +When trying to access that directory and file, you should see that these
     26 +operations are denied:
     27 + 
     28 +```bash
     29 +$ ls /tmp/test/
     30 +ls: cannot open directory '/tmp/test/': Operation not permitted
     31 +$ cat /tmp/test/test
     32 +cat: /tmp/test/test: Operation not permitted
     33 +```
     34 + 
     35 +The policy application should show logs like:
     36 + 
     37 +```bash
     38 +[2023-04-22T20:51:01Z INFO file_open] file_open: pid=3001 subject=980333 path=9632
     39 +[2023-04-22T20:51:03Z INFO file_open] file_open: pid=3010 subject=980298 path=9633
     40 +```
     41 +#### mount
     42 + 
     43 +The [mount](https://github.com/deepfence/ebpfguard/tree/main/examples/file_open)
     44 +example shows how to define a policy for `sb_mount`, `sb_remount` and
     45 +`sb_umount` LSM hooks as Rust code. It denies the mount operations for all
     46 +processes except for the optionally given one.
     47 + 
     48 +To try it out, let's create two directories:
     49 + 
     50 +```bash
     51 +$ mkdir /tmp/test1
     52 +$ mkdir /tmp/test2
     53 +```
     54 + 
     55 +Then run our example policy program, first without providing any binary to
     56 +allow mount for (so it's denied for all processes):
     57 + 
     58 +```bash
     59 +$ RUST_LOG=info cargo xtask run --example mount
     60 +```
     61 + 
     62 +Let's try to bind mount the first directory to the second one. It should
     63 +fail with the following error:
     64 + 
     65 +```bash
     66 +sudo mount --bind /tmp/test1 /tmp/test2
     67 +mount: /tmp/test2: permission denied.
     68 + dmesg(1) may have more information after failed mount system call.
     69 +```
     70 + 
     71 +And the policy program should show a log like:
     72 + 
     73 +```bash
     74 +[2023-04-23T21:02:58Z INFO mount] sb_mount: pid=17363 subject=678150
     75 +```
     76 + 
     77 +Now let's try to allow mount operations for the mount binary:
     78 + 
     79 +```bash
     80 +$ RUST_LOG=info cargo xtask run --example mount -- --allow /usr/bin/mount
     81 +```
     82 + 
     83 +And try to bind mount the first directory to the second one again. It should
     84 +succeed this time:
     85 + 
     86 +```bash
     87 +$ sudo mount --bind /tmp/test1 /tmp/test2
     88 +$ mount | grep test
     89 +tmpfs on /tmp/test2 type tmpfs (rw,nosuid,nodev,seclabel,nr_inodes=1048576,inode64)
     90 +```
     91 + 
     92 +### `task_fix_setuid`
     93 + 
     94 +The [task_fix_setuid](https://github.com/deepfence/ebpfguard/tree/main/examples/task_fix_setuid)
     95 +example shows how to define a policy for `task_fix_setuid` LSM hook as Rust
     96 +code. It denies the `setuid` operation for all processes except for the
     97 +optionally given one.
     98 + 
     99 +To try it out, run our example policy program, first without providing any
     100 +binary to allow `setuid` for (so it's denied for all processes):
     101 + 
     102 +```bash
     103 +$ RUST_LOG=info cargo xtask run --example task_fix_setuid
     104 +```
     105 + 
     106 +Then try to use `sudo`. It should fail with the following error:
     107 + 
     108 +```bash
     109 +$ sudo -i
     110 +sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
     111 +sudo: error initializing audit plugin sudoers_audit
     112 +```
     113 + 
     114 +And the policy program should show log like:
     115 + 
     116 +```bash
     117 +[2023-04-23T15:15:00Z INFO task_fix_setuid] file_open: pid=25604 subject=674642 old_uid=1000 old_gid=1000 new_uid=0 new_gid=1000
     118 +```
     119 + 
     120 +Now, let's try to allow `setuid` for a specific binary. Let's use `sudo`:
     121 + 
     122 +```bash
     123 +$ RUST_LOG=info cargo xtask run --example task_fix_setuid -- --allow /usr/bin/sudo
     124 +```
     125 + 
     126 +Then try to use `sudo` again. It should work this time:
     127 + 
     128 +```bash
     129 +$ sudo -i
     130 +# whoami
     131 +root
     132 +```
     133 + 
     134 +## Daemon with CLI and YAML engine
     135 + 
     136 +Run the daemon with:
     137 + 
     138 +```bash
     139 +$ RUST_LOG=info cargo xtask run --example daemon
     140 +```
     141 + 
     142 +Then manage the policies using the CLI:
     143 + 
     144 +```bash
     145 +$ cargo xtask run --example cli -- --help
     146 +```
     147 + 
     148 +You can apply policies from the
     149 +[example YAML file](https://github.com/deepfence/ebpfguard/blob/main/examples/cli/policy.yaml):
     150 + 
     151 +```bash
     152 +$ cargo xtask run --example cli -- policy add --path examples/cli/policy.yaml
     153 +```
     154 + 
  • ■ ■ ■ ■ ■ ■
    README.md
     1 +![Deepfence Logo](images/readme/deepfence-logo.png)
     2 + 
     3 +[![GitHub license](https://img.shields.io/github/license/deepfence/ebpfguard)](https://github.com/deepfence/ebpfguard/blob/master/LICENSE)
     4 +[![GitHub stars](https://img.shields.io/github/stars/deepfence/ebpfguard)](https://github.com/deepfence/ebpfguard/stargazers)
    1 5  [![Workflow Status](https://github.com/deepfence/ebpfguard/workflows/build-test/badge.svg)](https://github.com/deepfence/ebpfguard/actions?query=workflow)
     6 +[![GitHub issues](https://img.shields.io/github/issues/deepfence/ebpfguard)](https://github.com/deepfence/ebpfguard/issues)
     7 +[![Slack](https://img.shields.io/badge/[email protected]?logo=slack)](https://join.slack.com/t/deepfence-community/shared_invite/zt-podmzle9-5X~qYx8wMaLt9bGWwkSdgQ)
     8 +<h3 align="center">
     9 +<a
     10 + href="https://runacap.com/ross-index/annual-2022/"
     11 + target="_blank"
     12 + rel="noopener"
     13 +>
     14 + <img
     15 + style="width: 260px; height: 56px"
     16 + src="https://runacap.com/wp-content/uploads/2023/02/Annual_ROSS_badge_black_2022.svg"
     17 + alt="ROSS Index - Fastest Growing Open-Source Startups | Runa Capital"
     18 + width="260"
     19 + height="56"
     20 + />
     21 +</a>
     22 +</h3>
    2 23   
    3  -# ebpfguard
     24 +# Ebpfguard
    4 25   
    5 26  **Ebpfguard** is a library for managing Linux security policies. It is based on
    6 27  [LSM hooks](https://www.kernel.org/doc/html/latest/admin-guide/LSM/index.html),
    skipped 4 lines
    11 32  the need to use them directly.
    12 33   
    13 34  ## Prerequisites
     35 + 
     36 +### kernel capabilities
    14 37   
    15 38  First, you need to have a Linux kernel:
    16 39  * with BTF support
    skipped 16 lines
    33 56   
    34 57  If the output doesn't contain `bpf`, you need to enable BPF LSM by adding
    35 58  `lsm=[...],bpf` to your kernel config parameters. That can be achieved by
    36  -executing the [following script](https://raw.githubusercontent.com/vadorovsky/enable-bpf-lsm/main/enable-bpf-lsm.py).
     59 +executing the [enable-bpf-lsm.py](https://github.com/deepfence/ebpfguard/blob/main/enable-bpf-lsm.py.py) script.
    37 60   
    38  -Then you need the Rust stable and nightly toolchains installed on your system,
    39  -as well as bpf-linker. You can install these by following these
    40  -[instructions](https://aya-rs.dev/book/start/development/).
     61 +This script will print modified contents of `/etc/default/grub` file to stdout.
     62 +Either pipe it back directly to `/etc/default/grub` or save it somewhere
     63 +and compare contents before swapping to a new version.
    41 64   
    42  -## LSM hooks
    43  - 
    44  -LSM hooks supported by Ebpfguard are:
     65 +Whole command with direct pipe:
    45 66   
    46  -* [`bprm_check_security`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L62)
    47  -* [`file_open`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L620)
    48  -* [`sb_mount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L128)
    49  -* [`sb_remount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L147)
    50  -* [`sb_umount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L159)
    51  -* [`socket_bind`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L904)
    52  -* [`socket_connect`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L912)
    53  -* [`task_fix_setuid`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L709)
     67 +```bash
     68 +$ ./enable-bpf.lsm.py | sudo tee /etc/default/grub 1>/dev/null
     69 +```
    54 70   
    55  -## Examples
     71 +This file is used by grub2 to assemble final `grub.cfg`. To trigger reconfiguration
     72 +use grub's mkconfig command with `-o <path to grub.cfg>` switch.
    56 73   
    57  -### Defining single policies
     74 +Both command name and path to `grub.cfg` are distribution dependent.
    58 75   
    59  -#### `file_open`
     76 +On ubuntu:
    60 77   
    61  -The [file_open](https://github.com/deepfence/ebpfguard/tree/main/examples/file_open)
    62  -example shows how to define a policy for `file_open` LSM hook as Rust code.
    63  -It denies the given binary (or all processes, if none defined) from opening
    64  -the given directory.
     78 +```
     79 +$ sudo grub-mkconfig -o /boot/grub/grub.cfg
     80 +```
    65 81   
    66  -To try it out, let's create a directory and a file inside it:
     82 +On fedora:
    67 83   
    68  -```bash
    69  -$ mkdir /tmp/test
    70  -$ echo "foo" > /tmp/test/test
     84 +```
     85 +$ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
    71 86  ```
    72 87   
    73  -Then run our example policy program with:
     88 +After that's done reboot your system.
     89 + 
     90 +### rust toolchain and packages
    74 91   
    75  -```bash
    76  -$ RUST_LOG=info cargo xtask run --example file_open -- --path-to-deny /tmp/test
    77  -```
     92 +You need the Rust stable and nightly toolchains installed on your system, bpf-linker and bpftool binary.
    78 93   
    79  -When trying to access that directory and file, you should see that these
    80  -operations are denied:
     94 +Install nightly toolchain:
    81 95   
    82  -```bash
    83  -$ ls /tmp/test/
    84  -ls: cannot open directory '/tmp/test/': Operation not permitted
    85  -$ cat /tmp/test/test
    86  -cat: /tmp/test/test: Operation not permitted
     96 +```
     97 +$ rustup toolchain install nightly --component rust-src
    87 98  ```
    88 99   
    89  -The policy application should show logs like:
     100 +Optionally add miri:
    90 101   
    91  -```bash
    92  -[2023-04-22T20:51:01Z INFO file_open] file_open: pid=3001 subject=980333 path=9632
    93  -[2023-04-22T20:51:03Z INFO file_open] file_open: pid=3010 subject=980298 path=9633
    94 102  ```
    95  -#### mount
    96  - 
    97  -The [mount](https://github.com/deepfence/ebpfguard/tree/main/examples/file_open)
    98  -example shows how to define a policy for `sb_mount`, `sb_remount` and
    99  -`sb_umount` LSM hooks as Rust code. It denies the mount operations for all
    100  -processes except for the optionally given one.
     103 +$ rustup component add miri --toolchain nightly
     104 +```
    101 105   
    102  -To try it out, let's create two directories:
     106 +Finally install bpf-linker:
    103 107   
    104  -```bash
    105  -$ mkdir /tmp/test1
    106  -$ mkdir /tmp/test2
     108 +```
     109 +$ cargo install bpf-linker
    107 110  ```
    108 111   
    109  -Then run our example policy program, first without providing any binary to
    110  -allow mount for (so it's denied for all processes):
     112 +This bpf-linker installation method works on linux x86_64 systems.
     113 +For others refer to [aya-rs documentation](https://aya-rs.dev/book/start/development/).
    111 114   
    112  -```bash
    113  -$ RUST_LOG=info cargo xtask run --example mount
    114  -```
     115 +To install bpftool either use distro provided package or build it from [source](https://github.com/libbpf/bpftool).
    115 116   
    116  -Let's try to bind mount the first directory to the second one. It should
    117  -fail with the following error:
     117 +On ubuntu it is a part of linux-tools:
    118 118   
    119  -```bash
    120  -sudo mount --bind /tmp/test1 /tmp/test2
    121  -mount: /tmp/test2: permission denied.
    122  - dmesg(1) may have more information after failed mount system call.
     119 +```
     120 +$ sudo apt install linux-tools-$(uname -r)
    123 121  ```
    124 122   
    125  -And the policy program should show a log like:
     123 +## Development
     124 + 
     125 +All commands should be executed from repository/workspace root folder unless noted otherwise.
    126 126   
    127  -```bash
    128  -[2023-04-23T21:02:58Z INFO mount] sb_mount: pid=17363 subject=678150
    129  -```
     127 +### Compilation
    130 128   
    131  -Now let's try to allow mount operations for the mount binary:
     129 +First compile ebpf bytecode with the following command. It will be embedded
     130 +in userspace binary using aya.
    132 131   
    133  -```bash
    134  -$ RUST_LOG=info cargo xtask run --example mount -- --allow /usr/bin/mount
     132 +```
     133 +$ cargo xtask build-ebpf
    135 134  ```
    136 135   
    137  -And try to bind mount the first directory to the second one again. It should
    138  -succeed this time:
     136 +Then userspace code.
    139 137   
    140  -```bash
    141  -$ sudo mount --bind /tmp/test1 /tmp/test2
    142  -$ mount | grep test
    143  -tmpfs on /tmp/test2 type tmpfs (rw,nosuid,nodev,seclabel,nr_inodes=1048576,inode64)
     138 +```
     139 +$ cargo build
    144 140  ```
    145 141   
    146  -#### `task_fix_setuid`
     142 +### Tests
    147 143   
    148  -The [task_fix_setuid](https://github.com/deepfence/ebpfguard/tree/main/examples/task_fix_setuid)
    149  -example shows how to define a policy for `task_fix_setuid` LSM hook as Rust
    150  -code. It denies the `setuid` operation for all processes except for the
    151  -optionally given one.
     144 +Commands in this subsection mirror state of CI pipeline.
    152 145   
    153  -To try it out, run our example policy program, first without providing any
    154  -binary to allow `setuid` for (so it's denied for all processes):
     146 +Regular tests
    155 147   
    156  -```bash
    157  -$ RUST_LOG=info cargo xtask run --example task_fix_setuid
     148 +```
     149 +$ cargo test
    158 150  ```
    159 151   
    160  -Then try to use `sudo`. It should fail with the following error:
     152 +Formatting gateway. Drop check subflag to autoformat.
    161 153   
    162  -```bash
    163  -sudo -i
    164  -sudo: PERM_ROOT: setresuid(0, -1, -1): Operation not permitted
    165  -sudo: error initializing audit plugin sudoers_audit
     154 +```
     155 +$ cargo fmt --all -- --check
    166 156  ```
    167 157   
    168  -And the policy program should show log like:
     158 +Clippy lints.
    169 159   
    170  -```bash
    171  -[2023-04-23T15:15:00Z INFO task_fix_setuid] file_open: pid=25604 subject=674642 old_uid=1000 old_gid=1000 new_uid=0 new_gid=1000
     160 +```
     161 +$ cargo clippy --workspace -- --deny warnings
    172 162  ```
    173 163   
    174  -Now, let's try to allow `setuid` for a specific binary. Let's use `sudo`:
     164 +Miri verification.
    175 165   
    176  -```bash
    177  -$ RUST_LOG=info cargo xtask run --example task_fix_setuid -- --allow /usr/bin/sudo
     166 +```
     167 +$ cargo +nightly miri test --all-targets
    178 168  ```
    179 169   
    180  -Then try to use `sudo` again. It should work this time:
     170 +Note that miri verification requires nightly toolchain as well as miri component. To add them execute:
    181 171   
    182  -```bash
    183  -$ sudo -i
    184  -# whoami
    185  -root
     172 +```
     173 +$ rustup toolchain install nightly --component rust-src
     174 +$ rustup component add miri --toolchain nightly
    186 175  ```
    187 176   
    188  -### Daemon with CLI and YAML engine
     177 +## LSM hooks
    189 178   
    190  -Run the daemon with:
     179 +LSM hooks supported by Ebpfguard are:
    191 180   
    192  -```bash
    193  -$ RUST_LOG=info cargo xtask run --example daemon
    194  -```
     181 +* [`bprm_check_security`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L62)
     182 +* [`file_open`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L620)
     183 +* [`sb_mount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L128)
     184 +* [`sb_remount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L147)
     185 +* [`sb_umount`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L159)
     186 +* [`socket_bind`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L904)
     187 +* [`socket_connect`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L912)
     188 +* [`task_fix_setuid`](https://elixir.bootlin.com/linux/v6.2.12/source/include/linux/lsm_hooks.h#L709)
    195 189   
    196  -Then manage the policies using the CLI:
     190 +## Examples
    197 191   
    198  -```bash
    199  -$ cargo xtask run --example cli -- --help
    200  -```
     192 +For usage examples check [EXAMPLES.md](EXAMPLES.md).
    201 193   
    202  -You can apply policies from the
    203  -[example YAML file](https://github.com/deepfence/ebpfguard/blob/main/examples/cli/policy.yaml):
     194 +## Get in touch
    204 195   
    205  -```bash
    206  -$ cargo xtask run --example cli -- policy add --path examples/cli/policy.yaml
    207  -```
     196 +Thank you for using Ebpfguard. Please feel welcome to participate in the [Deepfence community](COMMUNITY.md).
     197 + 
     198 +* [Deepfence Community Website](https://community.deepfence.io)
     199 +* [<img src="https://img.shields.io/badge/[email protected]?logo=slack">](https://join.slack.com/t/deepfence-community/shared_invite/zt-podmzle9-5X~qYx8wMaLt9bGWwkSdgQ) Got a question, need some help? Find the Deepfence team on Slack
     200 +* [![GitHub issues](https://img.shields.io/github/issues/deepfence/ebpfguard)](https://github.com/deepfence/ebpfguard/issues) Got a feature request or found a bug? Raise an issue
     201 +<!-- * [![Documentation](https://img.shields.io/badge/documentation-read-green)](https://community.deepfence.io/docs/ebpfguard/) Read the documentation in the [Deepfence Ebpfguard Documentation](https://community.deepfence.io/docs/ebpfguard/) -->
     202 +<!-- * [productsecurity at deepfence dot io](SECURITY.md): Found a security issue? Share it in confidence -->
     203 +* Find out more at [deepfence.io](https://deepfence.io/)
    208 204   
    209 205  ## License
    210 206   
    skipped 2 lines
    213 209   
    214 210  eBPF programs inside ebpfguard-ebpf directory are licensed under
    215 211  [GNU General Public License, version 2](https://github.com/deepfence/ebpfguard/blob/main/ebpfguard-ebpf/LICENSE).
     212 + 
  • ■ ■ ■ ■ ■ ■
    enable-bpf-lsm.py
     1 +#!/usr/bin/env python3
     2 + 
     3 +import sys
     4 +import logging
     5 + 
     6 +logging.basicConfig()
     7 +log = logging.getLogger(None)
     8 +log.setLevel(logging.INFO)
     9 + 
     10 + 
     11 +def main():
     12 + try:
     13 + with open("/sys/kernel/security/lsm", "r") as f:
     14 + lsms = f.read().strip().split(",")
     15 + except Exception as e:
     16 + log.error(
     17 + "Couldn't open lsm capabilities pseudo file. Check if your kernel supports lsm."
     18 + )
     19 + sys.exit(-1)
     20 + 
     21 + if "bpf" in lsms:
     22 + log.info("BPF LSM already enabled")
     23 + return
     24 + 
     25 + lsms.append("bpf")
     26 + 
     27 + content = []
     28 + bpf_line = None
     29 + with open("/etc/default/grub") as fd:
     30 + for i, l in enumerate(fd):
     31 + if l.startswith("GRUB_CMDLINE_LINUX="):
     32 + if bpf_line:
     33 + log.warning(
     34 + "Multiple GRUB_CMDLINE_LINUX. Only last one takes effect. Check your configuration. This script will modify last occurence only."
     35 + )
     36 + bpf_line = (i, l)
     37 + else:
     38 + content.append(l)
     39 + idx, effective_grub_cmdline = bpf_line
     40 + 
     41 + if not effective_grub_cmdline:
     42 + log.error("""No line starting with "GRUB_CMDLINE_LINUX=".""")
     43 + sys.exit(-2)
     44 + 
     45 + if "lsm" in effective_grub_cmdline:
     46 + log.warning(
     47 + f"""LSMs explicitly declared in /etc/default/grub GRUB_CMDLINE_LINUX. Edit manually and append bpf value.
     48 + Whole line could look like GRUB_CMDLINE_LINUX="lsm={','.join(lsms)}" """
     49 + )
     50 + sys.exit(-3)
     51 + 
     52 + modified_cmdline = effective_grub_cmdline.lstrip('GRUB_CMDLINE_LINUX="').rstrip('"\n')
     53 + cmdline_lsm = "lsm={}".format(",".join(lsms))
     54 + if modified_cmdline == "":
     55 + modified_cmdline = cmdline_lsm
     56 + else:
     57 + modified_cmdline += " " + cmdline_lsm
     58 + modified_cmdline = 'GRUB_CMDLINE_LINUX="{}"\n'.format(modified_cmdline)
     59 + 
     60 + content.insert(idx, modified_cmdline)
     61 + 
     62 + print("".join(content))
     63 + 
     64 + 
     65 +if __name__ == "__main__":
     66 + main()
     67 + 
Please wait...
Page is in error, reload to recover