Justin Mattock | 1 Sep 2008 01:34
Picon

checkpolicy: error(s) encountered while parsing configuration

when loading the latest refpolicy I'm seing a
policy/modules/kernel/kernel.te":237:ERROR 'syntax error' at token 'corenet_raw_
corenet_raw_send_multicast_node(kernel_t)

not sure if this is checkpolicy or refpolicy
--

-- 
Justin P. Mattock

Hong | 1 Sep 2008 02:32
Picon

Re: checkpolicy: error(s) encountered while parsing configuration

Hi,

I also found the same problem.  I downloaded refpolicy source and tried to compile it under ubuntu 8.04.  Looks like corenet_raw_send_multicast_node is an interface(or macro?).  And it is not defined anywhere.

Hong

On Sun, Aug 31, 2008 at 7:34 PM, Justin Mattock <justinmattock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
when loading the latest refpolicy I'm seing a
policy/modules/kernel/kernel.te":237:ERROR 'syntax error' at token 'corenet_raw_
corenet_raw_send_multicast_node(kernel_t)

not sure if this is checkpolicy or refpolicy
--
Justin P. Mattock

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo-+05T5uksL2qpZYMLLGbcSA@public.gmane.org with
the words "unsubscribe selinux" without quotes as the message.

Murray McAllister | 1 Sep 2008 02:59
Picon
Favicon

Re: user guide draft: "Introduction" review

Stephen Smalley wrote:

[snip]

>>
>> -rwxrw-r--  user1 group1 unconfined_u:object_r:user_home_t:s0      file1
>>
>> In this example, SELinux provides a user (unconfined_u), a role 
>> (object_r), a type (user_home_t), and a category (s0). 

Should this be, "...and a level (s0)"?

Justin P. Mattock | 1 Sep 2008 02:50
Picon

Re: checkpolicy: error(s) encountered while parsing configuration

Maybe there is an updated package
For this, other than that I just used
The .tar.bz2 and everything works
Fine.

justin P. Mattock



On Aug 31, 2008, at 5:32 PM, Hong <kindloaf-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:

Hi,

I also found the same problem.  I downloaded refpolicy source and tried to compile it under ubuntu 8.04.  Looks like corenet_raw_send_multicast_node is an interface(or macro?).  And it is not defined anywhere.

Hong

On Sun, Aug 31, 2008 at 7:34 PM, Justin Mattock <justinmattock-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
when loading the latest refpolicy I'm seing a
policy/modules/kernel/kernel.te":237:ERROR 'syntax error' at token 'corenet_raw_
corenet_raw_send_multicast_node(kernel_t)

not sure if this is checkpolicy or refpolicy
--
Justin P. Mattock

--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo-+05T5uksL2qpZYMLLGbcSA@public.gmane.org with
the words "unsubscribe selinux" without quotes as the message.

James Morris | 1 Sep 2008 07:04
Favicon

Re: user guide draft: "Introduction" review

On Mon, 1 Sep 2008, Murray McAllister wrote:

> Stephen Smalley wrote:
> 
> [snip]
> 
> > > 
> > > -rwxrw-r--  user1 group1 unconfined_u:object_r:user_home_t:s0      file1
> > > 
> > > In this example, SELinux provides a user (unconfined_u), a role
> > > (object_r), a type (user_home_t), and a category (s0). 
> 
> Should this be, "...and a level (s0)"?

It's a sensitivity.

Security level = sensitivity + 0 or more categories.

- James
--

-- 
James Morris
<jmorris@...>

KaiGai Kohei | 1 Sep 2008 08:26
Picon

Re: [PATCH 3/3] Thread/Child-Domain Assignment (rev.4)

Joshua Brindle wrote:
> KaiGai Kohei wrote:
>> Joshua Brindle wrote:
>>> KaiGai Kohei wrote:
>>>> The following patch is revised one for libsepol.
>>>>
>>>> Updates:
>>>>  - The properties of type_datum are packed within the third word of
>>>>    type entries in the kernel policy.
>>>>    The first bit (TYPEDATUM_PROPERTY_PRIMARY) means the entry is a
>>>>    primary type, and the second bit (TYPEDATUM_PROPERTY_ATTRIBUTE)
>>>>    means the entry is an attribute.
>>>>
>>> I didn't see an answer in the current threads, and this looks like
>>  > the latest userland patch series so I'll ask here: What is
>> the purpose  > of the properties? We can infer what it knows
>> from the other fields
>>> in the datum, right?
>> Stephen said as follows:
>> http://marc.info/?l=selinux&m=121882413424973&w=2
>>
>>> Keeping the type attribute names in the types symtab in the kernel
>>> policy allows tools like audit2why and apol to extract the original
>>> attribute names and display them.  I originally shed them because the
>>> kernel didn't need to use that information and we don't want
>>> attribute names to be used in security contexts, but it costs us
>>> little to save them and check for them, and it benefits the tools.
> 
> No, I got that part. What I was missing was that we identified
> attributes differently in modules and kernel policy now, kind of
> confusing.

I see, modular policy format now has "primary", "flavor" and "flags"
members to identify its properties. It is different from newer kernel
policy format.

>> The type_datum has the following format in the newer kernel policy:
>>
>>   +0 +-------------------------+
>>      | length of name          |
>>   +4 +-------------------------+
>>      | type identifier value   |
>>   +8 +-------------------------+
>>      | property bits           | <--- TYPEDATUM_PROPERTY_PRIMARY
>> +12 +-------------------------+      TYPEDATUM_PROPERTY_ATTRIBUTE
>>      | bounds type identifier  |
>> +16 +-------------------------+
>>      | text representation of  |
>>      | name (variable length)  |
>>      +-------------------------+
>>
>> Any property bits are packed within the third field.
>>
> 
> I don't see that in the libsepol patch:
> 
>  <at>  <at>  -145,8 +146,16  <at>  <at> 
>  	ebitmap_t types;	/* types with this attribute */
>  #define TYPE_FLAGS_PERMISSIVE	0x01
>  	uint32_t flags;
> +	uint32_t bounds;	/* bounds type, if exist */
>  } type_datum_t;

