Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Landlock v1.1 #7688

Closed
wants to merge 2 commits into from
Closed

Landlock v1.1 #7688

wants to merge 2 commits into from

Conversation

regit
Copy link
Contributor

@regit regit commented Aug 3, 2022

Initial implementation of landlock support for Suricata.

Link to redmine ticket: https://redmine.openinfosecfoundation.org/issues/5479

Describe changes:

  • Add landlock support
  • Document it

regit added 2 commits August 3, 2022 14:23
This patch is adding support for Landlock, a Linux
Security Module available since Linux 5.13.

The concept is to prevent any file operation on directories where
Suricata is not supposed to access.

Landlock support is built by default if the header is present. The
feature is disabled by default and need to be activated in the YAML
to be active.

Landlock documentation: https://docs.kernel.org/userspace-api/landlock.html

Feature: OISF#5479
@codecov
Copy link

codecov bot commented Aug 3, 2022

Codecov Report

Merging #7688 (3cbe7f0) into master (f3d3274) will increase coverage by 0.06%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #7688      +/-   ##
==========================================
+ Coverage   75.88%   75.94%   +0.06%     
==========================================
  Files         659      660       +1     
  Lines      185668   185673       +5     
==========================================
+ Hits       140893   141013     +120     
+ Misses      44775    44660     -115     
Flag Coverage Δ
fuzzcorpus 60.74% <0.00%> (+0.14%) ⬆️
suricata-verify 52.57% <100.00%> (-0.02%) ⬇️
unittests 60.71% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

@suricata-qa
Copy link

Information: QA ran without warnings.

Pipeline 8474

Copy link

@l0kod l0kod left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

I guess you would like to squash non-doc related changes from the second commit to the first. ;)

src/util-landlock.c Show resolved Hide resolved
}
}

ConfNode *read_dirs = ConfGetNode("landlock.directories.read");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know Suricata enough, but couldn't these directories be inferred by other configurations (implicit rather than explicit)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is possible to specify full path in signature for example for dataset, lua script. As a user can't really rewrite the signatures, this feature is needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we can talk about the thread model. If we trust the config (+rules etc) at startup, we might be able collect all the paths we open and then lock things afterwards? Then we'd protect against runtime exploitation of some kind.

If we want to protect the config/rule loading stage as well we couldn't use this.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, and we could do both: a first layer of generic rules to forbid everything that a lua script should never be allowed to do (e.g., create block/char devices, read sensitive files, write new rules…), and a second (standalone) layer taking into account the explicit scripts/rules requirements. Being able to not ask users to explicitly configure sandboxing should be preferred to get a wide adoption.

- @e_logdir@
- @e_rundir@
read:
- /usr/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't /usr and /etc be inferred from the installation paths?

Copy link
Contributor Author

