9

On RHEL/CentOS 7 I'm trying to create a new SELinux security context for files to support a new service that I'm writing.

I've created a Type Enforcement file for my new service, but I can't manage to create a new type that the system will recognize as a file type.

I'm working based on this CentOS 5 "Building a local policy module" document, which instructs me to create a TE file then use checkmodule and semodule_package to compile it.

If I just write in my TE file:

type myservice_spool_t;

then the TE compiles fine, but when I try to semanage fcontext I get this:

$ sudo semanage fcontext -a -t myservice_spool_t "/var/spool/myservice(/.*)?" 
ValueError: Type myservice_spool_t is invalid, must be a file or device type

I've read various tutorials but failed to find an example that works - everything I look at is either:

  • outdated - e.g. This RHEL 4 SELinux documentation page says that one should use type myservice_spool_t, file_type; but checkmodule says: ERROR 'attribute file_type is not declared'
  • incomplete - e.g. this answer will have me use the macro file_type() but checkmodule says: ERROR 'This block has no require section.' at token 'files_type'
  • or completely missing - e.g. the new SELinux guide for RHEL 7 does not have any information on how to create new policies, except using audit2allow.

The SELinux project website is completely useless as I failed to locate a single working example

I'd appreciate a simple concise example of how to write a TE file that introduces a new type that semanage fcontext will approve of.

[Update]

I found this Gentoo documentation for creating policy files, which some useful explanations and examples.

Guss
  • 2,520
  • 5
  • 32
  • 55
  • Try https://fedoraproject.org/wiki/PackagingDrafts/SELinux#Creating_new_types, or Dan Walsh's blog http://danwalsh.livejournal.com. – user9517 Oct 02 '16 at 19:52

3 Answers3

3

I found out that the problem I was having is because I didn't compile the module correctly. As a result the macros probably didn't "take" and the checkmodule policy compiler error messages didn't really help to understand that.

To get all these macros to expand properly, one needs to compile the policy using the Makefiles provided by SELinux - with a TE file called myservice_spool.te, one should execute:

make -f /usr/share/selinux/devel/Makefile myservice_spool.pp

This will create a temporary TE file with all macros expanded, then call the relevant compilers to create myservice_spool.pp.

The Gentoo documentation linked in the OP has slightly more information, though the file paths are not correct for CentOS systems.

If you review the generated TE template in the tmp directory (that the SELinux makefile helpfully leaves in place), you can see that "attributes" is indeed the correct way to handle specifying a type as a file, butwe must require them to get them to work - the way SELinux TE files appear to work is that you don't get any symbols magically imported into the configuration file - you have to require anything you use.

So the correct non-macroified way to set up a new file type is something like this (copied from the TE generated template):

type myservice_spool_t;
require {
    attribute spoolfile;
    attribute file_type, non_security_file_type, non_auth_file_type;
} # end require
typeattribute myservice_spool_t file_type, non_security_file_type, non_auth_file_type, spoolfile;
Guss
  • 2,520
  • 5
  • 32
  • 55
  • That didn't work. `# make -f /usr/share/selinux/devel/Makefile` `mailcaptcha.pp Compiling targeted mailcaptcha module /usr/bin/checkmodule: loading policy configuration from tmp/mailcaptcha.tmp mailcaptcha.te":2:ERROR 'Building a policy module, but no module specification found.` – Chloe Jan 19 '17 at 05:10
  • It sounds like you don't have a `te` file, or it is not properly formatted. Do you mind sharing your file? – Guss Jan 19 '17 at 08:29
  • I don't have the original file I tried, but here is my latest attempt and the latest error: http://pastebin.com/JyEEi6dP – Chloe Jan 19 '17 at 16:48
  • The problem is at your code in line 9, not like the error report says. I'm not sure why it behaves that way, it could be about the order of the type declaration and the `require` that is different in my example. But anyway I suggest that you don't use my example, because - as I've wrote - its not a code, its an output from the pre-processor. you should use a macro like Mathew answered in his comment to your question. – Guss Jan 26 '17 at 17:18
  • Oh my goodness, thank you so much. I was having exactly the same issue as you and couldn't find any documentation on custom selinux modules and types that wasn't horribly outdated. – jayhendren Dec 05 '18 at 18:37
1

You need to declare it a member of the files attribute such that it has relabel privileges.

Try

type myservice_spool_t;
files_type(myservice_spool_t)

Or better in your case..

type myservice_spool_t;
files_spool_file(myservice_spool_t)

Given you are actually making a spool file. This gives other macros the ability to work with that spool if they have 'manage spool' privileges in their policy.

Heres a complete policy module example.

policy_module(`myservice', 1.0.0)