Are you saying members within type_datum_t should have one-to-one mapping
with its disk format? If so, it is the most straightforward approach to
add a "flavor" member for the disk format of kernel policy.

I guess your opinion is that smaller differences between kernel and
modular policy format is better. If so, what do you think about an idea
which packs all properties of a type into a property bits members.
We need 1 bit for "primary" property, 2 bits for "flavor" and 1 bit for
"permissive", so it is enough to store them into a 32bits variable.

In this case, the format of type_datum is changed as follows:

  + 0 : length of name (unchanged)
  + 4 : type identifier value (unchanged)
  + 8 : property bits which can have following bits
  +12 : bounds type identifier (newly added)
  +16 : ebitmap of attributes (modular only/unchanged)
  +XX : text representation of type name
  (*) flavor in modular policy format is deprecated.

Thanks,
--

-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@...>

Murray McAllister | 1 Sep 2008 09:03
Picon
Favicon

Re: user guide draft: "SELinux Contexts and Attributes" review

Cheers. Comments inline:

Stephen Smalley wrote:
> On Wed, 2008-08-27 at 16:54 +1000, Murray McAllister wrote:
>> Hi,
>>
>> The following is a draft of the SELinux Contexts and Attributes sections 
>> for the SELinux User Guide. Any comments and corrections are appreciated.
>>
>> Thanks.
>>
>> As previously mentioned, on Linux operating systems, files, directories, 
>> sockets, devices, and so on, are called objects, and processes, such as 
>> a user running a command, the Firefox application, and the Apache HTTP 
>> Server, are called subjects.
> 
> As before, this is generally true of operating systems not just Linux.
> 
>>  SELinux provides the Type Enforcement 
>> security model.
> 
> SELinux provides flexible MAC that can support many different security
> models, and the example security server included in SELinux provides a
> combination of role-based access control (RBAC), Type Enforcement (TE),
> and optionally Multi-Level Security (MLS).

How about:

...SELinux provides flexible MAC that supports a variety of different 
security models. On Fedora 10, SELinux provides a combination of 
role-based access control (RBAC), Type Enforcement® (TE), and 
optionally, Multi-Level Security (MLS). Subjects and objects are labeled 
with an SELinux context that contains additional information, such as an 
SELinux user, role, and a type. When running SELinux, all of this 
information is used to make access control decisions.

> 
>>  To enforce this, subjects and objects are labeled with 
>> an SELinux context that contains additional information, such as an 
>> SELinux user, role, and type. When running SELinux, all of this 
>> information is used to make access control decisions.
>>
>> The following is an example of the additional SELinux information used 
>> on Linux operating systems that use SELinux. This information is called 
>> the SELinux context, and is viewed using the ls -Z command:
>>
>> -rwxrw-r--  user1 group1 unconfined_u:object_r:user_home_t:s0      file1
>>
>> SELinux contexts follow the SELinux user:role:type:category syntax:
> 
> That should be :level or :range rather than just :category, where a
> level is a sensitivity followed by an optional list of categories.

How about "...role:type:sensitivity"?

> 
>> SELinux user: The SELinux user identity is an identity known to the 
>> policy that is authorized for a specific set of roles and for a specific 
>> MLS range. Each Linux user account is mapped to an SELinux user identity 
>> when a user login session is created, and the mapped SELinux user 
>> identity is used in the security context for processes in that session 
>> in order to bound what roles and levels they can enter[1]. Run the 
>> /usr/sbin/semanage login -l command to view a list of mappings between 
>> SELinux and Linux user accounts:
>>
>> Login Name                SELinux User              MLS/MCS Range
>>
>> __default__               unconfined_u              s0-s0:c0.c1023
>> root                      unconfined_u              s0-s0:c0.c1023
>> system_u                  system_u                  s0-s0:c0.c1023
>> test2user                 user_u                    s0
>> xguest                    xguest_u                  s0
>>
>> Output may differ from system to system. The Login Name column lists 
>> Linux users, and the the SELinux User column lists which SELinux user is 
>> mapped to which Linux user. The SELinux user does not restrict the 
>> access subjects have to objects.
> 
> Well, it does indirectly, by limiting what roles and levels are
> accessible to the subject.  It also can play a role in the constraints
> portion of the policy configuration, e.g. refpolicy doesn't allow a
> process to relabel a file with a different SELinux user identity unless
> its domain has the can_change_object_identity attribute.

Output may differ from system to system. The Login Name column lists 
Linux users, and the the SELinux User column lists which SELinux user is 
mapped to which Linux user. For subjects, the SELinux user limits which 
roles and levels are accessible. The last column, MLS/MCS Range, are 
levels and categories that are used by Multi-Level Security (MLS) and 
Mutli-Category Security (MCS). MLS and MCS levels and categories are 
discussed briefly later.

Would removing "For subjects" from the 3rd sentence make it accurate?

> 
>>  The last column, MLS/MCS Range, are 
>> categories that are used by Multi-Level Security (MLS) and 
>> Mutli-Category Security (MCS). MLS and MCS categories are discussed 
>> briefly later.
>>
>> role: Part of SELinux is the Role Based Access Control (RBAC) security 
>> model. The role is an attribute of RBAC. Roles are associated with 
>> domain types, and domain types are associated with SELinux users.
> 
> SELinux users are authorized for roles, and roles are authorized for
> domain types.  Domain types are not directly associated with SELinux
> users - the role serves as an intermediary.
> 
>>  Roles 
>> are important when writing policies, as they restrict domain 
>> transitions, but they do not restrict the access subjects have to 
>> objects, and as such, they are not discussed in detail in this guide.
> 
> Not directly, but indirectly since what roles you can enter determines
> what domain types you can enter and thus ultimately what object types
> you can access.  The role is a coarse-grained boundary on privilege
> escalation.

role:
Part of SELinux is the Role Based Access Control (RBAC) security model. 
The role is an attribute of RBAC. SELinux users are authorized for 
roles, and roles are authorized for domain types. The role serves as an 
intermediary between domains types and SELinux users. The roles that can 
be entered determine which domain types can be entered - ultimately, 
this controls which object types can be accessed. This helps reduce 
vulnerability to privileged escalation attacks.