@regit regit Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did put it there as a feature like filemagic is reading its config file in /etc and load things from /usr/. And this is independent from my build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is some thing like /usr/*/magic.mgc possible here?

Copy link
Contributor Author

@regit regit Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've got a nightmare of links on debian to access to this file. I don't think we can do something else than directory with landlock and certainly not a blob.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All glob/regex resolution is the job of user space, and it is then freeze once loaded in the kernel.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha. Trick with libmagic is that to maximize portability we by default don't specify a path to the magic file. The library will then load from a default value that differs between OS'/distros. I haven't seen a way to retrieve the path that it uses.

enabled: no
directories:
write:
- @e_logdir@
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't the log and run directory be a static/define string?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the are set by --sysconfdir and --localstatedir, e.g. ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These values it can be overwritten from configuration file so I prefer to have them here. For the log directory @jasonish remark on -l usage makes sense and it could be better to avoid to add it in the configuration.

Copy link
Contributor Author

@regit regit Aug 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got in down to in the MR to come

  directories:
    #write:
    #  - @e_rundir@
    read:
      - /usr/
      - /etc/
      - @e_sysconfdir@

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the are set by --sysconfdir and --localstatedir, e.g. ./configure --prefix=/usr --sysconfdir=/etc --localstatedir=/var

By static/define I meant C static or #define strings that could be populated by the ./configure command at build time.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I got in down to in the MR to come

  directories:
    #write:
    #  - @e_rundir@
    read:
      - /usr/
      - /etc/
      - @e_sysconfdir@

Great to not have to worry about write permissions!

/usr and /etc could maybe be inferred from a build configuration, maybe a new one with these paths as default values? I think it would be OK if users only had to specify such paths when they have a non-standard installation or distro.

src/util-landlock.c Show resolved Hide resolved
Copy link
Member

@jasonish jasonish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall I like this idea. Reminds me a bit of pledge on OpenBSD.

At some point I wonder if it makes sense to just do as much as possible automatically by default? Outside of Lua scripts and plugins, we know what we need to read and write.

Is read of /usr/ required for shared libraries and such?

doc/userguide/configuration/landlock.rst Show resolved Hide resolved
src/util-landlock.h Show resolved Hide resolved
src/util-landlock.c Show resolved Hide resolved
src/util-landlock.c Show resolved Hide resolved
@victorjulien
Copy link
Member

Thanks for jumping for review @l0kod !

@regit
Copy link
Contributor Author

regit commented Aug 3, 2022

Nice!

I guess you would like to squash non-doc related changes from the second commit to the first. ;)

Damn, the clang rewrite script did screw me up once more.

@victorjulien
Copy link
Member

victorjulien commented Aug 3, 2022

Nice!
I guess you would like to squash non-doc related changes from the second commit to the first. ;)

Damn, the clang rewrite script did screw me up once more.

git rebase master -x 'git clang-format HEAD' works well for me. Any change it makes can be commited as git commit -a --amend.

@regit
Copy link
Contributor Author

regit commented Aug 3, 2022

Overall I like this idea. Reminds me a bit of pledge on OpenBSD.

At some point I wonder if it makes sense to just do as much as possible automatically by default? Outside of Lua scripts and plugins, we know what we need to read and write.

Is read of /usr/ required for shared libraries and such?

Yes, it is needed for libmagic at least who wants /etc and /usr. Maybe this is the only one.

@l0kod
Copy link

l0kod commented Aug 4, 2022

About LANDLOCK_ACCESS_FS_REFER, you need to make sure it is not required by Suricata to (hard)link or rename files from/to different hierarchies. If it is legitimate for Lua scripts to do so, then we could defer the choice to enable Landlock with ABI 1 to users or infer from the Lua scripts. If it may be legitimate to do so for a default Suricata installation, you should abort sandboxing if the Landlock ABI is 1 (which would deny such actions except if the source/destination are in the same directory).

I guess link and rename actions are not common for most applications, but we should keep this in mind.

LANDLOCK_ACCESS_FS_REFER was a bit complex to implement securely, then the incremental development, which is the reason why renaming/linking was partially restricted at first. This access right (and the lifted limitation) is supported since Linux 5.19.

TL; DR: If Suricata might legitimately rename or link files to different directories, you should consider only using Landlock with ABI >= 2.

See https://www.kernel.org/doc/html/latest/userspace-api/landlock.html#file-renaming-and-linking-abi-1

@regit regit closed this Aug 4, 2022
@regit regit reopened this Aug 4, 2022
@regit
Copy link
Contributor Author

regit commented Aug 4, 2022

About LANDLOCK_ACCESS_FS_REFER, you need to make sure it is not required by Suricata to (hard)link or rename files from/to different hierarchies. If it is legitimate for Lua scripts to do so, then we could defer the choice to enable Landlock with ABI 1 to users or infer from the Lua scripts. If it may be legitimate to do so for a default Suricata installation, you should abort sandboxing if the Landlock ABI is 1 (which would deny such actions except if the source/destination are in the same directory).

I guess link and rename actions are not common for most applications, but we should keep this in mind.

LANDLOCK_ACCESS_FS_REFER was a bit complex to implement securely, then the incremental development, which is the reason why renaming/linking was partially restricted at first. This access right (and the lifted limitation) is supported since Linux 5.19.

TL; DR: If Suricata might legitimately rename or link files to different directories, you should consider only using Landlock with ABI >= 2.

See https://www.kernel.org/doc/html/latest/userspace-api/landlock.html#file-renaming-and-linking-abi-1

OK, this could be really an issue with files extraction, I need to test that.

@l0kod
Copy link

l0kod commented Aug 4, 2022

OK, this could be really an issue with files extraction, I need to test that.

You can test that behavior by just removing LANDLOCK_ACCESS_FS_REFER from handled_access_fs (and then allowed_access).

@regit
Copy link
Contributor Author

regit commented Aug 4, 2022

OK, this could be really an issue with files extraction, I need to test that.

You can test that behavior by just removing LANDLOCK_ACCESS_FS_REFER from handled_access_fs (and then allowed_access).

OK, I run a 5.18 and I got:

[68938] 4/8/2022 -- 16:43:59 - (output-filestore.c:144) <Warning> (OutputFilestoreFinalizeFiles) -- [ERRCODE: SC_WARN_RENAMING_FILE(303)] - Failed to rename /tmp/ddd//filestore/tmp/file.1 to /tmp/ddd//filestore/01/010f5a2db9b9ce1e8a9e0ae6837f8fb208f825423ab35aac09c26e3d2b3d4aef: Invalid cross-device link
[68942] 4/8/2022 -- 16:43:59 - (output-filestore.c:144) <Warning> (OutputFilestoreFinalizeFiles) -- [ERRCODE: SC_WARN_RENAMING_FILE(303)] - Failed to rename /tmp/ddd//filestore/tmp/file.2 to /tmp/ddd//filestore/ef/ef7239c674fd380fc2d8713d0fd82be91e543b7562ccfdffce3357819be1fd2c: Invalid cross-device link

So it makes sense for now to disable landlock if abi is 1 and filestore is enabled.

@l0kod
Copy link

l0kod commented Aug 4, 2022

So it makes sense for now to disable landlock if abi is 1 and filestore is enabled.

Usually, tools copy files instead of renaming or linking them when these syscalls return EXDEV (e.g. mv), but in the case of filestore I agree with these conditions when not to use Landlock.

@victorjulien
Copy link
Member

So it makes sense for now to disable landlock if abi is 1 and filestore is enabled.

Usually, tools copy files instead of renaming or linking them when these syscalls return EXDEV (e.g. mv), but in the case of filestore I agree with these conditions when not to use Landlock.

Is this related? https://redmine.openinfosecfoundation.org/issues/3003

Wonder if it could make sense to optionally support this using a copy logic.This would be at the cost of perf, but the trade off might be worth it to some?

@l0kod
Copy link

l0kod commented Aug 4, 2022

Is this related? https://redmine.openinfosecfoundation.org/issues/3003

Wonder if it could make sense to optionally support this using a copy logic.This would be at the cost of perf, but the trade off might be worth it to some?

Indeed, that might be interesting. Renaming and linking will always be faster than a copy, but the cost could be small using in-kernel copy such as sendfile or splice, especially with tmpfs.

@regit regit mentioned this pull request Aug 4, 2022
3 tasks
@regit
Copy link
Contributor Author

regit commented Aug 4, 2022

Replaced by #7696

@regit regit closed this Aug 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

5 participants