Skip to main content

SELinux: How to create a CIL from a TE file

For a project, I needed to compile and install a SELinux module only when necessary. Unfortunatelly, there is no versioning on stored modules; I can't check and compare with the source module. I came up with an idea: using MD5 signatures.

Modules are stored in /var/lib/selinux/Policy/active/modules/400/ModuleName/cil
The Policy can be found with sestatus:

# sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             targeted
...
  
Stored modules are actually compressed CIL, which can easily been dumped with bzcat:
# bzcat /var/lib/selinux/targeted/active/modules/400/my-httpd/cil
(typeattributeset cil_gen_require httpd_t)
(typeattributeset cil_gen_require default_t)
(typeattributeset cil_gen_require sysstat_log_t)
(typeattributeset cil_gen_require usr_t)
(allow httpd_t usr_t (file (write create unlink setattr)))
(allow httpd_t default_t (file (open read)))
(allow httpd_t sysstat_log_t (dir (add_name write)))
(allow httpd_t sysstat_log_t (file (open create)))
Piping the result to md5sum provides a signature.

The trickiest part is transforming the source (a .te file) to a CIL. A TE files looks like:

module my-httpd 1.2;

require {
        type httpd_t;
        type default_t;
        type sysstat_log_t;
        type usr_t;
        class dir { add_name write };
        class file { open read write create unlink setattr };
}
#============= httpd_t ==============
allow httpd_t usr_t:file { write create unlink setattr };
allow httpd_t default_t:file { open read };
allow httpd_t sysstat_log_t:dir { add_name write };
allow httpd_t sysstat_log_t:file { create open };
Hopefully, both syntax are similar, so the transformation can be achieved via sed with this simple program:
# remove semi-columns
s/;//g

# remove comments
s/#.*$//g        

# turn multiple space chars into one
s/[ \t]\+/ /g    

# remove leading and trailing spaces
s/^ \+\| \+$//   

# Turn { to (
s/ *{ */ (/      

# Turn } to )
s/ *}/)/         

# For each declaration of new type, add a line with the typeattribute,
# another line with the typeattributeset and a third line with the type.
s/^type \(.\+_t\), *\(.\+\)/(typeattribute \2)\n(typeattributeset \2 (\1))\n(type \2)/

# Turn the declaration of a existing type to a typeattributeset
s/^type \(.\+_t\)/(typeattributeset cil_gen_require \1)/

# Rule with 3 levels
s/^\(allow\|deny\|dontaudit\) *\(.\+_t\) \(.\+\):\(.\+\) \((.\+)\)/(\1 \2 \3 (\4 \5))/

# Rule with 4 levels
s/^\(allow\|deny\|dontaudit\) *\(.\+_t\) \(.\+\):\(.\+\) \(.\+\)/(\1 \2 \3 (\4 (\5)))/

# Remove any space before )
s/ \+)/)/g

# Remove lines not starting with (
/^(/!d           
Then, to turn the TE into CIL, simply do:
# sed -f te2cil.sed source-module.te 
However, another issue arose: the order of attributes within a class.
(allow ... (file (open create)))
will not provide the same signature as
(allow ... (file (create open)))
.
Sure enough, I could check all my sources and make sure the attributes are in alphabetical order, but I always prefer automation. So I came up with this awk file which does the trick:
NF>4 {  gsub(/\(|\)/,"");
        for(i=5;i<=NF;i++) A[i-5]=$i;
        n=asort(A);
        C="";
        for(i=5;i<=NF;i++)C=C" "A[i-4];
        delete A;
        print "("$1,$2,$3" ("$4,"("substr(C,2)")))"
}
Hence, getting the signature of the CIL becomes:
# sed -f te2cil.sed source-module.te | awk -f te2cil.awk | sort | md5sum

Finally, I make sure to sort the stored module as well:

# bzcat /var/lib/selinux/targeted/active/modules/400/my-httpd/cil | sed -f te2cil.sed | awk -f te2cil.awk | sort | md5sum

Comments

Popular posts from this blog

Update to Ubuntu 24.04

After years running Ubuntu 20.04, I recently (January 2025) installed Ubuntu 24.04 Noble Numbat. This cames with few improvements and a couple of disappointments, mainly the lost of my dual-screen: my graphic card, Nvidia Quadro FX3700, is not supported anymore by the latest driver. The result is: when the computer boots up, it does on output 0 (right screen). But as soon as Wayland starts, it switches to output 1 (left screen), ignoring the other output; my right screen remains black. This is a new behavior, it works fine on 20.04. Keyboard I write mainly in French and English. My keyboard is US Qwerty with US International layout. In English, what I see on keyboard is what I get on screen. In French, the diacritics are obtained with compositional keys: To get Ubuntu 20 Ubuntu 24 á é í ó ú ý Á É Í Ó Ú Ý ' e (Quote letter) ' E (Quote shift+letter) à è ...

Drive replacement for Fostex DMT8-vl

The IDE hard drive on my Fostex DMT8-vl multitrack recorder shows signs of its imminent death; when getting hot, I could not record anymore. Must be said this drive comes from an old Sun Station, and has been replaced because I/O failures were detected by Solaris. It worked at least 5 years in my recorder: not so bad. However, time is now to replace it. The DMT8-vl is not able to handle drives bigger than 8.4 GB. Well, it is able to (the current drive is 15 GB), but only 8.4 GB will be usable. My tought was to use a 8 GB CompactFlash; having no moving parts means no noise, which is quite temptating for a music recording device. I purchased a CompactFlash-IDE adapter on the internet (8$) and I had to build a male-male IDE cable adapter (4$). Unfortunately, this doesn't work. The drive is correctly discovered by the operating system, which proposes to format it ("format IDE?"). After answering "yes", the formating runs pretty fast (faster than on a real drive), ...

My journey with ATtiny4313 (part 1)

Introduction The context For a personal project, I want to program an Atmel ATtiny4313 microcontroller. I use microcontrollers for several years, but not on a regular basis (maybe 3-4 times a year), mostly for testing and generally with a deceptive result. But failure isn't the best training? This article aims to share my errors and success, as well as being a personal log. The project The project is to replace the main board of a Soundpool MO4, a MIDI OUT extension for the Atari ST; details here . Overall, the project is pretty simple: reading the parallel port and copy verbatim the data to MIDI out. This is the reason behind my choice of this particular microcontroller, since it embeds an USART and has an 8 bits parallel port (20 pins DIP package). The MO4 having 4 MIDI Outs, I will use 4 ATTiny4313, one for each out; this is actually cheaper than finding a 4-channel USART. Each microcontroller must determine if the data present on the parallel port shoul...