> 
>> type: The type is an attribute of Type Enforcement. The type defines a 
>> domain type for subjects, and a type for objects. SELinux policy rules 
>> define how types access each other, whether it be a domain accessing a 
>> type, or a domain accessing another domain. Access is only allowed if a 
>> specific rule exists that allows it.
>>
>> category: The category is an attribute of Multi-Level Security (MLS) and 
>> Multi-Category Security (MCS). Categories are used to categorize data, 
>> and identify its sensitivity or security level. Standard SELinux policy 
>> supports MCS; however, it is not heavily used. MCS allows users, at 
>> their own discretion, to add a category to a piece of data, for example, 
>> PatientRecord or CompanyConfidential. There is only a single security 
>> level, s0. MLS labels data with both categories (CompanyConfidential) 
>> and a sensitivity level. MLS enforces the Bell-LaPadula Mandatory Access 
>> Model, and is used in Labeled Security Protection Profile (LSPP) 
>> environments.
> 
> Again, this should be level or range rather than just category, where a
> level is a sensitivity and an optional list of categories and a range is
> a current/low level and a clearance/high level.  You may wish to note
> that people who wish to use the MLS restrictions need to install a
> separate -mls policy package and make it the default.

This part is in progress. I do not understand the difference between 
levels/categories and ranges. Can you recommend any papers or books on 
this? This is what is there now, keeping in mind I don't understand:

The level is an attribute of MLS and Multi-Category Security (MCS). 
There is a single sensitivity level, s0, which is the only sensitivity 
level used. This level is used when running the SELinux MLS policy, but 
not when running the SELinux targeted policy. An optional list of 
categories can be used to categorize data. Standard SELinux policy 
supports MCS; however, it is not heavily used. MCS allows users, at 
their own discretion, to add a category to a piece of data, for example, 
CompanyConfidential or PatientRecord. MLS labels data with both a 
sensitivity level and categories (such as CompanyConfidential). MLS 
enforces the Bell-LaPadula Mandatory Access Model, and is used in 
Labeled Security Protection Profile (LSPP) environments. To use MLS 
restrictions, install the selinux-policy-mls package, and configure MLS 
to be the default SELinux policy.

> 
>> Domain Transitions
>>
>> On Linux operating systems that run SELinux, processes, such as a user 
>> running the less command, or an Apache HTTP server, are called subjects. 
> 
> Not sure you need to keep repeating this.

Removed.

> 
>> An executable object transitions to a subject, and a subject runs in a 
>> domain. This transition is called a domain transition.
> 
> A process in one domain transitions to another domain by executing a new
> program with the entrypoint type for the new domain.

How about:

A subject in one domain transitions to another domain by executing an 
object that is labeled with a file type that has entrypoint permission 
for the new domain. The entrypoint permission is used in SELinux policy, 
and controls which domains an object can enter. The following example...

> 
>>  The following 
>> example demonstrates a domain transition:
>>
>> 1. A users wants to change their password. To change their password, 
>> they run the /usr/bin/passwd command. The /usr/bin/passwd file object is 
>> labeled with the passwd_exec_t file type:
>>
>> $ ls -Z /usr/bin/passwd
>> -rwsr-xr-x  root root system_u:object_r:passwd_exec_t:s0 /usr/bin/passwd
>>
>> The passwd application needs to access the /etc/shadow object, which is 
>> labeled with the shadow_t file type:
>>
>> $ ls -Z /etc/shadow
>> -r--------  root root system_u:object_r:shadow_t:s0    /etc/shadow
>>
>> 2. An SELinux policy rule states that subjects running in the passwd_t 
>> domain type are allowed to read and write to objects that are labeled 
>> with the shadow_t file type. The /etc/shadow object is the only object 
>> that is labeled with the shadow_t file type.
> 
> Also /etc/gshadow.  And the backup copies of both files created whenever
> they are updated (e.g. /etc/shadow-).  And any intermediate files
> created during the update transaction that contain any shadow password
> data - the point is that any file containing such data ought to be
> labeled with the shadow_t type so that it can be consistently protected
> throughout.

An SELinux policy rule states that subjects running in the passwd_t 
domain type are allowed to read and write to objects that are labeled 
with the shadow_t file type. Only objects and their back up copies that 
are required for a password change, such as /etc/gshadow, /etc/gshadow- 
and /etc/shadow, are labeled with the shadow_t file type.

> 
>> 3. When a user runs the /usr/bin/passwd command, the application 
>> transitions to a subject (a process), which is running in the passwd_t 
>> domain type.
> 
> The user shell process transitions to the passwd_t domain upon executing
> the /usr/bin/passwd command.

When a user runs the /usr/bin/passwd command, the user's shell process 
transitions to the passwd_t domain type.

> 
>>  With SELinux, since the default action is to deny, and a 
>> rule exists that allows (among other things) applications running in the 
>> passwd_t domain type to access objects labeled with the shadow_t file 
>> type, the passwd application is allowed to access /etc/shadow, and 
>> update the user's password.
>>
>> This example is not exhaustive, and is used as a basic example to 
>> explain domain transition. Although there is an actual rule that allows 
>> subjects running in the passwd_t domain type to access objects labeled 
>> with the shadow_t file type, other rules must be met before the object 
>> can successfully transition.
> 
> Not sure what you mean by "the object can successfully transition" -
> processes transition from one domain to another upon executing a new
> program.

...other SELinux policy rules must be met before the subject can 
transition to a new domain.

> 
> In the passwd example, the guarantees we are getting from Type
> Enforcement are:
> - Only authorized domains (e.g. passwd_t) can write to shadow password
> data (shadow_t).  Other processes, even superuser ones, cannot do so.
> - The passwd_t domain can only be entered by executing a program labeled
> with passwd_exec_t, can only execute from authorized shared libraries
> (e.g. lib_t) and cannot execute any other programs.  Thus, we can have
> some confidence that only authorized code is ever executed in passwd_t.
> - Only authorized domains (e.g. user_t) can transition to passwd_t.
> Thus, a daemon like sendmail_t that has no legitimate reason to ever run
> passwd cannot ever reach passwd_t.
> - passwd_t can only read and write authorized types (e.g. etc_t,
> shadow_t).  Thus, it cannot be tricked into reading or writing arbitrary
> files.

