Re: MLS dominance check behavior on el7

2018-09-11 Thread Ted Toth
That's awesome and now it's got me thinking about other classes/permissions
that we could implement. Can cil macros can be referenced in .te/.if files?


On Tue, Sep 11, 2018 at 2:27 PM Stephen Smalley  wrote:

> On 09/11/2018 02:49 PM, Ted Toth wrote:
> > Yes I too noticed the translate permission but couldn't find any info
> > related to it intended purpose. Regarding CIL unfortunately I have zero
> > experience with it but I've installed the compiler and started reading
> > through https://github.com/SELinuxProject/cil/wiki (any other pointers
> > to useful info would be appreciated). I have written lots of policy
> > would it be possible to add a class/permissions/mlsconstraints in an
> > old-fashion policy module?
>
> The older binary modules didn't support those kinds of statements
> outside of the base module.  Try this:
> $ cat > mcstrans.cil < ; define a mcstrans class with one permission color_use
> (class mcstrans (color_use))
> ; allow all domains mcstrans color_use permission to themselves
> (allow domain self (mcstrans (color_use)))
> ; only allow mcstrans color_use permission when h1 dominates h2
> (mlsconstrain (mcstrans (color_use)) (dom h1 h2))
> ; append the new mcstrans class to the end after all others
> (classorder (unordered mcstrans))
> EOF
>
> $ sudo semodule -i mcstrans.cil
>
> Then try performing permission checks with "mcstrans" as your class and
> "color_use" as your permission, between a domain and itself, with
> different levels.
>
> >
> > On Tue, Sep 11, 2018 at 1:27 PM Stephen Smalley  > > wrote:
> >
> > On 09/11/2018 10:41 AM, Stephen Smalley wrote:
> >  > On 09/10/2018 06:30 PM, Ted Toth wrote:
> >  >> mcstrans mcscolor.c also uses the same logic I'd been using to
> > check
> >  >> dominance so this too will no longer function as expected on
> > el7. Do
> >  >> you any suggestions for doing a 'generic' (one not tied to a
> > specific
> >  >> resource class) dominance check in lieu of context contains?
> >  >
> >  > You should probably define your own permission with its own
> > constraint
> >  > to avoid depending on the base policy's particular constraint
> >  > definitions.  Certainly for your own code.  For mcstrans, mcscolor
> >  > probably ought to be switched to using at least a separate
> > permission in
> >  > the context class if not its own class to avoid overloading the
> > meaning
> >  > with pam_selinux's usage (or vice versa, but likely harder to
> change
> >  > pam_selinux at this point).
> >  >
> >  > It is possible to define an entirely new class, its permissions,
> > and its
> >  > mls constraints via a CIL module IIUC, without needing to change
> the
> >  > base policy.
> >  >
> >  > I don't think you can add a permission to an existing class via a
> > CIL
> >  > module currently, unfortunately, so you can't just extend the
> > context
> >  > class without modifying the base policy.  So it may be easier to
> > define
> >  > an entirely new class.
> >  >
> >  > The class and permission ought to be specific to the usage.  For
> >  > example, mcstrans could have its own class (mcstrans) with its own
> >  > permissions (e.g. color_match or color_use or ...) that abstract
> > away
> >  > the logical check being performed.  Dominance checks performed for
> >  > different reasons ought to use different permissions so that one
> can
> >  > distinguish what TE pairs are allowed them.
> >  >
> >  > Your code could likewise define and use its own class and
> permission.
> >  >
> >  > Does that make sense?
> >
> > BTW, I noticed there is another permission ("translate") defined in
> the
> > context class and its constraint is ((h1 dom h2) or (t1 ==
> > mlstranslate)).  I would have guessed that it was intended as a
> > front-end service check over what processes could request context
> > translations from mcstrans or what contexts they could translate,
> but I
> > don't see it being used in mcstrans anywhere.  Is this a legacy thing
> > from early setransd/mcstransd days?  There is a TODO comment in
> > mcstrans
> > process_request() that suggests there was an intent to perform a
> > dominance check between the requester context and the specified
> > context,
> > but that's not implemented.  Appears to be allowed in current policy
> > for
> > all domains to the setrans_t domain itself.
> >
> >  >
> >  >>
> >  >> Ted
> >  >>
> >  >> On Mon, Sep 10, 2018 at 1:19 PM Ted Toth  > 
> >  >> >> wrote:
> >  >>
> >  >> Understood, thanks.
> >  >>
> >  >> On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley
> > mailto:s...@tycho.nsa.gov>
> >  >> 

Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 03:04 PM, Joe Nall wrote:




On Sep 11, 2018, at 1:29 PM, Stephen Smalley  wrote:

On 09/11/2018 10:41 AM, Stephen Smalley wrote:

On 09/10/2018 06:30 PM, Ted Toth wrote:

mcstrans mcscolor.c also uses the same logic I'd been using to check dominance 
so this too will no longer function as expected on el7. Do you any suggestions 
for doing a 'generic' (one not tied to a specific resource class) dominance 
check in lieu of context contains?

You should probably define your own permission with its own constraint to avoid 
depending on the base policy's particular constraint definitions.  Certainly 
for your own code.  For mcstrans, mcscolor probably ought to be switched to 
using at least a separate permission in the context class if not its own class 
to avoid overloading the meaning with pam_selinux's usage (or vice versa, but 
likely harder to change pam_selinux at this point).
It is possible to define an entirely new class, its permissions, and its mls 
constraints via a CIL module IIUC, without needing to change the base policy.
I don't think you can add a permission to an existing class via a CIL module 
currently, unfortunately, so you can't just extend the context class without 
modifying the base policy.  So it may be easier to define an entirely new class.
The class and permission ought to be specific to the usage.  For example, 
mcstrans could have its own class (mcstrans) with its own permissions (e.g. 
color_match or color_use or ...) that abstract away the logical check being 
performed.  Dominance checks performed for different reasons ought to use 
different permissions so that one can distinguish what TE pairs are allowed 
them.
Your code could likewise define and use its own class and permission.
Does that make sense?


BTW, I noticed there is another permission ("translate") defined in the context 
class and its constraint is ((h1 dom h2) or (t1 == mlstranslate)).  I would have guessed 
that it was intended as a front-end service check over what processes could request 
context translations from mcstrans or what contexts they could translate, but I don't see 
it being used in mcstrans anywhere.  Is this a legacy thing from early setransd/mcstransd 
days?  There is a TODO comment in mcstrans process_request() that suggests there was an 
intent to perform a dominance check between the requester context and the specified 
context, but that's not implemented.  Appears to be allowed in current policy for all 
domains to the setrans_t domain itself.


I think 'translate' predates my mcstransd work and dates from the original TCS 
implementation. There is an argument to implement that constraint, but we've 
been operating without it for so long it does not seem worthwhile.


Well, I guess we ought to either implement it or delete the permission 
definition from refpolicy.

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 03:29 PM, Stephen Smalley wrote:

On 09/11/2018 02:49 PM, Ted Toth wrote:
Yes I too noticed the translate permission but couldn't find any info 
related to it intended purpose. Regarding CIL unfortunately I have 
zero experience with it but I've installed the compiler and started 
reading through https://github.com/SELinuxProject/cil/wiki (any other 
pointers to useful info would be appreciated). I have written lots of 
policy would it be possible to add a class/permissions/mlsconstraints 
in an old-fashion policy module?


The older binary modules didn't support those kinds of statements 
outside of the base module.  Try this:

$ cat > mcstrans.cil 

Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 02:49 PM, Ted Toth wrote:
Yes I too noticed the translate permission but couldn't find any info 
related to it intended purpose. Regarding CIL unfortunately I have zero 
experience with it but I've installed the compiler and started reading 
through https://github.com/SELinuxProject/cil/wiki (any other pointers 
to useful info would be appreciated). I have written lots of policy 
would it be possible to add a class/permissions/mlsconstraints in an 
old-fashion policy module?


The older binary modules didn't support those kinds of statements 
outside of the base module.  Try this:

$ cat > mcstrans.cil > wrote:


On 09/11/2018 10:41 AM, Stephen Smalley wrote:
 > On 09/10/2018 06:30 PM, Ted Toth wrote:
 >> mcstrans mcscolor.c also uses the same logic I'd been using to
check
 >> dominance so this too will no longer function as expected on
el7. Do
 >> you any suggestions for doing a 'generic' (one not tied to a
specific
 >> resource class) dominance check in lieu of context contains?
 >
 > You should probably define your own permission with its own
constraint
 > to avoid depending on the base policy's particular constraint
 > definitions.  Certainly for your own code.  For mcstrans, mcscolor
 > probably ought to be switched to using at least a separate
permission in
 > the context class if not its own class to avoid overloading the
meaning
 > with pam_selinux's usage (or vice versa, but likely harder to change
 > pam_selinux at this point).
 >
 > It is possible to define an entirely new class, its permissions,
and its
 > mls constraints via a CIL module IIUC, without needing to change the
 > base policy.
 >
 > I don't think you can add a permission to an existing class via a
CIL
 > module currently, unfortunately, so you can't just extend the
context
 > class without modifying the base policy.  So it may be easier to
define
 > an entirely new class.
 >
 > The class and permission ought to be specific to the usage.  For
 > example, mcstrans could have its own class (mcstrans) with its own
 > permissions (e.g. color_match or color_use or ...) that abstract
away
 > the logical check being performed.  Dominance checks performed for
 > different reasons ought to use different permissions so that one can
 > distinguish what TE pairs are allowed them.
 >
 > Your code could likewise define and use its own class and permission.
 >
 > Does that make sense?

BTW, I noticed there is another permission ("translate") defined in the
context class and its constraint is ((h1 dom h2) or (t1 ==
mlstranslate)).  I would have guessed that it was intended as a
front-end service check over what processes could request context
translations from mcstrans or what contexts they could translate, but I
don't see it being used in mcstrans anywhere.  Is this a legacy thing
from early setransd/mcstransd days?  There is a TODO comment in
mcstrans
process_request() that suggests there was an intent to perform a
dominance check between the requester context and the specified
context,
but that's not implemented.  Appears to be allowed in current policy
for
all domains to the setrans_t domain itself.

 >
 >>
 >> Ted
 >>
 >> On Mon, Sep 10, 2018 at 1:19 PM Ted Toth mailto:txt...@gmail.com>
 >> >> wrote:
 >>
 >>     Understood, thanks.
 >>
 >>     On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley
mailto:s...@tycho.nsa.gov>
 >>     >> wrote:
 >>
 >>     On 09/10/2018 01:13 PM, Ted Toth wrote:
 >>  > We currently have code running on el6 that does a MLS
 >>     dominance check by
 >>  > calling security_compute_av_raw with the security