type myservice_spool_t;
files_spool_file(myservice_spool_t)

This would work, but only declare the type and thats that. You'd need some allow rules to make it do something worthwhile.

Matthew Ife
  • 22,927
  • 2
  • 54
  • 71
  • 2
    As I've mentioned in the question, I tried that and it doesn't work. With the new macro I still get this error: `myservice_spool.te:4:ERROR 'This block has no require section.' at token 'files_spool_file' on line 4:` – Guss Oct 03 '16 at 05:42
  • 3
    BTW: where can one find documentation for all these macros, or even the source? Googling for the very specific `files_spool_file` I get only a handful of results, which are all either source dumps of scripts using it, bug reports or mailing list posts. It seems like SELinux policies is a collection of magic incantations, held together by spitballs, duct tape and "its working, don't touch". – Guss Oct 03 '16 at 05:50
  • I found my problem - which was not about what macro to write, but how to compile the module. – Guss Oct 03 '16 at 06:22
  • 1
    That didn't work. `# checkmodule mailcaptcha.te checkmodule: loading policy configuration from mailcaptcha.te mailcaptcha.te:1:ERROR 'syntax error' at token 'type' on line 1: checkmodule: error(s) encountered while parsing configuration # cat mailcaptcha.te type mailcaptcha_t; files_type(mailcaptcha_t);` – Chloe Jan 19 '17 at 04:55
  • Given you've not declared it a policy module I'm not surprised. You need to fill out the type enforcement file as per normal standards and add that. – Matthew Ife Jan 19 '17 at 11:17
  • @MatthewIfe could you please elaborate on what you mean by "fill out the type enforcement file as per normal standards and add that"? I'm really struggling to find up-to-date, complete documentation on this subject. – jayhendren Dec 05 '18 at 18:10
  • @jayhendren I've updated my answer with a more complete module. – Matthew Ife Dec 05 '18 at 20:34
-1

https://selinuxproject.org/page/TypeStatements has the correct answer:

# Using the typeattribute statement to associate a type of
# setroubleshootd_exec_t to two attributes file_type and 
# non_security_file_type. 

# These are the previously declared attributes:
attribute file_type;
attribute non_security_file_type;

# The previously declared type:
type setroubleshootd_exec_t;

# These are the associations using the typeattribute statement:
typeattribute setroubleshootd_exec_t file_type, non_security_file_type;

But, yes, your question raises an interesting point.

SELinux natively knows three languages, and there is one third party abstraction language called "Reference policy".

  1. Monolitic policy language (checkpolicy is used to compile policy.conf -- man checkpolicy)
  2. Module policy language (checkmodule is used to compile $MODULE.{te.fc} -- man checkmodule)
  3. Common Intermediate Language (secilc is used to compile $MODULE.cil -- man secilc)

Each of the above native languages has its own specific properties, and it can be confusing.

Reference policy is basically a wrapper around "Module policy language" with the goal to make policy maintenance easier.

user9517
  • 114,104
  • 20
  • 206
  • 289
  • My misunderstanding was mostly that the fact something has been defined in the system, such as the `file_type` attribute, does not mean that it is defined for my policy file - I have to basically redefine it (or is it "reference it") in my policy file so I can use it. And that I didn't see explained anywhere, including in Stack Exchange answers. – Guss Oct 12 '16 at 11:04
  • This doesn't explain how to compile it. Neither `make` nor `checkmodule` works. `# make -f /usr/share/selinux/devel/Makefile \n mailcaptcha.pp Compiling targeted mailcaptcha module /usr/bin/checkmodule: loading policy configuration from tmp/mailcaptcha.tmp mailcaptcha.te":2:ERROR 'Building a policy module, but no module specification found.` – Chloe Jan 19 '17 at 05:15