In this example, Type Enforcement ensures:

* The passwd_t domain can only be entered by executing an object labeled 
with the passwd_exec_t file type; can only execute from authorized 
shared libraries, such as the lib_t file type; and can not execute any 
other objects.

* Only authorized domains, such as passwd_t, can write to objects 
labeled with the shadow_t file type. Even if other subjects are running 
with superuser privileges, those subject can not write to objects 
labeled with the shadow_t file type, as they are not running in the 
passwd_t domain.

* Only authorized domains can transition to the passwd_t domain. For 
example, the sendmail subject running in the sendmail_t domain does not 
have a legitimate reason to run /usr/bin/passwd; therefore, it can never 
transition to the passwd_t domain.

* Subjects running in the passwd_t domain type can only read and write 
authorized types, such as objects labeled with the etc_t or shadow_t 
file types. This prevents the passwd application from being tricked into 
reading or writing arbitrary files.

> 
>> SELinux Contexts for Subjects
>>
>> On Linux operating systems the run SELinux, when an application is 
>> executed, that application transitions to a subject and runs in a 
>> domain.
> 
> Again, not sure you need to keep repeating this, and technically it is
> "the process transitions to a new domain upon executing a program with
> the entrypoint type for that domain".

Removed.

> 
>>  The SELinux context for subjects is viewed using the pstree -Z 
>> command.
> 
> Or just ps -eZ.

Changed examples to use ps -eZ.