object class
 >>  > SECCLASS_CONTEXT with permission CONTEXT__CONTAINS as
you can
 >>     see in the
 >>  > python code below. When I run this code on el6 s1
dominates
 >>     s0 however
 >>  > when I run the same code on el7 s1 does not dominate
s0. On
 >>     both systems
 >>  > the file read dominance check works as expected. Can
anyone
 >>     help me
 >>  > understand why the context contains check does not
work the
 >>     same on both
 >>  > systems?
 >>
 >>     That would depend entirely on how the constraint is
written in
 >> the
 >>     policy.  I assume this is with the -mls 

Re: MLS dominance check behavior on el7

2018-09-11 Thread Joe Nall



> On Sep 11, 2018, at 1:29 PM, Stephen Smalley  wrote:
> 
> On 09/11/2018 10:41 AM, Stephen Smalley wrote:
>> On 09/10/2018 06:30 PM, Ted Toth wrote:
>>> mcstrans mcscolor.c also uses the same logic I'd been using to check 
>>> dominance so this too will no longer function as expected on el7. Do you 
>>> any suggestions for doing a 'generic' (one not tied to a specific resource 
>>> class) dominance check in lieu of context contains?
>> You should probably define your own permission with its own constraint to 
>> avoid depending on the base policy's particular constraint definitions.  
>> Certainly for your own code.  For mcstrans, mcscolor probably ought to be 
>> switched to using at least a separate permission in the context class if not 
>> its own class to avoid overloading the meaning with pam_selinux's usage (or 
>> vice versa, but likely harder to change pam_selinux at this point).
>> It is possible to define an entirely new class, its permissions, and its mls 
>> constraints via a CIL module IIUC, without needing to change the base policy.
>> I don't think you can add a permission to an existing class via a CIL module 
>> currently, unfortunately, so you can't just extend the context class without 
>> modifying the base policy.  So it may be easier to define an entirely new 
>> class.
>> The class and permission ought to be specific to the usage.  For example, 
>> mcstrans could have its own class (mcstrans) with its own permissions (e.g. 
>> color_match or color_use or ...) that abstract away the logical check being 
>> performed.  Dominance checks performed for different reasons ought to use 
>> different permissions so that one can distinguish what TE pairs are allowed 
>> them.
>> Your code could likewise define and use its own class and permission.
>> Does that make sense?
> 
> BTW, I noticed there is another permission ("translate") defined in the 
> context class and its constraint is ((h1 dom h2) or (t1 == mlstranslate)).  I 
> would have guessed that it was intended as a front-end service check over 
> what processes could request context translations from mcstrans or what 
> contexts they could translate, but I don't see it being used in mcstrans 
> anywhere.  Is this a legacy thing from early setransd/mcstransd days?  There 
> is a TODO comment in mcstrans process_request() that suggests there was an 
> intent to perform a dominance check between the requester context and the 
> specified context, but that's not implemented.  Appears to be allowed in 
> current policy for all domains to the setrans_t domain itself.

I think 'translate' predates my mcstransd work and dates from the original TCS 
implementation. There is an argument to implement that constraint, but we've 
been operating without it for so long it does not seem worthwhile.

joe



___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Yuli Khodorkovskiy
The selinux repo has more up to date and digestible documentation: 
https://github.com/SELinuxProject/selinux/tree/master/secilc/docs

> On Sep 11, 2018, at 2:49 PM, Ted Toth  wrote:
> 
> Yes I too noticed the translate permission but couldn't find any info related 
> to it intended purpose. Regarding CIL unfortunately I have zero experience 
> with it but I've installed the compiler and started reading through 
> https://github.com/SELinuxProject/cil/wiki (any other pointers to useful info 
> would be appreciated). I have written lots of policy would it be possible to 
> add a class/permissions/mlsconstraints in an old-fashion policy module?
> 
> On Tue, Sep 11, 2018 at 1:27 PM Stephen Smalley  wrote:
> On 09/11/2018 10:41 AM, Stephen Smalley wrote:
> > On 09/10/2018 06:30 PM, Ted Toth wrote:
> >> mcstrans mcscolor.c also uses the same logic I'd been using to check 
> >> dominance so this too will no longer function as expected on el7. Do 
> >> you any suggestions for doing a 'generic' (one not tied to a specific 
> >> resource class) dominance check in lieu of context contains?
> > 
> > You should probably define your own permission with its own constraint 
> > to avoid depending on the base policy's particular constraint 
> > definitions.  Certainly for your own code.  For mcstrans, mcscolor 
> > probably ought to be switched to using at least a separate permission in 
> > the context class if not its own class to avoid overloading the meaning 
> > with pam_selinux's usage (or vice versa, but likely harder to change 
> > pam_selinux at this point).
> > 
> > It is possible to define an entirely new class, its permissions, and its 
> > mls constraints via a CIL module IIUC, without needing to change the 
> > base policy.
> > 
> > I don't think you can add a permission to an existing class via a CIL 
> > module currently, unfortunately, so you can't just extend the context 
> > class without modifying the base policy.  So it may be easier to define 
> > an entirely new class.
> > 
> > The class and permission ought to be specific to the usage.  For 
> > example, mcstrans could have its own class (mcstrans) with its own 
> > permissions (e.g. color_match or color_use or ...) that abstract away 
> > the logical check being performed.  Dominance checks performed for 
> > different reasons ought to use different permissions so that one can 
> > distinguish what TE pairs are allowed them.
> > 
> > Your code could likewise define and use its own class and permission.
> > 
> > Does that make sense?
> 
> BTW, I noticed there is another permission ("translate") defined in the 
> context class and its constraint is ((h1 dom h2) or (t1 == 
> mlstranslate)).  I would have guessed that it was intended as a 
> front-end service check over what processes could request context 
> translations from mcstrans or what contexts they could translate, but I 
> don't see it being used in mcstrans anywhere.  Is this a legacy thing 
> from early setransd/mcstransd days?  There is a TODO comment in mcstrans 
> process_request() that suggests there was an intent to perform a 
> dominance check between the requester context and the specified context, 
> but that's not implemented.  Appears to be allowed in current policy for 
> all domains to the setrans_t domain itself.
> 
> > 
> >>
> >> Ted
> >>
> >> On Mon, Sep 10, 2018 at 1:19 PM Ted Toth  >> > wrote:
> >>
> >> Understood, thanks.
> >>
> >> On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley  >> > wrote:
> >>
> >> On 09/10/2018 01:13 PM, Ted Toth wrote:
> >>  > We currently have code running on el6 that does a MLS
> >> dominance check by
> >>  > calling security_compute_av_raw with the security object class
> >>  > SECCLASS_CONTEXT with permission CONTEXT__CONTAINS as you can
> >> see in the
> >>  > python code below. When I run this code on el6 s1 dominates
> >> s0 however
> >>  > when I run the same code on el7 s1 does not dominate s0. On
> >> both systems
> >>  > the file read dominance check works as expected. Can anyone
> >> help me
> >>  > understand why the context contains check does not work the
> >> same on both
> >>  > systems?
> >>
> >> That would depend entirely on how the constraint is written in 
> >> the
> >> policy.  I assume this is with the -mls policy on both?  seinfo
> >> --constrain | grep -C1 context would show you the constraint 
> >> in the
> >> kernel policy.
> >>
> >> Looks like refpolicy defines it as:
> >> mlsconstrain context contains
> >>   (( h1 dom h2 ) and ( l1 domby l2));
> >>
> >> The 2nd part of the constraint was introduced by:
> >> commit 4c365f4a6a6f933dd13b0127e03f832c6a6cf8fc
> >> Author: Harry Ciao  >> >
> >> Date:   Tue Feb 

Re: MLS dominance check behavior on el7

2018-09-11 Thread Ted Toth
Yes I too noticed the translate permission but couldn't find any info
related to it intended purpose. Regarding CIL unfortunately I have zero
experience with it but I've installed the compiler and started reading
through https://github.com/SELinuxProject/cil/wiki (any other pointers to
useful info would be appreciated). I have written lots of policy would it
be possible to add a class/permissions/mlsconstraints in an old-fashion
policy module?

On Tue, Sep 11, 2018 at 1:27 PM Stephen Smalley  wrote:

> On 09/11/2018 10:41 AM, Stephen Smalley wrote:
> > On 09/10/2018 06:30 PM, Ted Toth wrote:
> >> mcstrans mcscolor.c also uses the same logic I'd been using to check
> >> dominance so this too will no longer function as expected on el7. Do
> >> you any suggestions for doing a 'generic' (one not tied to a specific
> >> resource class) dominance check in lieu of context contains?
> >
> > You should probably define your own permission with its own constraint
> > to avoid depending on the base policy's particular constraint
> > definitions.  Certainly for your own code.  For mcstrans, mcscolor
> > probably ought to be switched to using at least a separate permission in
> > the context class if not its own class to avoid overloading the meaning
> > with pam_selinux's usage (or vice versa, but likely harder to change
> > pam_selinux at this point).
> >
> > It is possible to define an entirely new class, its permissions, and its
> > mls constraints via a CIL module IIUC, without needing to change the
> > base policy.
> >
> > I don't think you can add a permission to an existing class via a CIL
> > module currently, unfortunately, so you can't just extend the context
> > class without modifying the base policy.  So it may be easier to define
> > an entirely new class.
> >
> > The class and permission ought to be specific to the usage.  For
> > example, mcstrans could have its own class (mcstrans) with its own
> > permissions (e.g. color_match or color_use or ...) that abstract away
> > the logical check being performed.  Dominance checks performed for
> > different reasons ought to use different permissions so that one can
> > distinguish what TE pairs are allowed them.
> >
> > Your code could likewise define and use its own class and permission.
> >
> > Does that make sense?
>
> BTW, I noticed there is another permission ("translate") defined in the
> context class and its constraint is ((h1 dom h2) or (t1 ==
> mlstranslate)).  I would have guessed that it was intended as a
> front-end service check over what processes could request context
> translations from mcstrans or what contexts they could translate, but I
> don't see it being used in mcstrans anywhere.  Is this a legacy thing
> from early setransd/mcstransd days?  There is a TODO comment in mcstrans
> process_request() that suggests there was an intent to perform a
> dominance check between the requester context and the specified context,
> but that's not implemented.  Appears to be allowed in current policy for
> all domains to the setrans_t domain itself.
>
> >
> >>
> >> Ted
> >>
> >> On Mon, Sep 10, 2018 at 1:19 PM Ted Toth  >> > wrote:
> >>
> >> Understood, thanks.
> >>
> >> On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley  >> > wrote:
> >>
> >> On 09/10/2018 01:13 PM, Ted Toth wrote:
> >>  > We currently have code running on el6 that does a MLS
> >> dominance check by
> >>  > calling security_compute_av_raw with the security object
> class
> >>  > SECCLASS_CONTEXT with permission CONTEXT__CONTAINS as you can
> >> see in the
> >>  > python code below. When I run this code on el6 s1 dominates
> >> s0 however
> >>  > when I run the same code on el7 s1 does not dominate s0. On
> >> both systems
> >>  > the file read dominance check works as expected. Can anyone
> >> help me
> >>  > understand why the context contains check does not work the
> >> same on both
> >>  > systems?
> >>
> >> That would depend entirely on how the constraint is written in
> >> the
> >> policy.  I assume this is with the -mls policy on both?  seinfo
> >> --constrain | grep -C1 context would show you the constraint
> >> in the
> >> kernel policy.
> >>
> >> Looks like refpolicy defines it as:
> >> mlsconstrain context contains
> >>   (( h1 dom h2 ) and ( l1 domby l2));
> >>
> >> The 2nd part of the constraint was introduced by:
> >> commit 4c365f4a6a6f933dd13b0127e03f832c6a6cf8fc
> >> Author: Harry Ciao  >> >
> >> Date:   Tue Feb 15 10:16:32 2011 +0800
> >>
> >>   l1 domby l2 for contains MLS constraint
> >>
> >>   As identified by Stephan Smalley, the current MLS
> >> constraint for the
> >>   contains permission of the conte

Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 10:41 AM, Stephen Smalley wrote:

On 09/10/2018 06:30 PM, Ted Toth wrote:
mcstrans mcscolor.c also uses the same logic I'd been using to check 
dominance so this too will no longer function as expected on el7. Do 
you any suggestions for doing a 'generic' (one not tied to a specific 
resource class) dominance check in lieu of context contains?


You should probably define your own permission with its own constraint 
to avoid depending on the base policy's particular constraint 
definitions.  Certainly for your own code.  For mcstrans, mcscolor 
probably ought to be switched to using at least a separate permission in 
the context class if not its own class to avoid overloading the meaning 
with pam_selinux's usage (or vice versa, but likely harder to change 
pam_selinux at this point).


It is possible to define an entirely new class, its permissions, and its 
mls constraints via a CIL module IIUC, without needing to change the 
base policy.


I don't think you can add a permission to an existing class via a CIL 
module currently, unfortunately, so you can't just extend the context 
class without modifying the base policy.  So it may be easier to define 
an entirely new class.


The class and permission ought to be specific to the usage.  For 
example, mcstrans could have its own class (mcstrans) with its own 
permissions (e.g. color_match or color_use or ...) that abstract away 
the logical check being performed.  Dominance checks performed for 
different reasons ought to use different permissions so that one can 
distinguish what TE pairs are allowed them.


Your code could likewise define and use its own class and permission.

Does that make sense?


BTW, I noticed there is another permission ("translate") defined in the 
context class and its constraint is ((h1 dom h2) or (t1 == 
mlstranslate)).  I would have guessed that it was intended as a 
front-end service check over what processes could request context 
translations from mcstrans or what contexts they could translate, but I 
don't see it being used in mcstrans anywhere.  Is this a legacy thing 
from early setransd/mcstransd days?  There is a TODO comment in mcstrans 
process_request() that suggests there was an intent to perform a 
dominance check between the requester context and the specified context, 
but that's not implemented.  Appears to be allowed in current policy for 
all domains to the setrans_t domain itself.






Ted

On Mon, Sep 10, 2018 at 1:19 PM Ted Toth > wrote:


    Understood, thanks.

    On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley mailto:s...@tycho.nsa.gov>> wrote:

    On 09/10/2018 01:13 PM, Ted Toth wrote:
 > We currently have code running on el6 that does a MLS
    dominance check by
 > calling security_compute_av_raw with the security object class
 > SECCLASS_CONTEXT with permission CONTEXT__CONTAINS as you can
    see in the
 > python code below. When I run this code on el6 s1 dominates
    s0 however
 > when I run the same code on el7 s1 does not dominate s0. On
    both systems
 > the file read dominance check works as expected. Can anyone
    help me
 > understand why the context contains check does not work the
    same on both
 > systems?

    That would depend entirely on how the constraint is written in 
the

    policy.  I assume this is with the -mls policy on both?  seinfo
    --constrain | grep -C1 context would show you the constraint 
in the

    kernel policy.

    Looks like refpolicy defines it as:
    mlsconstrain context contains
          (( h1 dom h2 ) and ( l1 domby l2));

    The 2nd part of the constraint was introduced by:
    commit 4c365f4a6a6f933dd13b0127e03f832c6a6cf8fc
    Author: Harry Ciao mailto:qingtao@windriver.com>>
    Date:   Tue Feb 15 10:16:32 2011 +0800

      l1 domby l2 for contains MLS constraint

      As identified by Stephan Smalley, the current MLS
    constraint for the
      contains permission of the context class should consider
    the current
      level of a user along with the clearance level so that
    mls_systemlow
      is no longer considered contained in mls_systemhigh.

      Signed-off-by: Harry Ciao mailto:qingtao@windriver.com>>

    This was to prevent a user from logging in at a level below their
    authorized range, in the unusual scenario where the user's low
    level was
    not s0/systemlow.

 >
 > Ted
 >
 >

- 


 >
 > import selinux
 >
 > SECCLASS_CONTEXT = selinux.string_to_security_class("context")
 > CON

Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 01:39 PM, Joshua Brindle wrote:

On Tue, Sep 11, 2018 at 1:33 PM, Stephen Smalley  wrote:

On 09/11/2018 12:53 PM, Joshua Brindle wrote:


On Tue, Sep 11, 2018 at 10:41 AM, Stephen Smalley 
wrote:


On 09/10/2018 06:30 PM, Ted Toth wrote:



mcstrans mcscolor.c also uses the same logic I'd been using to check
dominance so this too will no longer function as expected on el7. Do you
any
suggestions for doing a 'generic' (one not tied to a specific resource
class) dominance check in lieu of context contains?




You should probably define your own permission with its own constraint to
avoid depending on the base policy's particular constraint definitions.
Certainly for your own code.  For mcstrans, mcscolor probably ought to be
switched to using at least a separate permission in the context class if
not
its own class to avoid overloading the meaning with pam_selinux's usage
(or
vice versa, but likely harder to change pam_selinux at this point).



Isn't the actual question what the GLB of the 2 contexts is, rather
than what permissions one has on the other? It seems like a hack to
use permissions to figure out dominance.

Would a libselinux interface to determine glb and lub of 2 contexts
make sense? Or maybe add a default_range glb and lub option and then
calculate it using relabel?



At least as used in mcstrans, it appears to be a way of matching which entry
from the colors configuration to use.  So it is just a "Can context C1 use
the colors specified for context C2?" question.  It just happens that the
way they are deciding that for the MLS part is through the dominance
relation.  And determining whether context C1 dominates context C2 is
something only the kernel security server or libsepol with the same policy
file loaded into it can answer, not libselinux or anything else.



I meant an libselinux as in a library interface to some file in
selinuxfs to calculate the glb.

If it is 'permission to see a color' that makes sense, I was thinking
the source context and target context have a glb that maps to the
color to be shown.


That doesn't seem to match the existing mcstrans logic or colors 
configuration file.  So, sure he could rewrite mcstrans and its 
configuration format, add a new libselinux interface, add a new kernel 
interface, and implement a new kernel security server function, but he 
just wanted to make something that was already working on rhel6 to work 
on rhel7, and which only broke because a constraint changed out 
underneath to address a concern with pam_selinux/login.  Easiest 
approach is to define a new class/perm and define the old constraint for 
it.  Requires adding a CIL module for the policy piece and then a couple 
of lines changed in mcstrans and his own code and he is done.

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Joshua Brindle
On Tue, Sep 11, 2018 at 1:33 PM, Stephen Smalley  wrote:
> On 09/11/2018 12:53 PM, Joshua Brindle wrote:
>>
>> On Tue, Sep 11, 2018 at 10:41 AM, Stephen Smalley 
>> wrote:
>>>
>>> On 09/10/2018 06:30 PM, Ted Toth wrote:


 mcstrans mcscolor.c also uses the same logic I'd been using to check
 dominance so this too will no longer function as expected on el7. Do you
 any
 suggestions for doing a 'generic' (one not tied to a specific resource
 class) dominance check in lieu of context contains?
>>>
>>>
>>>
>>> You should probably define your own permission with its own constraint to
>>> avoid depending on the base policy's particular constraint definitions.
>>> Certainly for your own code.  For mcstrans, mcscolor probably ought to be
>>> switched to using at least a separate permission in the context class if
>>> not
>>> its own class to avoid overloading the meaning with pam_selinux's usage
>>> (or
>>> vice versa, but likely harder to change pam_selinux at this point).
>>>
>>
>> Isn't the actual question what the GLB of the 2 contexts is, rather
>> than what permissions one has on the other? It seems like a hack to
>> use permissions to figure out dominance.
>>
>> Would a libselinux interface to determine glb and lub of 2 contexts
>> make sense? Or maybe add a default_range glb and lub option and then
>> calculate it using relabel?
>
>
> At least as used in mcstrans, it appears to be a way of matching which entry
> from the colors configuration to use.  So it is just a "Can context C1 use
> the colors specified for context C2?" question.  It just happens that the
> way they are deciding that for the MLS part is through the dominance
> relation.  And determining whether context C1 dominates context C2 is
> something only the kernel security server or libsepol with the same policy
> file loaded into it can answer, not libselinux or anything else.
>

I meant an libselinux as in a library interface to some file in
selinuxfs to calculate the glb.

If it is 'permission to see a color' that makes sense, I was thinking
the source context and target context have a glb that maps to the
color to be shown.
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/11/2018 12:53 PM, Joshua Brindle wrote:

On Tue, Sep 11, 2018 at 10:41 AM, Stephen Smalley  wrote:

On 09/10/2018 06:30 PM, Ted Toth wrote:


mcstrans mcscolor.c also uses the same logic I'd been using to check
dominance so this too will no longer function as expected on el7. Do you any
suggestions for doing a 'generic' (one not tied to a specific resource
class) dominance check in lieu of context contains?



You should probably define your own permission with its own constraint to
avoid depending on the base policy's particular constraint definitions.
Certainly for your own code.  For mcstrans, mcscolor probably ought to be
switched to using at least a separate permission in the context class if not
its own class to avoid overloading the meaning with pam_selinux's usage (or
vice versa, but likely harder to change pam_selinux at this point).



Isn't the actual question what the GLB of the 2 contexts is, rather
than what permissions one has on the other? It seems like a hack to
use permissions to figure out dominance.