> 
>>  For example:
>>
>> 1. Open a terminal, such as Applications → System Tools → Terminal.
>>
>> 2. Run the /usr/bin/passwd command. Do not enter a new password.
>>
>> 3. Open a new tab, or another terminal, and run the pstree -Z | grep 
>> passwd command. The output is similar to the following:
>>
>> |  |        `-passwd(`unconfined_u:unconfined_r:passwd_t:s0-s0:c0.c1023')
>>
>> 4. In the first tab, cancel passwd application.
>>
>> In this example, when the /usr/bin/passwd object, which is labeled with 
>> the passwd_exec_t file type, is executed, it transitions to a subject 
>> that runs in the passwd_t domain type. Remember: the type defines a 
>> domain type for subjects, and a type for objects.
>>
>> To view the SELinux contexts for all subjects, run the pstree -Z 
>> command. The following is an example of the pstree -Z output, and may 
>> differ on your system:
>>
>> ├─NetworkManager(`system_u:system_r:NetworkManager_t:s0')
>> │  └─{NetworkManager}(`system_u:system_r:NetworkManager_t:s0')
>> ├─acpid(`system_u:system_r:apmd_t:s0')
>> ├─anacron(`system_u:system_r:system_crond_t:s0')
>> ├─atd(`system_u:system_r:crond_t:s0-s0:c0.c1023')
>> ├─auditd(`system_u:system_r:auditd_t:s0')
>>
>>
>> By default, the SELinux targeted policy is used. When using targeted 
>> policy, most subjects (processes) use the system_r role. Type 
>> enforcement then separates each domain.
> 
> system_r is for system processes like daemons.  Targeted policy used to
> use system_r for everything and not use any user roles.  In F9, it uses
> unconfined_r for unconfined users.

The system_r role is used for system processes, such as daemons. Type 
enforcement then separates each domain.

I left user roles (unconfined_r, user_r) out, as they explained later.

Thanks again :)

KaiGai Kohei | 1 Sep 2008 11:08
Picon

[PATCH] libsepol : Add support for a new policy version (POLICYDB_VERSION_BOUNDARY)

The attached patch for libsepol add suport for a new policy version
named as (MOD_)POLICYDB_VERSION_BOUNDARY.

This version contains the following features.
- Boundary feature support:
 The upcoming kernel has a feature to define boundary relationship
 between two users, roles and types. It enables to restrict a bounded
 one can never have wider permissions than its bounds one.
 Any XXXX_datum_t structure have "u32 bounds" member to indicate its
 bounds, and we can handle it with the latest version of policy format
 provided by this patch.

- Loading attributes into kernel space:
 The upcoming kernel also allows to load entries of attribute.
 The attached patch turn off to drop them, when it tries to write
 kernel policy with its version is equal or greater than
 POLICYDB_VERSION_BOUNDARY.
 Any entries of attribute has a property of TYPEDATUM_PROPERTY_ATTRIBUTE.

- Improvement of type_datum format on kernel/modular policy.
 The type_datum entry has several its attribute fields like "primary",
 "flavor" and "flags", and these are stored within separated fields
 on-disk format. This patch enables to pack them into a single field.
 Currently four bits are defined, and rest of them are reserved.
   #define TYPEDATUM_PROPERTY_PRIMARY      0x0001
   #define TYPEDATUM_PROPERTY_ATTRIBUTE    0x0002
   #define TYPEDATUM_PROPERTY_ALIAS        0x0004  /* userspace only */
   #define TYPEDATUM_PROPERTY_PERMISSIVE   0x0008  /* userspace only */

TODO:
- Replace implementation of existing name based hierarchy checkings
  by the newer boundary feature.

Signed-off-by: KaiGai Kohei <kaigai@...>
---
 include/sepol/policydb/policydb.h |   28 +++++++-
 src/expand.c                      |  132 ++++++++++++++++++++++++++++++--------
 src/link.c                        |  108 ++++++++++++++++++++++++++++++-
 src/policydb.c                    |   72 +++++++++++++++++---
 src/write.c                       |   54 ++++++++++++---
 5 files changed, 342 insertions(+), 52 deletions(-)
---
Index: libsepol/include/sepol/policydb/policydb.h
===================================================================
--- libsepol/include/sepol/policydb/policydb.h	(revision 2950)
+++ libsepol/include/sepol/policydb/policydb.h	(working copy)
 <at>  <at>  -119,6 +119,7  <at>  <at> 
 	ebitmap_t dominates;	/* set of roles dominated by this role */
 	type_set_t types;	/* set of authorized types for role */
 	ebitmap_t cache;	/* This is an expanded set used for context validation during parsing */
+	uint32_t bounds;	/* bounds role, if exist */
 } role_datum_t;

 typedef struct role_trans {
 <at>  <at>  -145,8 +146,18  <at>  <at> 
 	ebitmap_t types;	/* types with this attribute */
 #define TYPE_FLAGS_PERMISSIVE	0x01
 	uint32_t flags;
+	uint32_t bounds;	/* bounds type, if exist */
 } type_datum_t;

+/*
+ * Properties of type_datum
+ * available on the policy version >= (MOD_)POLICYDB_VERSION_BOUNDARY
+ */
+#define TYPEDATUM_PROPERTY_PRIMARY	0x0001
+#define TYPEDATUM_PROPERTY_ATTRIBUTE	0x0002
+#define TYPEDATUM_PROPERTY_ALIAS	0x0004	/* userspace only */
+#define TYPEDATUM_PROPERTY_PERMISSIVE	0x0008	/* userspace only */
+
 /* User attributes */
 typedef struct user_datum {
 	symtab_datum_t s;
 <at>  <at>  -156,6 +167,7  <at>  <at> 
 	ebitmap_t cache;	/* This is an expanded set used for context validation during parsing */
 	mls_range_t exp_range;     /* expanded range used for validation */
 	mls_level_t exp_dfltlevel; /* expanded range used for validation */
+	uint32_t bounds;	/* bounds user, if exist */
 } user_datum_t;

 /* Sensitivity attributes */
 <at>  <at>  -595,10 +607,11  <at>  <at> 
 #define POLICYDB_VERSION_RANGETRANS	21
 #define POLICYDB_VERSION_POLCAP		22
 #define POLICYDB_VERSION_PERMISSIVE	23
+#define POLICYDB_VERSION_BOUNDARY	24

 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE
-#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_PERMISSIVE
+#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_BOUNDARY

 /* Module versions and specific changes*/
 #define MOD_POLICYDB_VERSION_BASE	   4
 <at>  <at>  -608,12 +621,23  <at>  <at> 
 #define MOD_POLICYDB_VERSION_MLS_USERS	   6
 #define MOD_POLICYDB_VERSION_POLCAP	   7
 #define MOD_POLICYDB_VERSION_PERMISSIVE	   8
+#define MOD_POLICYDB_VERSION_BOUNDARY      9

 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE
-#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_PERMISSIVE
+#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_BOUNDARY

 #define POLICYDB_CONFIG_MLS    1

+/* macros to check policy feature */
+
+/* TODO: add other features here */
+
+#define policydb_has_boundary_feature(p)			\
+	(((p)->policy_type == POLICY_KERN			\
+	  && p->policyvers >= POLICYDB_VERSION_BOUNDARY) ||	\
+	 ((p)->policy_type != POLICY_KERN			\
+	  && p->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY))
+
 /* the config flags related to unknown classes/perms are bits 2 and 3 */
 #define DENY_UNKNOWN	SEPOL_DENY_UNKNOWN
 #define REJECT_UNKNOWN	SEPOL_REJECT_UNKNOWN
Index: libsepol/src/policydb.c
===================================================================
--- libsepol/src/policydb.c	(revision 2950)
+++ libsepol/src/policydb.c	(working copy)
 <at>  <at>  -110,6 +110,12  <at>  <at> 
 	 .sym_num = SYM_NUM,
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
+        {
+	 .type = POLICY_KERN,
+	 .version = POLICYDB_VERSION_BOUNDARY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_NODE6 + 1,
+	},
 	{
 	 .type = POLICY_BASE,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 <at>  <at>  -141,6 +147,12  <at>  <at> 
 	 .ocon_num = OCON_NODE6 + 1,
 	 },
 	{
+	 .type = POLICY_BASE,
+	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = OCON_NODE6 + 1,
+	},
+	{
 	 .type = POLICY_MOD,
 	 .version = MOD_POLICYDB_VERSION_BASE,
 	 .sym_num = SYM_NUM,
 <at>  <at>  -170,6 +182,12  <at>  <at> 
 	 .sym_num = SYM_NUM,
 	 .ocon_num = 0
 	 },
+	{
+	 .type = POLICY_MOD,
+	 .version = MOD_POLICYDB_VERSION_BOUNDARY,
+	 .sym_num = SYM_NUM,
+	 .ocon_num = 0
+	},
 };

 #if 0
 <at>  <at>  -1855,20 +1873,25  <at>  <at> 
 {
 	char *key = 0;
 	role_datum_t *role;
-	uint32_t buf[2];
+	uint32_t buf[3];
 	size_t len;
-	int rc;
+	int rc, to_read = 2;

 	role = calloc(1, sizeof(role_datum_t));
 	if (!role)
 		return -1;

-	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+	if (policydb_has_boundary_feature(p))
+		to_read = 3;
+
+	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
 	if (rc < 0)
 		goto bad;

 	len = le32_to_cpu(buf[0]);
 	role->s.value = le32_to_cpu(buf[1]);
+	if (policydb_has_boundary_feature(p))
+		role->bounds = le32_to_cpu(buf[2]);

 	key = malloc(len + 1);
 	if (!key)
 <at>  <at>  -1924,7 +1947,9  <at>  <at> 
 	if (!typdatum)
 		return -1;

-	if (p->policy_type == POLICY_KERN)
+	if (policydb_has_boundary_feature(p))
+		to_read = 4;
+	else if (p->policy_type == POLICY_KERN)
 		to_read = 3;
 	else if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
 		to_read = 5;
 <at>  <at>  -1937,11 +1962,31  <at>  <at> 

 	len = le32_to_cpu(buf[0]);
 	typdatum->s.value = le32_to_cpu(buf[1]);
-	typdatum->primary = le32_to_cpu(buf[2]);
+	if (policydb_has_boundary_feature(p)) {
+		uint32_t properties = le32_to_cpu(buf[2]);
+
+		if (properties & TYPEDATUM_PROPERTY_PRIMARY)
+			typdatum->primary = 1;
+		if (properties & TYPEDATUM_PROPERTY_ATTRIBUTE)
+			typdatum->flavor = TYPE_ATTRIB;
+		if (properties & TYPEDATUM_PROPERTY_ALIAS
+		    && p->policy_type != POLICY_KERN)
+			typdatum->flavor = TYPE_ALIAS;
+		if (properties & TYPEDATUM_PROPERTY_PERMISSIVE
+		    && p->policy_type != POLICY_KERN)
+			typdatum->flags |= TYPE_FLAGS_PERMISSIVE;
+
+		typdatum->bounds = le32_to_cpu(buf[3]);
+	} else {
+		typdatum->primary = le32_to_cpu(buf[2]);
+		if (p->policy_type != POLICY_KERN) {
+			typdatum->flavor = le32_to_cpu(buf[3]);
+			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
+				typdatum->flags = le32_to_cpu(buf[4]);
+		}
+	}
+
 	if (p->policy_type != POLICY_KERN) {
-		typdatum->flavor = le32_to_cpu(buf[3]);
-		if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
-			typdatum->flags = le32_to_cpu(buf[4]);
 		if (ebitmap_read(&typdatum->types, fp))
 			goto bad;
 	}
 <at>  <at>  -2293,20 +2338,25  <at>  <at> 
 {
 	char *key = 0;
 	user_datum_t *usrdatum;
-	uint32_t buf[2];
+	uint32_t buf[3];
 	size_t len;
-	int rc;
+	int rc, to_read = 2;

 	usrdatum = calloc(1, sizeof(user_datum_t));
 	if (!usrdatum)
 		return -1;

-	rc = next_entry(buf, fp, sizeof(uint32_t) * 2);
+	if (policydb_has_boundary_feature(p))
+		to_read = 3;
+
+	rc = next_entry(buf, fp, sizeof(uint32_t) * to_read);
 	if (rc < 0)
 		goto bad;

 	len = le32_to_cpu(buf[0]);
 	usrdatum->s.value = le32_to_cpu(buf[1]);
+	if (policydb_has_boundary_feature(p))
+		usrdatum->bounds = le32_to_cpu(buf[2]);

 	key = malloc(len + 1);
 	if (!key)
Index: libsepol/src/expand.c
===================================================================
--- libsepol/src/expand.c	(revision 2950)
+++ libsepol/src/expand.c	(working copy)
 <at>  <at>  -466,6 +466,100  <at>  <at> 
 	return 0;
 }

+/*
+ * The boundaries have to be copied after the types/roles/users are copied,
+ * because it refers hashtab to lookup destinated objects.
+ */
+static int type_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	expand_state_t *state = (expand_state_t *) data;
+	type_datum_t *type = (type_datum_t *) datum;
+	type_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!type->bounds)
+		return 0;
+
+	if (!is_id_enabled((char *)key, state->base, SYM_TYPES))
+		return 0;
+
+	bounds_val = state->typemap[type->bounds - 1];
+
+	dest = hashtab_search(state->out->p_types.table, (char *)key);
+	if (!dest) {
+		ERR(state->handle, "Type lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
+static int role_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	expand_state_t *state = (expand_state_t *) data;
+	role_datum_t *role = (role_datum_t *) datum;
+	role_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!role->bounds)
+		return 0;
+
+	if (!is_id_enabled((char *)key, state->base, SYM_ROLES))
+		return 0;
+
+	bounds_val = state->rolemap[role->bounds - 1];
+
+	dest = hashtab_search(state->out->p_roles.table, (char *)key);
+	if (!dest) {
+		ERR(state->handle, "Role lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
+static int user_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	expand_state_t *state = (expand_state_t *) data;
+	user_datum_t *user = (user_datum_t *) datum;
+	user_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!user->bounds)
+		return 0;
+
+	if (!is_id_enabled((char *)key, state->base, SYM_USERS))
+		return 0;
+
+	bounds_val = state->usermap[user->bounds - 1];
+
+	dest = hashtab_search(state->out->p_users.table, (char *)key);
+	if (!dest) {
+		ERR(state->handle, "User lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle, "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
 /* The aliases have to be copied after the types and attributes to be certain that
  * the out symbol table will have the type that the alias refers. Otherwise, we
  * won't be able to find the type value for the alias. We can't depend on the
 <at>  <at>  -1865,31 +1959,6  <at>  <at> 
 	return 0;
 }

-static void type_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p
-			 __attribute__ ((unused)))
-{
-	free(key);
-	type_datum_destroy((type_datum_t *) datum);
-	free(datum);
-}
-
-static int type_attr_remove(hashtab_key_t key
-			    __attribute__ ((unused)), hashtab_datum_t datum,
-			    void *args)
-{
-	type_datum_t *typdatum;
-	policydb_t *p;
-
-	typdatum = (type_datum_t *) datum;
-	p = (policydb_t *) args;
-	if (typdatum->flavor == TYPE_ATTRIB) {
-		p->type_val_to_struct[typdatum->s.value - 1] = NULL;
-		p->p_type_val_to_name[typdatum->s.value - 1] = NULL;
-		return 1;
-	}
-	return 0;
-}
-
 /* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy.
  * this should not be called until after all the blocks have been processed and the attributes in target policy
  * are complete. */
 <at>  <at>  -2393,6 +2462,11  <at>  <at> 
 		goto cleanup;
 	}

+	/* copy type bounds */
+	if (hashtab_map(state.base->p_types.table,
+			type_bounds_copy_callback, &state))
+		goto cleanup;
+
 	/* copy aliases */
 	if (hashtab_map(state.base->p_types.table, alias_copy_callback, &state))
 		goto cleanup;
 <at>  <at>  -2406,6 +2480,9  <at>  <at> 
 	/* copy roles */
 	if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state))
 		goto cleanup;
+	if (hashtab_map(state.base->p_roles.table,
+			role_bounds_copy_callback, &state))
+		goto cleanup;

 	/* copy MLS's sensitivity level and categories - this needs to be done
 	 * before expanding users (they need to be indexed too) */
 <at>  <at>  -2421,6 +2498,9  <at>  <at> 
 	/* copy users */
 	if (hashtab_map(state.base->p_users.table, user_copy_callback, &state))
 		goto cleanup;
+	if (hashtab_map(state.base->p_users.table,
+			user_bounds_copy_callback, &state))
+		goto cleanup;

 	/* copy bools */
 	if (hashtab_map(state.base->p_bools.table, bool_copy_callback, &state))
 <at>  <at>  -2510,8 +2590,6  <at>  <at> 
 	}
 	if (hashtab_map(state.out->p_types.table, type_attr_map, &state))
 		goto cleanup;
-	hashtab_map_remove_on_error(state.out->p_types.table,
-				    type_attr_remove, type_destroy, state.out);
 	if (check) {
 		if (hierarchy_check_constraints(handle, state.out))
 			goto cleanup;
Index: libsepol/src/write.c
===================================================================
--- libsepol/src/write.c	(revision 2950)
+++ libsepol/src/write.c	(working copy)
 <at>  <at>  -920,6 +920,8  <at>  <at> 
 	items = 0;
 	buf[items++] = cpu_to_le32(len);
 	buf[items++] = cpu_to_le32(role->s.value);
+	if (policydb_has_boundary_feature(p))
+		buf[items++] = cpu_to_le32(role->bounds);
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items != items2)
 		return POLICYDB_ERROR;
 <at>  <at>  -952,19 +954,51  <at>  <at> 

 	typdatum = (type_datum_t *) datum;

+	/*
+	 * The kernel policy version less than 24 (= POLICYDB_VERSION_BOUNDARY)
+	 * does not support to load entries of attribute, so we skip to write it.
+	 */
+	if (p->policy_type == POLICY_KERN
+	    && p->policyvers < POLICYDB_VERSION_BOUNDARY
+	    && typdatum->flavor == TYPE_ATTRIB)
+		return POLICYDB_SUCCESS;
+
 	len = strlen(key);
 	items = 0;
 	buf[items++] = cpu_to_le32(len);
 	buf[items++] = cpu_to_le32(typdatum->s.value);