Would a libselinux interface to determine glb and lub of 2 contexts
make sense? Or maybe add a default_range glb and lub option and then
calculate it using relabel?


At least as used in mcstrans, it appears to be a way of matching which 
entry from the colors configuration to use.  So it is just a "Can 
context C1 use the colors specified for context C2?" question.  It just 
happens that the way they are deciding that for the MLS part is through 
the dominance relation.  And determining whether context C1 dominates 
context C2 is something only the kernel security server or libsepol with 
the same policy file loaded into it can answer, not libselinux or 
anything else.




___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Joshua Brindle
On Tue, Sep 11, 2018 at 10:41 AM, Stephen Smalley  wrote:
> On 09/10/2018 06:30 PM, Ted Toth wrote:
>>
>> mcstrans mcscolor.c also uses the same logic I'd been using to check
>> dominance so this too will no longer function as expected on el7. Do you any
>> suggestions for doing a 'generic' (one not tied to a specific resource
>> class) dominance check in lieu of context contains?
>
>
> You should probably define your own permission with its own constraint to
> avoid depending on the base policy's particular constraint definitions.
> Certainly for your own code.  For mcstrans, mcscolor probably ought to be
> switched to using at least a separate permission in the context class if not
> its own class to avoid overloading the meaning with pam_selinux's usage (or
> vice versa, but likely harder to change pam_selinux at this point).
>

Isn't the actual question what the GLB of the 2 contexts is, rather
than what permissions one has on the other? It seems like a hack to
use permissions to figure out dominance.

Would a libselinux interface to determine glb and lub of 2 contexts
make sense? Or maybe add a default_range glb and lub option and then
calculate it using relabel?
___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 07/10] SELinux: Abstract use of inode security blob

2018-09-11 Thread Casey Schaufler
Don't use the inode->i_security pointer directly.
Provide a helper function that provides the security blob pointer.