-	buf[items++] = cpu_to_le32(typdatum->primary);
-	if (p->policy_type != POLICY_KERN) {
-		buf[items++] = cpu_to_le32(typdatum->flavor);
-		if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
-			buf[items++] = cpu_to_le32(typdatum->flags);
-		else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE)
-			WARN(fp->handle, "Warning! Module policy version %d cannnot "
-			     "support permissive types, but one was defined",
-			     p->policyvers);
+	if (policydb_has_boundary_feature(p)) {
+		uint32_t properties = 0;
+
+		if (typdatum->primary)
+			properties |= TYPEDATUM_PROPERTY_PRIMARY;
+
+		if (typdatum->flavor == TYPE_ATTRIB) {
+			properties |= TYPEDATUM_PROPERTY_ATTRIBUTE;
+		} else if (typdatum->flavor == TYPE_ALIAS
+			   && p->policy_type != POLICY_KERN)
+			properties |= TYPEDATUM_PROPERTY_ALIAS;
+
+		if (typdatum->flags & TYPE_FLAGS_PERMISSIVE
+		    && p->policy_type != POLICY_KERN)
+			properties |= TYPEDATUM_PROPERTY_PERMISSIVE;
+
+		buf[items++] = cpu_to_le32(properties);
+		buf[items++] = cpu_to_le32(typdatum->bounds);
+	} else {
+		buf[items++] = cpu_to_le32(typdatum->primary);
+
+		if (p->policy_type != POLICY_KERN) {
+			buf[items++] = cpu_to_le32(typdatum->flavor);
+
+			if (p->policyvers >= MOD_POLICYDB_VERSION_PERMISSIVE)
+				buf[items++] = cpu_to_le32(typdatum->flags);
+			else if (typdatum->flags & TYPE_FLAGS_PERMISSIVE)
+				WARN(fp->handle, "Warning! Module policy "
+				     "version %d cannnot suport permissive "
+				     "types, but one was defined",
+				     p->policyvers);
+		}
 	}
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items != items2)
 <at>  <at>  -997,6 +1031,8  <at>  <at> 
 	items = 0;
 	buf[items++] = cpu_to_le32(len);
 	buf[items++] = cpu_to_le32(usrdatum->s.value);
+	if (policydb_has_boundary_feature(p))
+		buf[items++] = cpu_to_le32(usrdatum->bounds);
 	items2 = put_entry(buf, sizeof(uint32_t), items, fp);
 	if (items != items2)
 		return POLICYDB_ERROR;
Index: libsepol/src/link.c
===================================================================
--- libsepol/src/link.c	(revision 2950)
+++ libsepol/src/link.c	(working copy)
 <at>  <at>  -660,6 +660,97  <at>  <at> 
 	    user_copy_callback, bool_copy_callback, sens_copy_callback,
 	    cat_copy_callback};

+/*
+ * The boundaries have to be copied after the types/roles/users are copied,
+ * because it refers hashtab to lookup destinated objects.
+ */
+static int type_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	link_state_t *state = (link_state_t *) data;
+	type_datum_t *type = (type_datum_t *) datum;
+	type_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!type->bounds)
+		return 0;
+
+	bounds_val = state->cur->map[SYM_TYPES][type->bounds - 1];
+
+	dest = hashtab_search(state->base->p_types.table, key);
+	if (!dest) {
+		ERR(state->handle,
+		    "Type lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle,
+		    "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
+static int role_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	link_state_t *state = (link_state_t *) data;
+	role_datum_t *role = (role_datum_t *) datum;
+	role_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!role->bounds)
+		return 0;
+
+	bounds_val = state->cur->map[SYM_ROLES][role->bounds - 1];
+
+	dest = hashtab_search(state->base->p_roles.table, key);
+	if (!dest) {
+		ERR(state->handle,
+		    "Role lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle,
+		    "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
+static int user_bounds_copy_callback(hashtab_key_t key,
+				     hashtab_datum_t datum, void *data)
+{
+	link_state_t *state = (link_state_t *) data;
+	user_datum_t *user = (user_datum_t *) datum;
+	user_datum_t *dest;
+	uint32_t bounds_val;
+
+	if (!user->bounds)
+		return 0;
+
+	bounds_val = state->cur->map[SYM_USERS][user->bounds - 1];
+
+	dest = hashtab_search(state->base->p_users.table, key);
+	if (!dest) {
+		ERR(state->handle,
+		    "User lookup failed for %s", (char *)key);
+		return -1;
+	}
+	if (dest->bounds != 0 && dest->bounds != bounds_val) {
+		ERR(state->handle,
+		    "Inconsistent boundary for %s", (char *)key);
+		return -1;
+	}
+	dest->bounds = bounds_val;
+
+	return 0;
+}
+
 /* The aliases have to be copied after the types and attributes to be
  * certain that the base symbol table will have the type that the
  * alias refers. Otherwise, we won't be able to find the type value
 <at>  <at>  -1362,11 +1453,22  <at>  <at> 
 		}
 	}

-	if (hashtab_map
-	    (src_symtab[SYM_TYPES].table, alias_copy_callback, state)) {
+	if (hashtab_map(src_symtab[SYM_TYPES].table,
+			type_bounds_copy_callback, state))
 		return -1;
-	}

+	if (hashtab_map(src_symtab[SYM_TYPES].table,
+			alias_copy_callback, state))
+		return -1;
+
+	if (hashtab_map(src_symtab[SYM_ROLES].table,
+			role_bounds_copy_callback, state))
+		return -1;
+
+	if (hashtab_map(src_symtab[SYM_USERS].table,
+			user_bounds_copy_callback, state))
+		return -1;
+
 	/* then fix bitmaps associated with those newly copied identifiers */
 	for (i = 0; i < SYM_NUM; i++) {
 		if (fix_callback_f[i] != NULL &&

--

-- 
OSS Platform Development Division, NEC
KaiGai Kohei <kaigai@...>

Shintaro Fujiwara | 1 Sep 2008 11:06
Picon

How can I know violations in denied timing ?

Hello, I'm Shintaro, Fujiwara writer of segatex.

I wrote a small c program in latest segatex which pops up a widget when violation occurs but,
it only reads audit.log and make another file and periodically compare old one and new one.
If new one differs from old one, it pops up a widget.

But what I really want to do is that something like setroubleshoot, which I imagine reads kernel directly.

I'm making segatex not to alternate Redhat's one, but for my own pleasure and my study.

I have no experiences reading kernel and don't know how to read kernel files at all.

So, if you have time to spare for me, please let me know how to read kernel files.

This time, I want to make a small program like setroubleshoot.

Thank you very much in advance.

--
http://intrajp.no-ip.com/ Home Page
Joshua Brindle | 1 Sep 2008 16:47
Favicon

RE: [PATCH 3/3] Thread/Child-Domain Assignment (rev.4)

KaiGai Kohei wrote:
> Joshua Brindle wrote:
>> KaiGai Kohei wrote:
>>> Joshua Brindle wrote:
>>>> KaiGai Kohei wrote:
>>>>> The following patch is revised one for libsepol.
>>>>> 
>>>>> Updates:
>>>>>  - The properties of type_datum are packed within the third word
>>>>>    of type entries in the kernel policy.
>>>>>    The first bit (TYPEDATUM_PROPERTY_PRIMARY) means the entry is a
>>>>>    primary type, and the second bit (TYPEDATUM_PROPERTY_ATTRIBUTE)
>>>>>    means the entry is an attribute.
>>>>> 
>>>> I didn't see an answer in the current threads, and this looks like
>>>  > the latest userland patch series so I'll ask here: What is the
>>> purpose  > of the properties? We can infer what it knows from the
>>> other fields
>>>> in the datum, right?
>>> Stephen said as follows:
>>> http://marc.info/?l=selinux&m=121882413424973&w=2
>>> 
>>>> Keeping the type attribute names in the types symtab in the kernel
>>>> policy allows tools like audit2why and apol to extract the original
>>>> attribute names and display them.  I originally shed them because
>>>> the kernel didn't need to use that information and we don't want
>>>> attribute names to be used in security contexts, but it costs us
>>>> little to save them and check for them, and it benefits the tools.
>> 
>> No, I got that part. What I was missing was that we identified
>> attributes differently in modules and kernel policy now, kind of
>> confusing.
> 
> I see, modular policy format now has "primary", "flavor" and "flags"
> members to identify its properties. It is different from
> newer kernel policy format.
> 
>>> The type_datum has the following format in the newer kernel policy:
>>> 
>>>   +0 +-------------------------+
>>>      | length of name          |
>>>   +4 +-------------------------+
>>>      | type identifier value   |
>>>   +8 +-------------------------+
>>>      | property bits           | <--- TYPEDATUM_PROPERTY_PRIMARY
>>> +12 +-------------------------+      TYPEDATUM_PROPERTY_ATTRIBUTE
>>>      | bounds type identifier  |
>>> +16 +-------------------------+
>>>      | text representation of  |
>>>      | name (variable length)  |
>>>      +-------------------------+
>>> 
>>> Any property bits are packed within the third field.
>>> 
>> 
>> I don't see that in the libsepol patch:
>> 
>>  <at>  <at>  -145,8 +146,16  <at>  <at> 
>>  	ebitmap_t types;	/* types with this attribute */
>>  #define TYPE_FLAGS_PERMISSIVE	0x01
>>  	uint32_t flags;
>> +	uint32_t bounds;	/* bounds type, if exist */
>>  } type_datum_t;
> 
> Are you saying members within type_datum_t should have
> one-to-one mapping with its disk format? If so, it is the
> most straightforward approach to add a "flavor" member for
> the disk format of kernel policy.
> 

No, don't add flavor to the kernel format. Add the property to the
libsepol type_datum

> I guess your opinion is that smaller differences between
> kernel and modular policy format is better. If so, what do

No, I'm fine with differences in those 2 formats. I just don't want to
get confused later when the on-disk format has extra fields that the
structs in libsepol don't have.

> you think about an idea which packs all properties of a type
> into a property bits members.
> We need 1 bit for "primary" property, 2 bits for "flavor" and
> 1 bit for "permissive", so it is enough to store them into a 32bits
> variable. 
> 
> In this case, the format of type_datum is changed as follows:
> 
>   + 0 : length of name (unchanged)
>   + 4 : type identifier value (unchanged)
>   + 8 : property bits which can have following bits
>   +12 : bounds type identifier (newly added)
>   +16 : ebitmap of attributes (modular only/unchanged)
>   +XX : text representation of type name
>   (*) flavor in modular policy format is deprecated.
> 
> Thanks,


Gmane