Signed-off-by: Casey Schaufler 
---
 security/selinux/hooks.c  | 26 +-
 security/selinux/include/objsec.h |  6 ++
 security/selinux/selinuxfs.c  |  4 ++--
 3 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3468b4592036..2720fe3ebf5f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -276,7 +276,7 @@ static int __inode_security_revalidate(struct inode *inode,
   struct dentry *dentry,
   bool may_sleep)
 {
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
 
might_sleep_if(may_sleep);
 
@@ -297,7 +297,7 @@ static int __inode_security_revalidate(struct inode *inode,
 
 static struct inode_security_struct *inode_security_novalidate(struct inode 
*inode)
 {
-   return inode->i_security;
+   return selinux_inode(inode);
 }
 
 static struct inode_security_struct *inode_security_rcu(struct inode *inode, 
bool rcu)
@@ -307,7 +307,7 @@ static struct inode_security_struct 
*inode_security_rcu(struct inode *inode, boo
error = __inode_security_revalidate(inode, NULL, !rcu);
if (error)
return ERR_PTR(error);
-   return inode->i_security;
+   return selinux_inode(inode);
 }
 
 /*
@@ -316,14 +316,14 @@ static struct inode_security_struct 
*inode_security_rcu(struct inode *inode, boo
 static struct inode_security_struct *inode_security(struct inode *inode)
 {
__inode_security_revalidate(inode, NULL, true);
-   return inode->i_security;
+   return selinux_inode(inode);
 }
 
 static struct inode_security_struct *backing_inode_security_novalidate(struct 
dentry *dentry)
 {
struct inode *inode = d_backing_inode(dentry);
 
-   return inode->i_security;
+   return selinux_inode(inode);
 }
 
 /*
@@ -334,7 +334,7 @@ static struct inode_security_struct 
*backing_inode_security(struct dentry *dentr
struct inode *inode = d_backing_inode(dentry);
 
__inode_security_revalidate(inode, dentry, true);
-   return inode->i_security;
+   return selinux_inode(inode);
 }
 
 static void inode_free_rcu(struct rcu_head *head)
@@ -347,7 +347,7 @@ static void inode_free_rcu(struct rcu_head *head)
 
 static void inode_free_security(struct inode *inode)
 {
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
struct superblock_security_struct *sbsec = inode->i_sb->s_security;
 
/*
@@ -1501,7 +1501,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
 static int inode_doinit_with_dentry(struct inode *inode, struct dentry 
*opt_dentry)
 {
struct superblock_security_struct *sbsec = NULL;
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
u32 task_sid, sid = 0;
u16 sclass;
struct dentry *dentry;
@@ -1801,7 +1801,7 @@ static int inode_has_perm(const struct cred *cred,
return 0;
 
sid = cred_sid(cred);
-   isec = inode->i_security;
+   isec = selinux_inode(inode);
 
return avc_has_perm(&selinux_state,
sid, isec->sid, isec->sclass, perms, adp);
@@ -3029,7 +3029,7 @@ static int selinux_inode_init_security(struct inode 
*inode, struct inode *dir,
 
/* Possibly defer initialization to selinux_complete_init. */
if (sbsec->flags & SE_SBINITIALIZED) {
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
isec->sclass = inode_mode_to_security_class(inode->i_mode);
isec->sid = newsid;
isec->initialized = LABEL_INITIALIZED;
@@ -3129,7 +3129,7 @@ static noinline int audit_inode_permission(struct inode 
*inode,
   unsigned flags)
 {
struct common_audit_data ad;
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
int rc;
 
ad.type = LSM_AUDIT_DATA_INODE;
@@ -4150,7 +4150,7 @@ static int selinux_task_kill(struct task_struct *p, 
struct siginfo *info,
 static void selinux_task_to_inode(struct task_struct *p,
  struct inode *inode)
 {
-   struct inode_security_struct *isec = inode->i_security;
+   struct inode_security_struct *isec = selinux_inode(inode);
u32 sid = task_sid(p);
 
spin_lock(&isec->lock);
@@ -6529,7 +6529,7 @@ static void selinux_release_secctx(char *secdata, u32 
seclen)
 
 static void selinux_inode_invalidate_secctx(struct 

[PATCH 10/10] LSM: Blob sharing support for S.A.R.A and LandLock

2018-09-11 Thread Casey Schaufler
Two proposed security modules require the ability to
share security blobs with existing "major" security modules.
These modules, S.A.R.A and LandLock, provide significantly
different services than SELinux, Smack or AppArmor. Using
either in conjunction with the existing modules is quite
reasonable. S.A.R.A requires access to the cred blob, while
LandLock uses the cred, file and inode blobs.

The use of the cred, file and inode blobs has been
abstracted in preceding patches in the series. This
patch teaches the affected security modules how to access
the part of the blob set aside for their use in the case
where blobs are shared. The configuration option
CONFIG_SECURITY_STACKING identifies systems where the
blobs may be shared.

The mechanism for selecting which security modules are
active has been changed to allow non-conflicting "major"
security modules to be used together. At this time the
TOMOYO module can safely be used with any of the others.
The two new modules would be non-conflicting as well.

Signed-off-by: Casey Schaufler 
---
 Documentation/admin-guide/LSM/index.rst | 14 +++--
 include/linux/lsm_hooks.h   |  2 +-
 security/Kconfig| 81 +
 security/apparmor/include/cred.h|  8 +++
 security/apparmor/include/file.h|  9 ++-
 security/apparmor/include/lib.h |  4 ++
 security/apparmor/lsm.c |  8 ++-
 security/security.c | 30 -
 security/selinux/hooks.c|  3 +-
 security/selinux/include/objsec.h   | 18 +-
 security/smack/smack.h  | 19 +-
 security/smack/smack_lsm.c  | 17 +++---
 security/tomoyo/common.h| 12 +++-
 security/tomoyo/tomoyo.c|  3 +-
 14 files changed, 200 insertions(+), 28 deletions(-)

diff --git a/Documentation/admin-guide/LSM/index.rst 
b/Documentation/admin-guide/LSM/index.rst
index 9842e21afd4a..d3d8af174042 100644
--- a/Documentation/admin-guide/LSM/index.rst
+++ b/Documentation/admin-guide/LSM/index.rst
@@ -17,10 +17,16 @@ MAC extensions, other extensions can be built using the LSM 
to provide
 specific changes to system operation when these tweaks are not available
 in the core functionality of Linux itself.
 
-The Linux capabilities modules will always be included. This may be
-followed by any number of "minor" modules and at most one "major" module.
-For more details on capabilities, see ``capabilities(7)`` in the Linux
-man-pages project.
+The Linux capabilities modules will always be included. For more details
+on capabilities, see ``capabilities(7)`` in the Linux man-pages project.
+
+Security modules that do not use the security data blobs maintained
+by the LSM infrastructure are considered "minor" modules. These may be
+included at compile time and stacked explicitly. Security modules that
+use the LSM maintained security blobs are considered "major" modules.
+These may only be stacked if the CONFIG_LSM_STACKED configuration
+option is used. If this is chosen all of the security modules selected
+will be used.
 
 A list of the active security modules can be found by reading
 ``/sys/kernel/security/lsm``. This is a comma separated list, and
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 416b20c3795b..dddcced54fea 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2079,7 +2079,7 @@ static inline void security_delete_hooks(struct 
security_hook_list *hooks,
 #define __lsm_ro_after_init__ro_after_init
 #endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
 
-extern int __init security_module_enable(const char *module);
+extern bool __init security_module_enable(const char *lsm, const bool stacked);
 extern void __init capability_add_hooks(void);
 #ifdef CONFIG_SECURITY_YAMA
 extern void __init yama_add_hooks(void);
diff --git a/security/Kconfig b/security/Kconfig
index 22f7664c4977..ed48025ae9e0 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -36,6 +36,28 @@ config SECURITY_WRITABLE_HOOKS
bool
default n
 
+config SECURITY_STACKING
+   bool "Security module stacking"
+   depends on SECURITY
+   help
+ Allows multiple major security modules to be stacked.
+ Modules are invoked in the order registered with a
+ "bail on fail" policy, in which the infrastructure
+ will stop processing once a denial is detected. Not
+ all modules can be stacked. SELinux, Smack and AppArmor are
+ known to be incompatible. User space components may
+ have trouble identifying the security module providing
+ data in some cases.
+
+ If you select this option you will have to select which
+ of the stackable modules you wish to be active. The
+ "Default security module" will be ignored. The boot line
+ "security=" option can be used to specify that one of
+ the modules identifed for stacking should be used instead
+  

[PATCH 09/10] LSM: Infrastructure management of the inode security

2018-09-11 Thread Casey Schaufler
Move management of the inode->i_security blob out
of the individual security modules and into the security
infrastructure. Instead of allocating the blobs from within
the modules the modules tell the infrastructure how much
space is required, and the space is allocated there.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h |  3 ++
 security/security.c   | 83 ++-
 security/selinux/hooks.c  | 32 +---
 security/selinux/include/objsec.h |  5 +-
 security/smack/smack_lsm.c| 70 --
 5 files changed, 98 insertions(+), 95 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 167ffbd4d0c0..416b20c3795b 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2030,6 +2030,7 @@ struct security_hook_list {
 struct lsm_blob_sizes {
int lbs_cred;
int lbs_file;
+   int lbs_inode;
 };
 
 /*
@@ -2092,9 +2093,11 @@ static inline void loadpin_add_hooks(void) { };
 #endif
 
 extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp);
+extern int lsm_inode_alloc(struct inode *inode);
 
 #ifdef CONFIG_SECURITY
 void lsm_early_cred(struct cred *cred);
+void lsm_early_inode(struct inode *inode);
 #endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/security.c b/security/security.c
index 5430cae73cf6..2501cdcbebff 100644
--- a/security/security.c
+++ b/security/security.c
@@ -41,6 +41,7 @@ struct security_hook_heads security_hook_heads 
__lsm_ro_after_init;
 static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
 
 static struct kmem_cache *lsm_file_cache;
+static struct kmem_cache *lsm_inode_cache;
 
 char *lsm_names;
 static struct lsm_blob_sizes blob_sizes;
@@ -101,6 +102,10 @@ int __init security_init(void)
lsm_file_cache = kmem_cache_create("lsm_file_cache",
   blob_sizes.lbs_file, 0,
   SLAB_PANIC, NULL);
+   if (blob_sizes.lbs_inode)
+   lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
+   blob_sizes.lbs_inode, 0,
+   SLAB_PANIC, NULL);
/*
 * The second call to a module specific init function
 * adds hooks to the hook lists and does any other early
@@ -111,6 +116,7 @@ int __init security_init(void)
 #ifdef CONFIG_SECURITY_LSM_DEBUG
pr_info("LSM: cred blob size   = %d\n", blob_sizes.lbs_cred);
pr_info("LSM: file blob size   = %d\n", blob_sizes.lbs_file);
+   pr_info("LSM: inode blob size   = %d\n", blob_sizes.lbs_inode);
 #endif
 
return 0;
@@ -288,6 +294,13 @@ void __init security_add_blobs(struct lsm_blob_sizes 
*needed)
 {
lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file);
+   /*
+* The inode blob gets an rcu_head in addition to
+* what the modules might need.
+*/
+   if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
+   blob_sizes.lbs_inode = sizeof(struct rcu_head);
+   lsm_set_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
 }
 
 /**
@@ -311,6 +324,46 @@ int lsm_file_alloc(struct file *file)
return 0;
 }
 
+/**
+ * lsm_inode_alloc - allocate a composite inode blob
+ * @inode: the inode that needs a blob
+ *
+ * Allocate the inode blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+int lsm_inode_alloc(struct inode *inode)
+{
+   if (!lsm_inode_cache) {
+   inode->i_security = NULL;
+   return 0;
+   }
+
+   inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS);
+   if (inode->i_security == NULL)
+   return -ENOMEM;
+   return 0;
+}
+
+/**
+ * lsm_early_inode - during initialization allocate a composite inode blob
+ * @inode: the inode that needs a blob
+ *
+ * Allocate the inode blob for all the modules if it's not already there
+ */
+void lsm_early_inode(struct inode *inode)
+{
+   int rc;
+
+   if (inode == NULL)
+   panic("%s: NULL inode.\n", __func__);
+   if (inode->i_security != NULL)
+   return;
+   rc = lsm_inode_alloc(inode);
+   if (rc)
+   panic("%s: Early inode alloc failed.\n", __func__);
+}
+
 /*
  * Hook list operation macros.
  *
@@ -557,14 +610,40 @@ EXPORT_SYMBOL(security_sb_parse_opts_str);
 
 int security_inode_alloc(struct inode *inode)
 {
-   inode->i_security = NULL;
-   return call_int_hook(inode_alloc_security, 0, inode);
+   int rc = lsm_inode_alloc(inode);
+
+   if (unlikely(rc))
+   return rc;
+   rc = call_int_hook(inode_alloc_security, 0, inode);
+   if (unlikely(rc))
+   security_inode_free(inode);
+   return rc;
+}
+
+static void inode_free_by_rcu(struct rcu_head 

[PATCH 06/10] LSM: Infrastructure management of the file security blob

2018-09-11 Thread Casey Schaufler
Move management of the file->f_security blob out of the
individual security modules and into the infrastructure.
The modules no longer allocate or free the data, instead
they tell the infrastructure how much space they require.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  1 +
 security/apparmor/lsm.c| 19 +++---
 security/security.c| 54 +++---
 security/selinux/hooks.c   | 25 ++
 security/smack/smack.h |  5 
 security/smack/smack_lsm.c | 26 +++---
 6 files changed, 78 insertions(+), 52 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 0bef312efd45..167ffbd4d0c0 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2029,6 +2029,7 @@ struct security_hook_list {
  */
 struct lsm_blob_sizes {
int lbs_cred;
+   int lbs_file;
 };
 
 /*
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index c2566aaa138e..15716b6ff860 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -431,21 +431,21 @@ static int apparmor_file_open(struct file *file)
 
 static int apparmor_file_alloc_security(struct file *file)
 {
-   int error = 0;
-
-   /* freed by apparmor_file_free_security */
+   struct aa_file_ctx *ctx = file_ctx(file);
struct aa_label *label = begin_current_label_crit_section();
-   file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL);
-   if (!file_ctx(file))
-   error = -ENOMEM;
-   end_current_label_crit_section(label);
 
-   return error;
+   spin_lock_init(&ctx->lock);
+   rcu_assign_pointer(ctx->label, aa_get_label(label));
+   end_current_label_crit_section(label);
+   return 0;
 }
 
 static void apparmor_file_free_security(struct file *file)
 {
-   aa_free_file_ctx(file_ctx(file));
+   struct aa_file_ctx *ctx = file_ctx(file);
+
+   if (ctx)
+   aa_put_label(rcu_access_pointer(ctx->label));
 }
 
 static int common_file_perm(const char *op, struct file *file, u32 mask)
@@ -1131,6 +1131,7 @@ static void apparmor_sock_graft(struct sock *sk, struct 
socket *parent)
  */
 struct lsm_blob_sizes apparmor_blob_sizes = {
.lbs_cred = sizeof(struct aa_task_ctx *),
+   .lbs_file = sizeof(struct aa_file_ctx),
 };
 
 static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = {
diff --git a/security/security.c b/security/security.c
index ff7df14f6db1..5430cae73cf6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -40,6 +40,8 @@
 struct security_hook_heads security_hook_heads __lsm_ro_after_init;
 static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
 
+static struct kmem_cache *lsm_file_cache;
+
 char *lsm_names;
 static struct lsm_blob_sizes blob_sizes;
 
@@ -92,6 +94,13 @@ int __init security_init(void)
 */
do_security_initcalls();
 
+   /*
+* Create any kmem_caches needed for blobs
+*/
+   if (blob_sizes.lbs_file)
+   lsm_file_cache = kmem_cache_create("lsm_file_cache",
+  blob_sizes.lbs_file, 0,
+  SLAB_PANIC, NULL);
/*
 * The second call to a module specific init function
 * adds hooks to the hook lists and does any other early
@@ -101,6 +110,7 @@ int __init security_init(void)
 
 #ifdef CONFIG_SECURITY_LSM_DEBUG
pr_info("LSM: cred blob size   = %d\n", blob_sizes.lbs_cred);
+   pr_info("LSM: file blob size   = %d\n", blob_sizes.lbs_file);
 #endif
 
return 0;
@@ -277,6 +287,28 @@ static void __init lsm_set_size(int *need, int *lbs)
 void __init security_add_blobs(struct lsm_blob_sizes *needed)
 {
lsm_set_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
+   lsm_set_size(&needed->lbs_file, &blob_sizes.lbs_file);
+}
+
+/**
+ * lsm_file_alloc - allocate a composite file blob
+ * @file: the file that needs a blob
+ *
+ * Allocate the file blob for all the modules
+ *
+ * Returns 0, or -ENOMEM if memory can't be allocated.
+ */
+int lsm_file_alloc(struct file *file)
+{
+   if (!lsm_file_cache) {
+   file->f_security = NULL;
+   return 0;
+   }
+
+   file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL);
+   if (file->f_security == NULL)
+   return -ENOMEM;
+   return 0;
 }
 
 /*
@@ -962,12 +994,28 @@ int security_file_permission(struct file *file, int mask)
 
 int security_file_alloc(struct file *file)
 {
-   return call_int_hook(file_alloc_security, 0, file);
+   int rc = lsm_file_alloc(file);
+
+   if (rc)
+   return rc;
+   rc = call_int_hook(file_alloc_security, 0, file);
+   if (unlikely(rc))
+   security_file_free(file);
+   return rc;
 }
 
 void security_file_free(struct file *file)
 {
+   void *blob;
+
+   if (!lsm_file_cache)
+   return;
+
   

[PATCH 04/10] LSM: Infrastructure management of the cred security blob

2018-09-11 Thread Casey Schaufler
Move management of the cred security blob out of the
security modules and into the security infrastructure.
Instead of allocating and freeing space the security
modules tell the infrastructure how much space they
require.

Some SELinux memory management debug code has been removed.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h |  14 
 kernel/cred.c |  13 
 security/Kconfig  |  11 
 security/apparmor/domain.c|   2 +-
 security/apparmor/include/cred.h  |  16 -
 security/apparmor/lsm.c   |  28 ++--
 security/apparmor/task.c  |   6 +-
 security/security.c   | 106 +-
 security/selinux/hooks.c  |  63 +-
 security/selinux/include/objsec.h |   4 ++
 security/selinux/selinuxfs.c  |   1 +
 security/smack/smack.h|   1 +
 security/smack/smack_lsm.c|  85 +---
 security/tomoyo/common.h  |  21 +-
 security/tomoyo/domain.c  |   4 +-
 security/tomoyo/securityfs_if.c   |  15 +++--
 security/tomoyo/tomoyo.c  |  56 +---
 17 files changed, 303 insertions(+), 143 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 97a020c616ad..0bef312efd45 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2024,6 +2024,13 @@ struct security_hook_list {
char*lsm;
 } __randomize_layout;
 
+/*
+ * Security blob size or offset data.
+ */
+struct lsm_blob_sizes {
+   int lbs_cred;
+};
+
 /*
  * Initializing a security_hook_list structure takes
  * up a lot of space in a source file. This macro takes
@@ -2036,6 +2043,7 @@ struct security_hook_list {
 extern struct security_hook_heads security_hook_heads;
 extern char *lsm_names;
 
+extern void security_add_blobs(struct lsm_blob_sizes *needed);
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm);
 
@@ -2082,4 +2090,10 @@ void __init loadpin_add_hooks(void);
 static inline void loadpin_add_hooks(void) { };
 #endif
 
+extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp);
+
+#ifdef CONFIG_SECURITY
+void lsm_early_cred(struct cred *cred);
+#endif
+
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/kernel/cred.c b/kernel/cred.c
index ecf03657e71c..fa2061ee4955 100644
--- a/kernel/cred.c
+++ b/kernel/cred.c
@@ -704,19 +704,6 @@ bool creds_are_invalid(const struct cred *cred)
 {
if (cred->magic != CRED_MAGIC)
return true;
-#ifdef CONFIG_SECURITY_SELINUX
-   /*
-* cred->security == NULL if security_cred_alloc_blank() or
-* security_prepare_creds() returned an error.
-*/
-   if (selinux_is_enabled() && cred->security) {
-   if ((unsigned long) cred->security < PAGE_SIZE)
-   return true;
-   if ((*(u32 *)cred->security & 0xff00) ==
-   (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8))
-   return true;
-   }
-#endif
return false;
 }
 EXPORT_SYMBOL(creds_are_invalid);
diff --git a/security/Kconfig b/security/Kconfig
index 27d8b2688f75..22f7664c4977 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -36,6 +36,17 @@ config SECURITY_WRITABLE_HOOKS
bool
default n
 
+config SECURITY_LSM_DEBUG
+   bool "Enable debugging of the LSM infrastructure"
+   depends on SECURITY
+   help
+ This allows you to choose debug messages related to
+ security modules configured into your kernel. These
+ messages may be helpful in determining how a security
+ module is using security blobs.
+
+ If you are unsure how to answer this question, answer N.
+
 config SECURITYFS
bool "Enable the securityfs filesystem"
help
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 08c88de0ffda..726910bba84b 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -975,7 +975,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm)
}
aa_put_label(cred_label(bprm->cred));
/* transfer reference, released when cred is freed */
-   cred_label(bprm->cred) = new;
+   set_cred_label(bprm->cred, new);
 
 done:
aa_put_label(label);
diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h
index e287b7d0d4be..a90eae76d7c1 100644
--- a/security/apparmor/include/cred.h
+++ b/security/apparmor/include/cred.h
@@ -23,8 +23,22 @@
 #include "policy_ns.h"
 #include "task.h"
 
-#define cred_label(X) ((X)->security)
+static inline struct aa_label *cred_label(const struct cred *cred)
+{
+   struct aa_label **blob = cred->security;
+
+   AA_BUG(!blob);
+   return *blob;
+}
 
+static inline void set_cred_label(const struct cred *cred,
+ struct aa_label *label

[PATCH 05/10] SELinux: Abstract use of file security blob

2018-09-11 Thread Casey Schaufler
Don't use the file->f_security pointer directly.
Provide a helper function that provides the security blob pointer.

Signed-off-by: Casey Schaufler 
---
 security/selinux/hooks.c  | 18 +-
 security/selinux/include/objsec.h |  5 +
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9b49698754a7..94b3123c237b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -397,7 +397,7 @@ static int file_alloc_security(struct file *file)
 
 static void file_free_security(struct file *file)
 {
-   struct file_security_struct *fsec = file->f_security;
+   struct file_security_struct *fsec = selinux_file(file);
file->f_security = NULL;
kmem_cache_free(file_security_cache, fsec);
 }
@@ -1880,7 +1880,7 @@ static int file_has_perm(const struct cred *cred,
 struct file *file,
 u32 av)
 {
-   struct file_security_struct *fsec = file->f_security;
+   struct file_security_struct *fsec = selinux_file(file);
struct inode *inode = file_inode(file);
struct common_audit_data ad;
u32 sid = cred_sid(cred);
@@ -2224,7 +2224,7 @@ static int selinux_binder_transfer_file(struct 
task_struct *from,
struct file *file)
 {
u32 sid = task_sid(to);
-   struct file_security_struct *fsec = file->f_security;
+   struct file_security_struct *fsec = selinux_file(file);
struct dentry *dentry = file->f_path.dentry;
struct inode_security_struct *isec;
struct common_audit_data ad;
@@ -3536,7 +3536,7 @@ static int selinux_revalidate_file_permission(struct file 
*file, int mask)
 static int selinux_file_permission(struct file *file, int mask)
 {
struct inode *inode = file_inode(file);
-   struct file_security_struct *fsec = file->f_security;
+   struct file_security_struct *fsec = selinux_file(file);
struct inode_security_struct *isec;
u32 sid = current_sid();
 
@@ -3571,7 +3571,7 @@ static int ioctl_has_perm(const struct cred *cred, struct 
file *file,
u32 requested, u16 cmd)
 {
struct common_audit_data ad;
-   struct file_security_struct *fsec = file->f_security;
+   struct file_security_struct *fsec = selinux_file(file);
struct inode *inode = file_inode(file);
struct inode_security_struct *isec;
struct lsm_ioctlop_audit ioctl;
@@ -3823,7 +3823,7 @@ static void selinux_file_set_fowner(struct file *file)
 {
struct file_security_struct *fsec;
 
-   fsec = file->f_security;
+   fsec = selinux_file(file);
fsec->fown_sid = current_sid();
 }
 
@@ -3838,7 +3838,7 @@ static int selinux_file_send_sigiotask(struct task_struct 
*tsk,
/* struct fown_struct is never outside the context of a struct file */
file = container_of(fown, struct file, f_owner);
 
-   fsec = file->f_security;
+   fsec = selinux_file(file);
 
if (!signum)
perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */
@@ -3862,7 +3862,7 @@ static int selinux_file_open(struct file *file)
struct file_security_struct *fsec;
struct inode_security_struct *isec;
 
-   fsec = file->f_security;
+   fsec = selinux_file(file);
isec = inode_security(file_inode(file));
/*
 * Save inode label and policy sequence number
@@ -4002,7 +4002,7 @@ static int selinux_kernel_module_from_file(struct file 
*file)
ad.type = LSM_AUDIT_DATA_FILE;
ad.u.file = file;
 
-   fsec = file->f_security;
+   fsec = selinux_file(file);
if (sid != fsec->sid) {
rc = avc_has_perm(&selinux_state,
  sid, fsec->sid, SECCLASS_FD, FD__USE, &ad);
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index db1c7000ada3..2586fbc7e38c 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -167,4 +167,9 @@ static inline struct task_security_struct 
*selinux_cred(const struct cred *cred)
return cred->security;
 }
 
+static inline struct file_security_struct *selinux_file(const struct file 
*file)
+{
+   return file->f_security;
+}
+
 #endif /* _SELINUX_OBJSEC_H_ */
-- 
2.17.1


___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


[PATCH 08/10] Smack: Abstract use of inode security blob

2018-09-11 Thread Casey Schaufler
Don't use the inode->i_security pointer directly.
Provide a helper function that provides the security blob pointer.

Signed-off-by: Casey Schaufler 
---
 security/smack/smack.h |  9 +++--
 security/smack/smack_lsm.c | 32 
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/security/smack/smack.h b/security/smack/smack.h
index 043525a52e94..5da5bd1b9b47 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -367,12 +367,17 @@ static inline struct smack_known **smack_file(const 
struct file *file)
return file->f_security;
 }
 
+static inline struct inode_smack *smack_inode(const struct inode *inode)
+{
+   return inode->i_security;
+}
+
 /*
  * Is the directory transmuting?
  */
 static inline int smk_inode_transmutable(const struct inode *isp)
 {
-   struct inode_smack *sip = isp->i_security;
+   struct inode_smack *sip = smack_inode(isp);
return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0;
 }
 
@@ -381,7 +386,7 @@ static inline int smk_inode_transmutable(const struct inode 
*isp)
  */
 static inline struct smack_known *smk_of_inode(const struct inode *isp)
 {
-   struct inode_smack *sip = isp->i_security;
+   struct inode_smack *sip = smack_inode(isp);
return sip->smk_inode;
 }
 
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index d1430341798f..364699ad55b9 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -166,7 +166,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, 
int rc)
 static int smk_bu_inode(struct inode *inode, int mode, int rc)
 {
struct task_smack *tsp = smack_cred(current_cred());
-   struct inode_smack *isp = inode->i_security;
+   struct inode_smack *isp = smack_inode(inode);
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -198,7 +198,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
struct task_smack *tsp = smack_cred(current_cred());
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file_inode(file);
-   struct inode_smack *isp = inode->i_security;
+   struct inode_smack *isp = smack_inode(inode);
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -228,7 +228,7 @@ static int smk_bu_credfile(const struct cred *cred, struct 
file *file,
struct task_smack *tsp = smack_cred(cred);
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file_inode(file);
-   struct inode_smack *isp = inode->i_security;
+   struct inode_smack *isp = smack_inode(inode);
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
if (isp->smk_flags & SMK_INODE_IMPURE)
@@ -824,7 +824,7 @@ static int smack_set_mnt_opts(struct super_block *sb,
/*
 * Initialize the root inode.
 */
-   isp = inode->i_security;
+   isp = smack_inode(inode);
if (isp == NULL) {
isp = new_inode_smack(sp->smk_root);
if (isp == NULL)
@@ -912,7 +912,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm)
if (bprm->called_set_creds)
return 0;
 
-   isp = inode->i_security;
+   isp = smack_inode(inode);
if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task)
return 0;
 
@@ -992,7 +992,7 @@ static void smack_inode_free_rcu(struct rcu_head *head)
  */
 static void smack_inode_free_security(struct inode *inode)
 {
-   struct inode_smack *issp = inode->i_security;
+   struct inode_smack *issp = smack_inode(inode);
 
/*
 * The inode may still be referenced in a path walk and
@@ -1020,7 +1020,7 @@ static int smack_inode_init_security(struct inode *inode, 
struct inode *dir,
 const struct qstr *qstr, const char **name,
 void **value, size_t *len)
 {
-   struct inode_smack *issp = inode->i_security;
+   struct inode_smack *issp = smack_inode(inode);
struct smack_known *skp = smk_of_current();
struct smack_known *isp = smk_of_inode(inode);
struct smack_known *dsp = smk_of_inode(dir);
@@ -1358,7 +1358,7 @@ static void smack_inode_post_setxattr(struct dentry 
*dentry, const char *name,
  const void *value, size_t size, int flags)
 {
struct smack_known *skp;
-   struct inode_smack *isp = d_backing_inode(dentry)->i_security;
+   struct inode_smack *isp = smack_inode(d_backing_inode(dentry));
 
if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) {
isp->smk_flags |= SMK_INODE_TRANSMUTE;
@@ -1439,7 +1439,7 @@ static int smack_inode_removexattr(struct dentry *dentry, 
const char *name)
if (rc != 0)
return rc;
 
-   isp = d_backing_inode(dentry)->i_security;
+   isp = smack_inode(d_backing_inode(dentry));
/*
 *

[PATCH 03/10] SELinux: Abstract use of cred security blob

2018-09-11 Thread Casey Schaufler
Don't use the cred->security pointer directly.
Provide a helper function that provides the security blob pointer.

Signed-off-by: Casey Schaufler 
---
 security/selinux/hooks.c  | 54 +++
 security/selinux/include/objsec.h |  5 +++
 security/selinux/xfrm.c   |  4 +--
 3 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ad9a9b8e9979..9d6cdd21acb6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -228,7 +228,7 @@ static inline u32 cred_sid(const struct cred *cred)
 {
const struct task_security_struct *tsec;
 
-   tsec = cred->security;
+   tsec = selinux_cred(cred);
return tsec->sid;
 }
 
@@ -464,7 +464,7 @@ static int may_context_mount_sb_relabel(u32 sid,
struct superblock_security_struct *sbsec,
const struct cred *cred)
 {
-   const struct task_security_struct *tsec = cred->security;
+   const struct task_security_struct *tsec = selinux_cred(cred);
int rc;
 
rc = avc_has_perm(&selinux_state,
@@ -483,7 +483,7 @@ static int may_context_mount_inode_relabel(u32 sid,
struct superblock_security_struct *sbsec,
const struct cred *cred)
 {
-   const struct task_security_struct *tsec = cred->security;
+   const struct task_security_struct *tsec = selinux_cred(cred);
int rc;
rc = avc_has_perm(&selinux_state,
  tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM,
@@ -1949,7 +1949,7 @@ static int may_create(struct inode *dir,
  struct dentry *dentry,
  u16 tclass)
 {
-   const struct task_security_struct *tsec = current_security();
+   const struct task_security_struct *tsec = selinux_cred(current_cred());
struct inode_security_struct *dsec;
struct superblock_security_struct *sbsec;
u32 sid, newsid;
@@ -1971,7 +1971,7 @@ static int may_create(struct inode *dir,
if (rc)
return rc;
 
-   rc = selinux_determine_inode_label(current_security(), dir,
+   rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir,
   &dentry->d_name, tclass, &newsid);
if (rc)
return rc;
@@ -2478,8 +2478,8 @@ static int selinux_bprm_set_creds(struct linux_binprm 
*bprm)
if (bprm->called_set_creds)
return 0;
 
-   old_tsec = current_security();
-   new_tsec = bprm->cred->security;
+   old_tsec = selinux_cred(current_cred());
+   new_tsec = selinux_cred(bprm->cred);
isec = inode_security(inode);
 
/* Default to the current task SID. */
@@ -2643,7 +2643,7 @@ static void selinux_bprm_committing_creds(struct 
linux_binprm *bprm)
struct rlimit *rlim, *initrlim;
int rc, i;
 
-   new_tsec = bprm->cred->security;
+   new_tsec = selinux_cred(bprm->cred);
if (new_tsec->sid == new_tsec->osid)
return;
 
@@ -2686,7 +2686,7 @@ static void selinux_bprm_committing_creds(struct 
linux_binprm *bprm)
  */
 static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
 {
-   const struct task_security_struct *tsec = current_security();
+   const struct task_security_struct *tsec = selinux_cred(current_cred());
struct itimerval itimer;
u32 osid, sid;
int rc, i;
@@ -2989,7 +2989,7 @@ static int selinux_dentry_init_security(struct dentry 
*dentry, int mode,
u32 newsid;
int rc;
 
-   rc = selinux_determine_inode_label(current_security(),
+   rc = selinux_determine_inode_label(selinux_cred(current_cred()),
   d_inode(dentry->d_parent), name,
   inode_mode_to_security_class(mode),
   &newsid);
@@ -3009,14 +3009,14 @@ static int selinux_dentry_create_files_as(struct dentry 
*dentry, int mode,
int rc;
struct task_security_struct *tsec;
 
-   rc = selinux_determine_inode_label(old->security,
+   rc = selinux_determine_inode_label(selinux_cred(old),
   d_inode(dentry->d_parent), name,
   inode_mode_to_security_class(mode),
   &newsid);
if (rc)
return rc;
 
-   tsec = new->security;
+   tsec = selinux_cred(new);
tsec->create_sid = newsid;
return 0;
 }
@@ -3026,7 +3026,7 @@ static int selinux_inode_init_security(struct inode 
*inode, struct inode *dir,
   const char **name,
   void **value, size_t *len)
 {
-   const struct task_security_struct *tsec = current_security();
+   const struct task_security_struct *tsec = selinux_cred(current_cred

[PATCH 02/10] Smack: Abstract use of cred security blob

2018-09-11 Thread Casey Schaufler
Don't use the cred->security pointer directly.
Provide a helper function that provides the security blob pointer.

Signed-off-by: Casey Schaufler 
---
 security/smack/smack.h| 14 +++--
 security/smack/smack_access.c |  4 +--
 security/smack/smack_lsm.c| 57 +--
 security/smack/smackfs.c  | 18 +--
 4 files changed, 50 insertions(+), 43 deletions(-)

diff --git a/security/smack/smack.h b/security/smack/smack.h
index f7db791fb566..0b55d6a55b26 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -356,6 +356,11 @@ extern struct list_head smack_onlycap_list;
 #define SMACK_HASH_SLOTS 16
 extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS];
 
+static inline struct task_smack *smack_cred(const struct cred *cred)
+{
+   return cred->security;
+}
+
 /*
  * Is the directory transmuting?
  */
@@ -382,13 +387,16 @@ static inline struct smack_known *smk_of_task(const 
struct task_smack *tsp)
return tsp->smk_task;
 }
 
-static inline struct smack_known *smk_of_task_struct(const struct task_struct 
*t)
+static inline struct smack_known *smk_of_task_struct(
+   const struct task_struct *t)
 {
struct smack_known *skp;
+   const struct cred *cred;
 
rcu_read_lock();
-   skp = smk_of_task(__task_cred(t)->security);
+   cred = __task_cred(t);
rcu_read_unlock();
+   skp = smk_of_task(smack_cred(cred));
return skp;
 }
 
@@ -405,7 +413,7 @@ static inline struct smack_known *smk_of_forked(const 
struct task_smack *tsp)
  */
 static inline struct smack_known *smk_of_current(void)
 {
-   return smk_of_task(current_security());
+   return smk_of_task(smack_cred(current_cred()));
 }
 
 /*
diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c
index 9a4c0ad46518..489d49a20b47 100644
--- a/security/smack/smack_access.c
+++ b/security/smack/smack_access.c
@@ -275,7 +275,7 @@ int smk_tskacc(struct task_smack *tsp, struct smack_known 
*obj_known,
 int smk_curacc(struct smack_known *obj_known,
   u32 mode, struct smk_audit_info *a)
 {
-   struct task_smack *tsp = current_security();
+   struct task_smack *tsp = smack_cred(current_cred());
 
return smk_tskacc(tsp, obj_known, mode, a);
 }
@@ -635,7 +635,7 @@ DEFINE_MUTEX(smack_onlycap_lock);
  */
 bool smack_privileged_cred(int cap, const struct cred *cred)
 {
-   struct task_smack *tsp = cred->security;
+   struct task_smack *tsp = smack_cred(cred);
struct smack_known *skp = tsp->smk_task;
struct smack_known_list_elem *sklep;
int rc;
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 340fc30ad85d..68ee3ae8f25c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -122,7 +122,7 @@ static int smk_bu_note(char *note, struct smack_known *sskp,
 static int smk_bu_current(char *note, struct smack_known *oskp,
  int mode, int rc)
 {
-   struct task_smack *tsp = current_security();
+   struct task_smack *tsp = smack_cred(current_cred());
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
if (rc <= 0)
@@ -143,7 +143,7 @@ static int smk_bu_current(char *note, struct smack_known 
*oskp,
 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
 static int smk_bu_task(struct task_struct *otp, int mode, int rc)
 {
-   struct task_smack *tsp = current_security();
+   struct task_smack *tsp = smack_cred(current_cred());
struct smack_known *smk_task = smk_of_task_struct(otp);
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
@@ -165,7 +165,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, 
int rc)
 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
 static int smk_bu_inode(struct inode *inode, int mode, int rc)
 {
-   struct task_smack *tsp = current_security();
+   struct task_smack *tsp = smack_cred(current_cred());
struct inode_smack *isp = inode->i_security;
char acc[SMK_NUM_ACCESS_TYPE + 1];
 
@@ -195,7 +195,7 @@ static int smk_bu_inode(struct inode *inode, int mode, int 
rc)
 #ifdef CONFIG_SECURITY_SMACK_BRINGUP
 static int smk_bu_file(struct file *file, int mode, int rc)
 {
-   struct task_smack *tsp = current_security();
+   struct task_smack *tsp = smack_cred(current_cred());
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file_inode(file);
struct inode_smack *isp = inode->i_security;
@@ -225,7 +225,7 @@ static int smk_bu_file(struct file *file, int mode, int rc)
 static int smk_bu_credfile(const struct cred *cred, struct file *file,
int mode, int rc)
 {
-   struct task_smack *tsp = cred->security;
+   struct task_smack *tsp = smack_cred(cred);
struct smack_known *sskp = tsp->smk_task;
struct inode *inode = file_inode(file);
struct inode_smack *isp = inode->i_security;
@@ -429,7 +429,7 @@ static int smk_ptrace_rule_check(struc

[PATCH 01/10] procfs: add smack subdir to attrs

2018-09-11 Thread Casey Schaufler
Back in 2007 I made what turned out to be a rather serious
mistake in the implementation of the Smack security module.
The SELinux module used an interface in /proc to manipulate
the security context on processes. Rather than use a similar
interface, I used the same interface. The AppArmor team did
likewise. Now /proc/.../attr/current will tell you the
security "context" of the process, but it will be different
depending on the security module you're using.

This patch provides a subdirectory in /proc/.../attr for
Smack. Smack user space can use the "current" file in
this subdirectory and never have to worry about getting
SELinux attributes by mistake. Programs that use the
old interface will continue to work (or fail, as the case
may be) as before.

The proposed S.A.R.A security module is dependent on
the mechanism to create its own attr subdirectory.

The original implementation is by Kees Cook.

Signed-off-by: Casey Schaufler 
---
 Documentation/admin-guide/LSM/index.rst | 13 +++--
 fs/proc/base.c  | 64 +
 fs/proc/internal.h  |  1 +
 include/linux/security.h| 15 --
 security/security.c | 24 --
 5 files changed, 96 insertions(+), 21 deletions(-)

diff --git a/Documentation/admin-guide/LSM/index.rst 
b/Documentation/admin-guide/LSM/index.rst
index c980dfe9abf1..9842e21afd4a 100644
--- a/Documentation/admin-guide/LSM/index.rst
+++ b/Documentation/admin-guide/LSM/index.rst
@@ -17,9 +17,8 @@ MAC extensions, other extensions can be built using the LSM 
to provide
 specific changes to system operation when these tweaks are not available
 in the core functionality of Linux itself.
 
-Without a specific LSM built into the kernel, the default LSM will be the
-Linux capabilities system. Most LSMs choose to extend the capabilities
-system, building their checks on top of the defined capability hooks.
+The Linux capabilities modules will always be included. This may be
+followed by any number of "minor" modules and at most one "major" module.
 For more details on capabilities, see ``capabilities(7)`` in the Linux
 man-pages project.
 
@@ -30,6 +29,14 @@ order in which checks are made. The capability module will 
always
 be first, followed by any "minor" modules (e.g. Yama) and then
 the one "major" module (e.g. SELinux) if there is one configured.
 
+Process attributes associated with "major" security modules should
+be accessed and maintained using the special files in ``/proc/.../attr``.
+A security module may maintain a module specific subdirectory there,
+named after the module. ``/proc/.../attr/smack`` is provided by the Smack
+security module and contains all its special files. The files directly
+in ``/proc/.../attr`` remain as legacy interfaces for modules that provide
+subdirectories.
+
 .. toctree::
:maxdepth: 1
 
diff --git a/fs/proc/base.c b/fs/proc/base.c
index ccf86f16d9f0..bd2dd85310fe 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -140,9 +140,13 @@ struct pid_entry {
 #define REG(NAME, MODE, fops)  \
NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
 #define ONE(NAME, MODE, show)  \
-   NOD(NAME, (S_IFREG|(MODE)), \
+   NOD(NAME, (S_IFREG|(MODE)), \
NULL, &proc_single_file_operations, \
{ .proc_show = show } )
+#define ATTR(LSM, NAME, MODE)  \
+   NOD(NAME, (S_IFREG|(MODE)), \
+   NULL, &proc_pid_attr_operations,\
+   { .lsm = LSM })
 
 /*
  * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -2503,7 +2507,7 @@ static ssize_t proc_pid_attr_read(struct file * file, 
char __user * buf,
if (!task)
return -ESRCH;
 
-   length = security_getprocattr(task,
+   length = security_getprocattr(task, PROC_I(inode)->op.lsm,
  (char*)file->f_path.dentry->d_name.name,
  &p);
put_task_struct(task);
@@ -2552,7 +2556,9 @@ static ssize_t proc_pid_attr_write(struct file * file, 
const char __user * buf,
if (rv < 0)
goto out_free;
 
-   rv = security_setprocattr(file->f_path.dentry->d_name.name, page, 
count);
+   rv = security_setprocattr(PROC_I(inode)->op.lsm,
+ file->f_path.dentry->d_name.name, page,
+ count);
mutex_unlock(¤t->signal->cred_guard_mutex);
 out_free:
kfree(page);
@@ -2566,13 +2572,53 @@ static const struct file_operations 
proc_pid_attr_operations = {
.llseek = generic_file_llseek,
 };
 
+#define LSM_DIR_OPS(LSM) \
+static int proc_##LSM##_attr_dir_iterate(struct file *filp, \
+struct dir_context *ctx) \
+{ \
+   return proc_pident_readdir(filp, ctx, \
+  

[PATCH v2 00/10] LSM: Module stacking in support of S.A.R.A and Landlock

2018-09-11 Thread Casey Schaufler
LSM: Module stacking in support of S.A.R.A and Landlock

v2: Reduce the patchset to what is required to support
the proposed S.A.R.A. and LandLock security modules

The S.A.R.A. security module is intended to be used
in conjunction with other security modules. It requires
state to be maintained for the credential, which
in turn requires a mechanism for sharing the credential
security blob. The module also requires mechanism for
user space manipulation of the credential information,
hence an additional subdirectory in /proc/.../attr.

The LandLock security module provides user configurable
policy in the secmark mechanism. It requires data in
the credential, file and inode security blobs. For this
to be used along side the existing "major" security
modules mechanism for sharing these blobs is provided.

A side effect of providing sharing of the crendential
security blob is that the TOMOYO module can be used at
the same time as the other "major" modules.

The mechanism for configuring which security modules are
enabled has to change when stacking in enabled. Any
module that uses just the security blobs that are shared
can be selected. Additionally, one other "major" module
can be selected.

The security module stacking issues around networking and
IPC are not addressed here as they are beyond what is
required for TOMOYO, S.A.R.A and LandLock.

git://github.com/cschaufler/lsm-stacking.git#stacking-4.19-rc2-saralock

Signed-off-by: Casey Schaufler 
---
 Documentation/admin-guide/LSM/index.rst |  23 ++-
 fs/proc/base.c  |  64 ++-
 fs/proc/internal.h  |   1 +
 include/linux/lsm_hooks.h   |  20 ++-
 include/linux/security.h|  15 +-
 kernel/cred.c   |  13 --
 security/Kconfig|  92 ++
 security/apparmor/domain.c  |   2 +-
 security/apparmor/include/cred.h|  24 ++-
 security/apparmor/include/file.h|   9 +-
 security/apparmor/include/lib.h |   4 +
 security/apparmor/lsm.c |  53 --
 security/apparmor/task.c|   6 +-
 security/security.c | 293 ++--
 security/selinux/hooks.c| 215 ---
 security/selinux/include/objsec.h   |  37 +++-
 security/selinux/selinuxfs.c|   5 +-
 security/selinux/xfrm.c |   4 +-
 security/smack/smack.h  |  42 -
 security/smack/smack_access.c   |   4 +-
 security/smack/smack_lsm.c  | 283 +++---
 security/smack/smackfs.c|  18 +-
 security/tomoyo/common.h|  31 +++-
 security/tomoyo/domain.c|   4 +-
 security/tomoyo/securityfs_if.c |  15 +-
 security/tomoyo/tomoyo.c|  57 +--
 26 files changed, 899 insertions(+), 435 deletions(-)

___
Selinux mailing list
Selinux@tycho.nsa.gov
To unsubscribe, send email to selinux-le...@tycho.nsa.gov.
To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.


Re: MLS dominance check behavior on el7

2018-09-11 Thread Stephen Smalley

On 09/10/2018 06:30 PM, Ted Toth wrote:
mcstrans mcscolor.c also uses the same logic I'd been using to check 
dominance so this too will no longer function as expected on el7. Do you 
any suggestions for doing a 'generic' (one not tied to a specific 
resource class) dominance check in lieu of context contains?


You should probably define your own permission with its own constraint 
to avoid depending on the base policy's particular constraint 
definitions.  Certainly for your own code.  For mcstrans, mcscolor 
probably ought to be switched to using at least a separate permission in 
the context class if not its own class to avoid overloading the meaning 
with pam_selinux's usage (or vice versa, but likely harder to change 
pam_selinux at this point).


It is possible to define an entirely new class, its permissions, and its 
mls constraints via a CIL module IIUC, without needing to change the 
base policy.


I don't think you can add a permission to an existing class via a CIL 
module currently, unfortunately, so you can't just extend the context 
class without modifying the base policy.  So it may be easier to define 
an entirely new class.


The class and permission ought to be specific to the usage.  For 
example, mcstrans could have its own class (mcstrans) with its own 
permissions (e.g. color_match or color_use or ...) that abstract away 
the logical check being performed.  Dominance checks performed for 
different reasons ought to use different permissions so that one can 
distinguish what TE pairs are allowed them.


Your code could likewise define and use its own class and permission.

Does that make sense?



Ted

On Mon, Sep 10, 2018 at 1:19 PM Ted Toth > wrote:


Understood, thanks.

On Mon, Sep 10, 2018 at 12:46 PM Stephen Smalley mailto:s...@tycho.nsa.gov>> wrote:

On 09/10/2018 01:13 PM, Ted Toth wrote:
 > We currently have code running on el6 that does a MLS
dominance check by
 > calling security_compute_av_raw with the security object class
 > SECCLASS_CONTEXT with permission CONTEXT__CONTAINS as you can
see in the
 > python code below. When I run this code on el6 s1 dominates
s0 however
 > when I run the same code on el7 s1 does not dominate s0. On
both systems
 > the file read dominance check works as expected. Can anyone
help me
 > understand why the context contains check does not work the
same on both
 > systems?

That would depend entirely on how the constraint is written in the
policy.  I assume this is with the -mls policy on both?  seinfo
--constrain | grep -C1 context would show you the constraint in the
kernel policy.

Looks like refpolicy defines it as:
mlsconstrain context contains
          (( h1 dom h2 ) and ( l1 domby l2));

The 2nd part of the constraint was introduced by:
commit 4c365f4a6a6f933dd13b0127e03f832c6a6cf8fc
Author: Harry Ciao mailto:qingtao@windriver.com>>
Date:   Tue Feb 15 10:16:32 2011 +0800

      l1 domby l2 for contains MLS constraint

      As identified by Stephan Smalley, the current MLS
constraint for the
      contains permission of the context class should consider
the current
      level of a user along with the clearance level so that
mls_systemlow
      is no longer considered contained in mls_systemhigh.

      Signed-off-by: Harry Ciao mailto:qingtao@windriver.com>>

This was to prevent a user from logging in at a level below their
authorized range, in the unusual scenario where the user's low
level was
not s0/systemlow.

 >
 > Ted
 >
 >

-
 >
 > import selinux
 >
 > SECCLASS_CONTEXT = selinux.string_to_security_class("context")
 > CONTEXT__CONTAINS =
selinux.string_to_av_perm(SECCLASS_CONTEXT, "contains")
 > SECCLASS_FILE = selinux.string_to_security_class("file")
 > FILE__READ = selinux.string_to_av_perm(SECCLASS_FILE, "read")
 >
 > raw_con1 = "user_u:user_r:user_t:s1"
 > raw_con2 = "user_u:user_r:user_t:s0"
 >
 > avd = selinux.av_decision()
 > selinux.avc_reset()
 > try:
 >      rc = selinux.security_compute_av_raw(raw_con1, raw_con2,
 > SECCLASS_CONTEXT, CONTEXT__CONTAINS, avd)
 >      if rc < 0:
 >          print("selinux.security_compute_av_raw failed for %s
%s" %
 > (raw_con1, raw_con2))
 >      if (avd.allowed & CONTEXT__CONTAINS) == CONTEXT__CONTAINS:
 >          print("