* running interpreted scripts in different domains
@ 2004-07-18 20:33 Joshua Brindle
2004-07-19 8:28 ` Luke Kenneth Casson Leighton
2004-07-20 15:42 ` James Carter
0 siblings, 2 replies; 14+ messages in thread
From: Joshua Brindle @ 2004-07-18 20:33 UTC (permalink / raw)
To: SELinux
Ok, so I had this seemingly good idea to let apache run interpreted apps
(php, perl, whathaveyou) in different domains. To do this I started
playing with fastcgi to do the type transition from apache to the
interpreters domain (which works well) but that leaves all php scripts
in the same domain (php_t) which then can't be isolated from one
another. The idea is to have a php domain for each user (method_php_t)
and so on. The only way I could think to do this was to use fastcgi's
wrapper function to setexec() before calling the interpreter (it will do
this per user). So the idea is that there is a php script of a user
labeled with something like method_php_script_t and the fastcgi wrapper
would read that target context and paired with it's source context ask
selinux what the auto type trans would be so that it can explicitly do
it with setexec().
The problem is that the userspace avc doesn't currently provide this
information, all you can get is an access decision or a labeling or
relabeling decision. It seems a little extreme to add a
security_compute_trans() to the userspace avc (and selinuxfs filesystem,
etc) just to make scripts a little more isolated and provide more fine
grained access but I can't think of another (good) way to do this. The
alternative would be to use default types but that isn't very scalable
for X number of interpreters times N number of users.
Can anyone else think of a way to accomplish this or shall I try adding
a calculate auto type trans to the userspace avc's?
Joshua Brindle
Hardened Gentoo
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-18 20:33 running interpreted scripts in different domains Joshua Brindle
@ 2004-07-19 8:28 ` Luke Kenneth Casson Leighton
2004-07-19 11:56 ` Russell Coker
2004-07-20 15:42 ` James Carter
1 sibling, 1 reply; 14+ messages in thread
From: Luke Kenneth Casson Leighton @ 2004-07-19 8:28 UTC (permalink / raw)
To: Joshua Brindle; +Cc: SELinux
it sounds to me like you almost need to have _two_ contexts.
one method_php_t and the other user_t.
and to be able to make access decisions like this:
allow method_php_t+user_t bin_t:lnk_file file_read;
meaning "if you have both the method_php_t context AND the user_t
context, then allow reading of symbolic links in /bin".
allowing to have two [or more?] simultaneous contexts might also
help with user directories and stuff, although i have to admit that
i sufficiently don't grok the issues there to be able to anything
other than hint / say "what about this?".
l.
On Sun, Jul 18, 2004 at 04:33:22PM -0400, Joshua Brindle wrote:
> Ok, so I had this seemingly good idea to let apache run interpreted apps
> (php, perl, whathaveyou) in different domains. To do this I started
> playing with fastcgi to do the type transition from apache to the
> interpreters domain (which works well) but that leaves all php scripts
> in the same domain (php_t) which then can't be isolated from one
> another. The idea is to have a php domain for each user (method_php_t)
> and so on. The only way I could think to do this was to use fastcgi's
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-19 8:28 ` Luke Kenneth Casson Leighton
@ 2004-07-19 11:56 ` Russell Coker
2004-07-19 12:01 ` Joshua Brindle
0 siblings, 1 reply; 14+ messages in thread
From: Russell Coker @ 2004-07-19 11:56 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton; +Cc: Joshua Brindle, SELinux
On Mon, 19 Jul 2004 18:28, Luke Kenneth Casson Leighton <lkcl@lkcl.net> wrote:
> it sounds to me like you almost need to have _two_ contexts.
>
> one method_php_t and the other user_t.
>
> and to be able to make access decisions like this:
>
> allow method_php_t+user_t bin_t:lnk_file file_read;
>
> meaning "if you have both the method_php_t context AND the user_t
> context, then allow reading of symbolic links in /bin".
Currently in SE Linux each process has exactly one context, it can only gain a
new context by dropping the old one. If a process could have two contexts
then it could potentially go through a series of operations to collect
multiple contexts ending up with a large set of access rights which were not
planned by the person who wrote the policy. Some other security systems have
had problems similar to this.
--
http://www.coker.com.au/selinux/ My NSA Security Enhanced Linux packages
http://www.coker.com.au/bonnie++/ Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/ Postal SMTP/POP benchmark
http://www.coker.com.au/~russell/ My home page
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-19 11:56 ` Russell Coker
@ 2004-07-19 12:01 ` Joshua Brindle
0 siblings, 0 replies; 14+ messages in thread
From: Joshua Brindle @ 2004-07-19 12:01 UTC (permalink / raw)
To: russell; +Cc: Luke Kenneth Casson Leighton, SELinux
Russell Coker wrote:
>On Mon, 19 Jul 2004 18:28, Luke Kenneth Casson Leighton <lkcl@lkcl.net> wrote:
>
>
>>it sounds to me like you almost need to have _two_ contexts.
>>
>>one method_php_t and the other user_t.
>>
>>and to be able to make access decisions like this:
>>
>> allow method_php_t+user_t bin_t:lnk_file file_read;
>>
>>meaning "if you have both the method_php_t context AND the user_t
>>context, then allow reading of symbolic links in /bin".
>>
>>
>
>Currently in SE Linux each process has exactly one context, it can only gain a
>new context by dropping the old one. If a process could have two contexts
>then it could potentially go through a series of operations to collect
>multiple contexts ending up with a large set of access rights which were not
>planned by the person who wrote the policy. Some other security systems have
>had problems similar to this.
>
>
>
Right, fastcgi supports having multiple interpreters running (one per
uid generally)
so the question is not to get the information to fastcgi about what
context to put in setexeccon().
Joshua Brindle
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-18 20:33 running interpreted scripts in different domains Joshua Brindle
2004-07-19 8:28 ` Luke Kenneth Casson Leighton
@ 2004-07-20 15:42 ` James Carter
2004-07-20 18:14 ` Joshua Brindle
1 sibling, 1 reply; 14+ messages in thread
From: James Carter @ 2004-07-20 15:42 UTC (permalink / raw)
To: Joshua Brindle; +Cc: SELinux
On Sun, 2004-07-18 at 16:33, Joshua Brindle wrote:
> Ok, so I had this seemingly good idea to let apache run interpreted apps
> (php, perl, whathaveyou) in different domains. To do this I started
> playing with fastcgi to do the type transition from apache to the
> interpreters domain (which works well) but that leaves all php scripts
> in the same domain (php_t) which then can't be isolated from one
> another. The idea is to have a php domain for each user (method_php_t)
> and so on. The only way I could think to do this was to use fastcgi's
> wrapper function to setexec() before calling the interpreter (it will do
> this per user). So the idea is that there is a php script of a user
> labeled with something like method_php_script_t and the fastcgi wrapper
> would read that target context and paired with it's source context ask
> selinux what the auto type trans would be so that it can explicitly do
> it with setexec().
>
Why can't the kernel do the auto transition? Maybe I don't understand
what you are using for your source and target contexts.
If you call security_compute_create with fastcgi's context as the
source, the script's context as the target, and using the
SECCLASS_PROCESS class, then you will get the same result as the kernel
when it looks for the default transition in selinux_bprm_security. So
if you take the new context returned by security_compute_create and call
setexec with it, you will end up with the same result that you would
have if you had just let the kernel do the auto transition.
> The problem is that the userspace avc doesn't currently provide this
> information, all you can get is an access decision or a labeling or
> relabeling decision. It seems a little extreme to add a
> security_compute_trans() to the userspace avc (and selinuxfs filesystem,
> etc) just to make scripts a little more isolated and provide more fine
> grained access but I can't think of another (good) way to do this. The
> alternative would be to use default types but that isn't very scalable
> for X number of interpreters times N number of users.
>
> Can anyone else think of a way to accomplish this or shall I try adding
> a calculate auto type trans to the userspace avc's?
>
Again, why can't you use security_compute_create?
>From selinux.h:
/* Compute a labeling decision and set *newcon to refer to it.
Caller must free via freecon. */
extern int security_compute_create(security_context_t scon,
security_context_t tcon,
security_class_t tclass,
security_context_t *newcon);
> Joshua Brindle
> Hardened Gentoo
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
--
James Carter <jwcart2@epoch.ncsc.mil>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 15:42 ` James Carter
@ 2004-07-20 18:14 ` Joshua Brindle
2004-07-20 20:27 ` James Carter
0 siblings, 1 reply; 14+ messages in thread
From: Joshua Brindle @ 2004-07-20 18:14 UTC (permalink / raw)
To: jwcart2; +Cc: SELinux
James Carter wrote:
>Why can't the kernel do the auto transition? Maybe I don't understand
>what you are using for your source and target contexts.
>
>If you call security_compute_create with fastcgi's context as the
>source, the script's context as the target, and using the
>SECCLASS_PROCESS class, then you will get the same result as the kernel
>when it looks for the default transition in selinux_bprm_security. So
>if you take the new context returned by security_compute_create and call
>setexec with it, you will end up with the same result that you would
>have if you had just let the kernel do the auto transition.
>
>
>
Oh good, I was hoping I was just overlooking something obvious. I
thought that security_compute_create() was just for automatic object
type transitions but now that I think about it that doesn't make much
sense to seperate those since they are the same thing in different classes.
The kernel can't do the auto transition because there is no execve()
happening when the php interpreter reads the .php file and interprets
it. The idea is to have the fastcgi wrapper running in some domain,
fcgi_wrapper_t and have it able to do a security_compute_create()
between it's own context and method_php_script_t and decide that it
should run in method_php_t and then setexeccon() to method_php_t and
execute the php interpreter for the user method. That way my scripts can
be entirely isolated from system and other users and I can't use php to
read other peoples php scripts that could contain passwords and so on.
>Again, why can't you use security_compute_create?
>
>>From selinux.h:
>/* Compute a labeling decision and set *newcon to refer to it.
> Caller must free via freecon. */
>extern int security_compute_create(security_context_t scon,
> security_context_t tcon,
> security_class_t tclass,
> security_context_t *newcon);
>
>
>
Yes, I looked at this and thought it was for file labeling decisions..
silly me ;)
Joshua Brindle
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 18:14 ` Joshua Brindle
@ 2004-07-20 20:27 ` James Carter
2004-07-20 20:32 ` Joshua Brindle
0 siblings, 1 reply; 14+ messages in thread
From: James Carter @ 2004-07-20 20:27 UTC (permalink / raw)
To: Joshua Brindle; +Cc: SELinux
Sorry, I guess I wasn't very clear.
I was trying to say that you are trying to manually do something that
the kernel can do automatically.
You don't need to do the security_create_compute() and setexeccon()
before the exec, because, on the exec, the kernel will do the same
thing. In both cases, you would have had to use the domain_auto_trans
macro, so you don't gain anything by doing it manually.
Without an exec, setexecon() won't help you.
>From selinux.h:
/* Set exec security context for the next execve.
Call with NULL if you want to reset to the default. */
extern int setexeccon(security_context_t con);
I am not an expert on Apache and php, but I am pretty sure that when you
execute the php interpreter an exec is occurring somewhere.
On Tue, 2004-07-20 at 14:14, Joshua Brindle wrote:
> James Carter wrote:
>
> >Why can't the kernel do the auto transition? Maybe I don't understand
> >what you are using for your source and target contexts.
> >
> >If you call security_compute_create with fastcgi's context as the
> >source, the script's context as the target, and using the
> >SECCLASS_PROCESS class, then you will get the same result as the kernel
> >when it looks for the default transition in selinux_bprm_security. So
> >if you take the new context returned by security_compute_create and call
> >setexec with it, you will end up with the same result that you would
> >have if you had just let the kernel do the auto transition.
> >
> >
> >
> Oh good, I was hoping I was just overlooking something obvious. I
> thought that security_compute_create() was just for automatic object
> type transitions but now that I think about it that doesn't make much
> sense to seperate those since they are the same thing in different classes.
>
> The kernel can't do the auto transition because there is no execve()
> happening when the php interpreter reads the .php file and interprets
> it. The idea is to have the fastcgi wrapper running in some domain,
> fcgi_wrapper_t and have it able to do a security_compute_create()
> between it's own context and method_php_script_t and decide that it
> should run in method_php_t and then setexeccon() to method_php_t and
> execute the php interpreter for the user method. That way my scripts can
> be entirely isolated from system and other users and I can't use php to
> read other peoples php scripts that could contain passwords and so on.
>
>
> >Again, why can't you use security_compute_create?
> >
> >>From selinux.h:
> >/* Compute a labeling decision and set *newcon to refer to it.
> > Caller must free via freecon. */
> >extern int security_compute_create(security_context_t scon,
> > security_context_t tcon,
> > security_class_t tclass,
> > security_context_t *newcon);
> >
> >
> >
> Yes, I looked at this and thought it was for file labeling decisions..
> silly me ;)
>
> Joshua Brindle
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
--
James Carter <jwcart2@epoch.ncsc.mil>
National Security Agency
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 20:27 ` James Carter
@ 2004-07-20 20:32 ` Joshua Brindle
2004-07-20 23:22 ` Luke Kenneth Casson Leighton
2004-07-21 23:06 ` Thomas Bleher
0 siblings, 2 replies; 14+ messages in thread
From: Joshua Brindle @ 2004-07-20 20:32 UTC (permalink / raw)
To: jwcart2; +Cc: SELinux
James Carter wrote:
>Sorry, I guess I wasn't very clear.
>
>I was trying to say that you are trying to manually do something that
>the kernel can do automatically.
>
>You don't need to do the security_create_compute() and setexeccon()
>before the exec, because, on the exec, the kernel will do the same
>thing. In both cases, you would have had to use the domain_auto_trans
>macro, so you don't gain anything by doing it manually.
>
>Without an exec, setexecon() won't help you.
>>From selinux.h:
>/* Set exec security context for the next execve.
> Call with NULL if you want to reset to the default. */
>extern int setexeccon(security_context_t con);
>
>I am not an expert on Apache and php, but I am pretty sure that when you
>execute the php interpreter an exec is occurring somewhere.
>
>
>
Right, an exec is happening from httpd_t to php_exec_t currently, and
this will give back php_exec_t. Thats the standard way php is done in
SELinux at the moment and exactly what I'm trying to make better.
Now, the new idea is to have fastcgi wrapper which already does setuid()
and setgid() based on the ownership of the target php script (this is a
script! it is not executed by execve()) and then executes php (which is
php_exec_t) resulting in php_t again. What I want it to do is also read
the context of the target script and calculate the autotrans that would
happen if php was going to execute the script directly and then do
setexeccon() to do it manually.
You are exactly right in that I'm trying to do something manually but
afaik the kernel can't do this automatically because it's just the php
binary reading in a script and interpreting it, no execve() happens
after the php interpreter is loaded and therefore no per-user php
domains can currently happen.
Joshua Brindle
>On Tue, 2004-07-20 at 14:14, Joshua Brindle wrote:
>
>
>>James Carter wrote:
>>
>>
>>
>>>Why can't the kernel do the auto transition? Maybe I don't understand
>>>what you are using for your source and target contexts.
>>>
>>>If you call security_compute_create with fastcgi's context as the
>>>source, the script's context as the target, and using the
>>>SECCLASS_PROCESS class, then you will get the same result as the kernel
>>>when it looks for the default transition in selinux_bprm_security. So
>>>if you take the new context returned by security_compute_create and call
>>>setexec with it, you will end up with the same result that you would
>>>have if you had just let the kernel do the auto transition.
>>>
>>>
>>>
>>>
>>>
>>Oh good, I was hoping I was just overlooking something obvious. I
>>thought that security_compute_create() was just for automatic object
>>type transitions but now that I think about it that doesn't make much
>>sense to seperate those since they are the same thing in different classes.
>>
>>The kernel can't do the auto transition because there is no execve()
>>happening when the php interpreter reads the .php file and interprets
>>it. The idea is to have the fastcgi wrapper running in some domain,
>>fcgi_wrapper_t and have it able to do a security_compute_create()
>>between it's own context and method_php_script_t and decide that it
>>should run in method_php_t and then setexeccon() to method_php_t and
>>execute the php interpreter for the user method. That way my scripts can
>>be entirely isolated from system and other users and I can't use php to
>>read other peoples php scripts that could contain passwords and so on.
>>
>>
>>
>>
>>>Again, why can't you use security_compute_create?
>>>
>>>>From selinux.h:
>>>/* Compute a labeling decision and set *newcon to refer to it.
>>> Caller must free via freecon. */
>>>extern int security_compute_create(security_context_t scon,
>>> security_context_t tcon,
>>> security_class_t tclass,
>>> security_context_t *newcon);
>>>
>>>
>>>
>>>
>>>
>>Yes, I looked at this and thought it was for file labeling decisions..
>>silly me ;)
>>
>>Joshua Brindle
>>
>>--
>>This message was distributed to subscribers of the selinux mailing list.
>>If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
>>the words "unsubscribe selinux" without quotes as the message.
>>
>>
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 20:32 ` Joshua Brindle
@ 2004-07-20 23:22 ` Luke Kenneth Casson Leighton
2004-07-21 0:59 ` Joshua Brindle
2004-07-21 23:06 ` Thomas Bleher
1 sibling, 1 reply; 14+ messages in thread
From: Luke Kenneth Casson Leighton @ 2004-07-20 23:22 UTC (permalink / raw)
To: Joshua Brindle; +Cc: jwcart2, SELinux
On Tue, Jul 20, 2004 at 04:32:11PM -0400, Joshua Brindle wrote:
> James Carter wrote:
>
> >Sorry, I guess I wasn't very clear.
> >
> >I was trying to say that you are trying to manually do something that
> >the kernel can do automatically.
> >
> >You don't need to do the security_create_compute() and setexeccon()
> >before the exec, because, on the exec, the kernel will do the same
> >thing. In both cases, you would have had to use the domain_auto_trans
> >macro, so you don't gain anything by doing it manually.
> >
> >Without an exec, setexecon() won't help you.
> >>From selinux.h:
> >/* Set exec security context for the next execve.
> > Call with NULL if you want to reset to the default. */
> >extern int setexeccon(security_context_t con);
> >
> >I am not an expert on Apache and php, but I am pretty sure that when you
> >execute the php interpreter an exec is occurring somewhere.
> >
> >
> >
> Right, an exec is happening from httpd_t to php_exec_t currently, and
> this will give back php_exec_t. Thats the standard way php is done in
> SELinux at the moment and exactly what I'm trying to make better.
>
> Now, the new idea is to have fastcgi wrapper which already does setuid()
> and setgid() based on the ownership of the target php script (this is a
> script! it is not executed by execve()) and then executes php (which is
> php_exec_t) resulting in php_t again. What I want it to do is also read
> the context of the target script and calculate the autotrans that would
> happen if php was going to execute the script directly and then do
> setexeccon() to do it manually.
>
> You are exactly right in that I'm trying to do something manually but
> afaik the kernel can't do this automatically because it's just the php
> binary reading in a script and interpreting it, no execve() happens
> after the php interpreter is loaded and therefore no per-user php
> domains can currently happen.
so, you want to emulate [activate] the effect of domain_auto_trans without
_actually_ doing an execve.
but also because you are not actually doing an execve, you also wish
to RETURN to the context from which the domain_auto_trans was made.
in other words, if i am interpreting this correctly [please someone
make sure i have this right] you wish to do what a seteuid does,
namely to temporarily go to an alternative-privileged context and
then return to the previous context.
and as we know, seteuid was discussed and then explicitly stomped on
from a great height (tm).
the recommended approach to get round this was, sadly-in-this-case
(given the name fastcgi), to do the execve and be done with it.
... alternatively, might we see the rebirth of that cgi "helper" daemon
that i am aware cropped up at one point in apache?
like i said, my experience with SE/Linux being limited to a few months,
if i have the wrong end of the stick, here, please some correct me.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 23:22 ` Luke Kenneth Casson Leighton
@ 2004-07-21 0:59 ` Joshua Brindle
0 siblings, 0 replies; 14+ messages in thread
From: Joshua Brindle @ 2004-07-21 0:59 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton; +Cc: jwcart2, SELinux
Luke Kenneth Casson Leighton wrote:
>On Tue, Jul 20, 2004 at 04:32:11PM -0400, Joshua Brindle wrote:
>
>
>>James Carter wrote:
>>
>>
>>
>>>Sorry, I guess I wasn't very clear.
>>>
>>>I was trying to say that you are trying to manually do something that
>>>the kernel can do automatically.
>>>
>>>You don't need to do the security_create_compute() and setexeccon()
>>>before the exec, because, on the exec, the kernel will do the same
>>>thing. In both cases, you would have had to use the domain_auto_trans
>>>macro, so you don't gain anything by doing it manually.
>>>
>>>Without an exec, setexecon() won't help you.
>>>>From selinux.h:
>>>/* Set exec security context for the next execve.
>>> Call with NULL if you want to reset to the default. */
>>>extern int setexeccon(security_context_t con);
>>>
>>>I am not an expert on Apache and php, but I am pretty sure that when you
>>>execute the php interpreter an exec is occurring somewhere.
>>>
>>>
>>>
>>>
>>>
>>Right, an exec is happening from httpd_t to php_exec_t currently, and
>>this will give back php_exec_t. Thats the standard way php is done in
>>SELinux at the moment and exactly what I'm trying to make better.
>>
>>Now, the new idea is to have fastcgi wrapper which already does setuid()
>>and setgid() based on the ownership of the target php script (this is a
>>script! it is not executed by execve()) and then executes php (which is
>>php_exec_t) resulting in php_t again. What I want it to do is also read
>>the context of the target script and calculate the autotrans that would
>>happen if php was going to execute the script directly and then do
>>setexeccon() to do it manually.
>>
>>You are exactly right in that I'm trying to do something manually but
>>afaik the kernel can't do this automatically because it's just the php
>>binary reading in a script and interpreting it, no execve() happens
>>after the php interpreter is loaded and therefore no per-user php
>>domains can currently happen.
>>
>>
>
> so, you want to emulate [activate] the effect of domain_auto_trans without
> _actually_ doing an execve.
>
>
>
right
> but also because you are not actually doing an execve, you also wish
> to RETURN to the context from which the domain_auto_trans was made.
>
> in other words, if i am interpreting this correctly [please someone
> make sure i have this right] you wish to do what a seteuid does,
> namely to temporarily go to an alternative-privileged context and
> then return to the previous context.
>
> and as we know, seteuid was discussed and then explicitly stomped on
> from a great height (tm).
>
>
>
not the same thing. Doing seteuid() _during_ some application and being
able to change the context at that point is unsafe and therefore should
never be implemented. That is _not_ what I'm trying to do.
> the recommended approach to get round this was, sadly-in-this-case
> (given the name fastcgi), to do the execve and be done with it.
>
>
>
not getting around it, using fastcgi to augment the process (running a
straight php cgi with lots of users is a huge drag on resources anyway)
and this can also be of benefit to any kind of interpreted scripts where
the interpreter runs as a cgi in apache.
> ... alternatively, might we see the rebirth of that cgi "helper" daemon
> that i am aware cropped up at one point in apache?
>
>
>
It might work the same way but I'm happy with the was fastcgi is
working, since it will spawn a php process for each person the end
result should be somehting like several php's running in different
contexts, like
fred_php_t
method_php_t
sys_php_t
and so on
> like i said, my experience with SE/Linux being limited to a few months,
> if i have the wrong end of the stick, here, please some correct me.
>
> l.
>
>
Again, I think we may be having some misunderstanding, caused by my
unawareness of security_compute_create giving the info I need. To
illustrate this I want the following (and think I almost have it now
that I know about security_compute_create().
apache running in httpd_t
fastcgi is an apache module therefore it's also in httpd_t
apache gets a request for ~method/foo.php
fastcgi spawns the wrapper (running in fcgi_wrapper_t) which looks for
the file in question
fastcgi wrapper sees /home/method/public_html/foo.php is owned by
method:method and context is method_php_script_t
fastcgi wrapper seteuid/setegid to method:method and computes the
transition from fastcgi_wrapper_t to method_php_script_t (which can
never happen!)
fastcgi wrapper gets the answer back, method_php_t
fastcgi wrapper does setexeccon(method_php_t) and runs php
now there is a persistant php running in method_php_t ready to 'run'
~method/foo.php
in this way we have completely isolated user domains for any interpreted
scripts running from apache! :D
Joshua Brindle
Hardened Gentoo
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-20 20:32 ` Joshua Brindle
2004-07-20 23:22 ` Luke Kenneth Casson Leighton
@ 2004-07-21 23:06 ` Thomas Bleher
2004-07-22 8:56 ` Luke Kenneth Casson Leighton
1 sibling, 1 reply; 14+ messages in thread
From: Thomas Bleher @ 2004-07-21 23:06 UTC (permalink / raw)
To: SELinux
[-- Attachment #1: Type: text/plain, Size: 2420 bytes --]
* Joshua Brindle <method@gentoo.org> [2004-07-20 23:57]:
> James Carter wrote:
> >I was trying to say that you are trying to manually do something that
> >the kernel can do automatically.
> >
> >You don't need to do the security_create_compute() and setexeccon()
> >before the exec, because, on the exec, the kernel will do the same
> >thing. In both cases, you would have had to use the domain_auto_trans
> >macro, so you don't gain anything by doing it manually.
> >
> >Without an exec, setexecon() won't help you.
> >>From selinux.h:
> >/* Set exec security context for the next execve.
> > Call with NULL if you want to reset to the default. */
> >extern int setexeccon(security_context_t con);
> >
> >I am not an expert on Apache and php, but I am pretty sure that when you
> >execute the php interpreter an exec is occurring somewhere.
> >
> Right, an exec is happening from httpd_t to php_exec_t currently, and
> this will give back php_exec_t. Thats the standard way php is done in
> SELinux at the moment and exactly what I'm trying to make better.
>
> Now, the new idea is to have fastcgi wrapper which already does setuid()
> and setgid() based on the ownership of the target php script (this is a
> script! it is not executed by execve()) and then executes php (which is
> php_exec_t) resulting in php_t again. What I want it to do is also read
> the context of the target script and calculate the autotrans that would
> happen if php was going to execute the script directly and then do
> setexeccon() to do it manually.
How does cron handle this? I think that cron is in a similar situation
since it can't exec the users crontab. From macros/program/crond_macros.te:
# Permit a transition from the crond_t domain to this domain.
# The transition is requested explicitly by the modified crond
# via execve_secure. There is no way to set up an automatic
# transition, since crontabs are configuration files, not executables.
domain_trans(crond_t, shell_exec_t, $1_crond_t)
Additionaly, crond has this:
# Set exec context.
can_setexec(crond_t)
Maybe someone who knows the cron code better than me can explain what
exactly cron is doing and if this can be applied to the fastcgi code as
well.
Thomas
--
http://www.cip.ifi.lmu.de/~bleher/selinux/ - my SELinux pages
GPG-Fingerprint: BC4F BB16 30D6 F253 E3EA D09E C562 2BAE B2F4 ABE7
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-21 23:06 ` Thomas Bleher
@ 2004-07-22 8:56 ` Luke Kenneth Casson Leighton
2004-07-22 13:19 ` Daniel J Walsh
2004-07-22 14:35 ` Luke Kenneth Casson Leighton
0 siblings, 2 replies; 14+ messages in thread
From: Luke Kenneth Casson Leighton @ 2004-07-22 8:56 UTC (permalink / raw)
To: SELinux
On Thu, Jul 22, 2004 at 01:06:06AM +0200, Thomas Bleher wrote:
> How does cron handle this? I think that cron is in a similar situation
> since it can't exec the users crontab. From macros/program/crond_macros.te:
>
> # Permit a transition from the crond_t domain to this domain.
> # The transition is requested explicitly by the modified crond
> # via execve_secure. There is no way to set up an automatic
> # transition, since crontabs are configuration files, not executables.
> domain_trans(crond_t, shell_exec_t, $1_crond_t)
>
> Additionaly, crond has this:
> # Set exec context.
> can_setexec(crond_t)
>
> Maybe someone who knows the cron code better than me can explain what
> exactly cron is doing and if this can be applied to the fastcgi code as
> well.
this patch fragment is out-of-date, dan walsh has done some updates
since:
--- database.c.old 2004-05-19 10:03:06.000000000 +0100
+++ database.c 2004-05-20 15:15:55.000000000 +0100
@@ -30,6 +30,11 @@
#include <sys/stat.h>
#include <sys/file.h>
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#endif
#define TMAX(a,b) ((a)>(b)?(a):(b))
@@ -46,7 +51,7 @@
#endif /* ifndef PATH_MAX */
-static void process_crontab __P((char *, char *, char *,
+static void process_crontab __P((char *, char *, char *,
struct stat *,
cron_db *, cron_db *));
#ifdef DEBIAN
@@ -167,7 +172,7 @@
new_db.head = new_db.tail = NULL;
if (syscron_stat.st_mtime) {
- process_crontab("root", "*system*",
+ process_crontab(SYSUSERNAME, "*system*",
SYSCRONTAB, &syscron_stat,
&new_db, old_db);
}
@@ -205,7 +210,7 @@
/* statbuf is used as working storage by process_crontab() --
current contents are irrelevant */
- process_crontab("root", fname, tabname,
+ process_crontab(SYSUSERNAME, fname, tabname,
&statbuf, &new_db, old_db);
}
@@ -324,6 +329,13 @@
int crontab_fd = OK - 1;
user *u;
+#ifdef WITH_SELINUX
+ security_context_t file_context=NULL;
+ security_context_t user_context=NULL;
+ struct av_decision avd;
+ int retval=0, selinux_enabled = (is_selinux_enabled() > 0);
+#endif
+
#ifdef DEBIAN
/* If the name begins with *system*, don't worry about password -
it's part of the system crontab */
@@ -349,6 +361,14 @@
goto next_crontab;
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ log_it(fname, getpid(), "getfilecon FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
if (fstat(crontab_fd, statbuf) < OK) {
log_it(fname, getpid(), "FSTAT FAILED", tabname);
goto next_crontab;
@@ -385,6 +405,14 @@
goto next_crontab;
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ log_it(fname, getpid(), "getfilecon FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
if (fstat(crontab_fd, statbuf) < OK) {
log_it(fname, getpid(), "FSTAT FAILED", tabname);
goto next_crontab;
@@ -425,6 +453,31 @@
free_user(u);
log_it(fname, getpid(), "RELOAD", tabname);
}
+#ifdef WITH_SELINUX
+ if (selinux_enabled) {
+ /*
+ * Since crontab files are not directly executed,
+ * crond must ensure that the crontab file has
+ * a context that is appropriate for the context of
+ * the user cron job. It performs an entrypoint
+ * permission check for this purpose.
+ */
+ if (get_default_context(uname, NULL, &user_context)) {
+ log_it(uname, getpid(), "NO CONTEXT", tabname);
+ goto next_crontab;
+ }
+ retval = security_compute_av(user_context, file_context,
+ SECCLASS_FILE, FILE__ENTRYPOINT, &avd);
+ freecon(user_context);
+ freecon(file_context);
+ file_context = NULL;
+
+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) {
+ log_it(fname, getpid(), "ENTRYPOINT FAILED", tabname);
+ goto next_crontab;
+ }
+ }
+#endif
u = load_user(crontab_fd, pw, fname);
if (u != NULL) {
u->mtime = statbuf->st_mtime;
@@ -436,6 +489,12 @@
Debug(DLOAD, (" [done]\n"))
close(crontab_fd);
}
+#ifdef WITH_SELINUX
+ if(file_context) {
+ freecon(file_context);
+ file_context = NULL;
+ }
+#endif
}
#ifdef DEBIAN
which i believe to be testing the access permissions on the crontab
file, and in child_process() which is called by do_command() which
is called by job_queue():
#ifdef WITH_SELINUX
if (is_selinux_enabled()) {
security_context_t scontext;
if (get_default_context(u->name, NULL, &scontext)) {
fprintf(stderr, "execle_secure: couldn't get security context for user %s\n", u->name);
_exit(ERROR_EXIT);
}
if (setexeccon(scontext) < 0) {
fprintf(stderr, "Could not set exec context to %s for user %s\n", scontext,u->name);
_exit(ERROR_EXIT);
}
freecon(scontext);
}
#endif
execle(shell, shell, "-c", e->cmd, (char *)0, jobenv);
fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
perror("execl");
_exit(ERROR_EXIT);
}
which ensures that the command is run under the correct user context (u->name).
dan, steven, russell and the deb maintainer steve greene had a bash at
going over this because the deb maintainer would not accept the patch:
the reason it turned out was because of bugs in the patch _and_ in
cron over how to deal with running cron jobs as non-user (i.e. as
the cron system, and the fake and deliberately nonexistent username
*system* was used to "represent" the cron system such that if a
getpwnam was called with "*system*" it would always fail).
of course, cron _does_ have the concept of system, called system_u :)
anyway, as you can see, the shell command is exec'd, there's also
a cron_popen() but i haven't tracked down how it's called.
if fastcgi does an exec?e to run the cgi script, cron's code would,
i believe, be a useful starting point.
l.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-22 8:56 ` Luke Kenneth Casson Leighton
@ 2004-07-22 13:19 ` Daniel J Walsh
2004-07-22 14:35 ` Luke Kenneth Casson Leighton
1 sibling, 0 replies; 14+ messages in thread
From: Daniel J Walsh @ 2004-07-22 13:19 UTC (permalink / raw)
To: Luke Kenneth Casson Leighton; +Cc: SELinux
[-- Attachment #1: Type: text/plain, Size: 19 bytes --]
Latest cron patch.
[-- Attachment #2: vixie-cron-selinux.patch --]
[-- Type: text/x-patch, Size: 5835 bytes --]
--- vixie-cron-3.0.1/Makefile.selinux 2004-06-25 12:31:30.000000000 -0400
+++ vixie-cron-3.0.1/Makefile 2004-06-25 12:31:30.000000000 -0400
@@ -55,7 +55,7 @@
INCLUDE = -I.
#INCLUDE =
#<<need getopt()>>
-LIBS =
+LIBS = -lselinux
#<<optimize or debug?>>
OPTIM = $(RPM_OPT_FLAGS)
#OPTIM = -g
@@ -71,7 +71,7 @@
#<<want to use a nonstandard CC?>>
#CC = vcc
#<<manifest defines>>
-DEFS = -s
+DEFS = -s -DWITH_SELINUX
#(SGI IRIX systems need this)
#DEFS = -D_BSD_SIGNALS -Dconst=
#<<the name of the BSD-like install program>>
--- vixie-cron-3.0.1/user.c.selinux 1995-05-31 17:37:22.000000000 -0400
+++ vixie-cron-3.0.1/user.c 2004-06-25 12:33:43.000000000 -0400
@@ -23,9 +23,73 @@
*/
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
+#endif
+
#include "cron.h"
+#ifdef WITH_SELINUX
+static int get_security_context(char *name,
+ int crontab_fd,
+ security_context_t *rcontext,
+ char *tabname) {
+ security_context_t scontext;
+ security_context_t file_context=NULL;
+ struct av_decision avd;
+ int retval=0;
+ *rcontext = NULL;
+ if (get_default_context(name, NULL, &scontext)) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "No SELinux security context",tabname);
+ return -1;
+ } else {
+ log_it(name, getpid(), "No security context but SELinux in permissive mode, continuing",tabname);
+ }
+ }
+
+ if (fgetfilecon(crontab_fd, &file_context) < OK) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "getfilecon FAILED", tabname);
+ freecon(scontext);
+ return -1;
+ } else {
+ log_it(name, getpid(), "getfilecon FAILED but SELinux in permissive mode, continuing", tabname);
+ *rcontext=scontext;
+ return 0;
+ }
+ }
+
+ /*
+ * Since crontab files are not directly executed,
+ * crond must ensure that the crontab file has
+ * a context that is appropriate for the context of
+ * the user cron job. It performs an entrypoint
+ * permission check for this purpose.
+ */
+ retval = security_compute_av(scontext,
+ file_context,
+ SECCLASS_FILE,
+ FILE__ENTRYPOINT,
+ &avd);
+ freecon(file_context);
+ if (retval || ((FILE__ENTRYPOINT & avd.allowed) != FILE__ENTRYPOINT)) {
+ if (security_getenforce() > 0) {
+ log_it(name, getpid(), "ENTRYPOINT FAILED", tabname);
+ freecon(scontext);
+ return -1;
+ } else {
+ log_it(name, getpid(), "ENTRYPOINT FAILED but SELinux in permissive mode, continuing", tabname);
+ }
+ }
+ *rcontext=scontext;
+ return 0;
+}
+#endif
+
void
free_user(u)
user *u;
@@ -37,15 +101,20 @@
ne = e->next;
free_entry(e);
}
+#ifdef WITH_SELINUX
+ freecon(u->scontext);
+#endif
free(u);
}
user *
-load_user(crontab_fd, pw, name)
+load_user(crontab_fd, pw, uname, fname, tabname)
int crontab_fd;
struct passwd *pw; /* NULL implies syscrontab */
- char *name;
+ char *uname;
+ char *fname;
+ char *tabname;
{
char envstr[MAX_ENVSTR];
FILE *file;
@@ -64,7 +133,7 @@
/* file is open. build user entry, then read the crontab file.
*/
u = (user *) malloc(sizeof(user));
- u->name = strdup(name);
+ u->name = strdup(fname);
u->crontab = NULL;
/*
@@ -72,6 +141,22 @@
*/
envp = env_init();
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled() > 0) {
+ char *sname=uname;
+ if (pw==NULL) {
+ sname="system_u";
+ }
+
+ if (get_security_context(sname, crontab_fd,
+ &u->scontext, tabname) != 0) {
+ free_user(u);
+ u = NULL;
+ goto done;
+ }
+ }
+#endif
+
/*
* load the crontab
*/
--- vixie-cron-3.0.1/database.c.selinux 2004-06-25 12:31:30.000000000 -0400
+++ vixie-cron-3.0.1/database.c 2004-06-25 12:31:30.000000000 -0400
@@ -297,7 +297,7 @@
free_user(u);
log_it(fname, getpid(), "RELOAD", tabname);
}
- u = load_user(crontab_fd, pw, fname);
+ u = load_user(crontab_fd, pw, uname, fname, tabname);
if (u != NULL) {
u->mtime = statbuf->st_mtime;
link_user(new_db, u);
--- vixie-cron-3.0.1/cron.h.selinux 2004-06-25 12:31:30.000000000 -0400
+++ vixie-cron-3.0.1/cron.h 2004-06-25 12:31:30.000000000 -0400
@@ -39,7 +39,9 @@
#include "pathnames.h"
#include "config.h"
#include "externs.h"
-
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
/* these are really immutable, and are
* defined for symbolic convenience only
* TRUE, FALSE, and ERR must be distinct
@@ -174,6 +176,9 @@
char *name;
time_t mtime; /* last modtime of crontab */
entry *crontab; /* this person's crontab */
+#ifdef WITH_SELINUX
+ security_context_t scontext; /* SELinux security context */
+#endif
} user;
typedef struct _cron_db {
@@ -219,7 +224,7 @@
**env_copy __P((char **)),
**env_set __P((char **, char *));
-user *load_user __P((int, struct passwd *, char *)),
+user *load_user __P((int, struct passwd *, char *, char *, char *)),
*find_user __P((cron_db *, char *));
entry *load_entry __P((FILE *, void (*)(),
--- vixie-cron-3.0.1/do_command.c.selinux 2004-06-25 12:31:30.000000000 -0400
+++ vixie-cron-3.0.1/do_command.c 2004-06-25 12:31:30.000000000 -0400
@@ -29,6 +29,9 @@
# include <syslog.h>
#endif
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
static void child_process __P((entry *, user *)),
do_univ __P((user *));
@@ -251,6 +254,18 @@
*/
(void) signal(SIGCHLD, SIG_DFL);
#endif
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled() >0 ) {
+ if (setexeccon(u->scontext) < 0) {
+ if (security_getenforce() > 0) {
+ fprintf(stderr,
+ "Could not set exec context to %s for user %s\n",
+ u->scontext,u->name);
+ _exit(ERROR_EXIT);
+ }
+ }
+ }
+#endif
execle(shell, shell, "-c", e->cmd, (char *)0, e->envp);
fprintf(stderr, "execl: couldn't exec `%s'\n", shell);
perror("execl");
^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: running interpreted scripts in different domains
2004-07-22 8:56 ` Luke Kenneth Casson Leighton
2004-07-22 13:19 ` Daniel J Walsh
@ 2004-07-22 14:35 ` Luke Kenneth Casson Leighton
1 sibling, 0 replies; 14+ messages in thread
From: Luke Kenneth Casson Leighton @ 2004-07-22 14:35 UTC (permalink / raw)
To: SELinux
On Thu, Jul 22, 2004 at 09:56:51AM +0100, Luke Kenneth Casson Leighton wrote:
> *system* was used to "represent" the cron system such that if a
> getpwnam was called with "*system*" it would always fail).
>
> of course, cron _does_ have the concept of system, called system_u :)
duh, i meant selinux does have the concept of system, called system_u.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2004-07-22 14:24 UTC | newest]
Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-07-18 20:33 running interpreted scripts in different domains Joshua Brindle
2004-07-19 8:28 ` Luke Kenneth Casson Leighton
2004-07-19 11:56 ` Russell Coker
2004-07-19 12:01 ` Joshua Brindle
2004-07-20 15:42 ` James Carter
2004-07-20 18:14 ` Joshua Brindle
2004-07-20 20:27 ` James Carter
2004-07-20 20:32 ` Joshua Brindle
2004-07-20 23:22 ` Luke Kenneth Casson Leighton
2004-07-21 0:59 ` Joshua Brindle
2004-07-21 23:06 ` Thomas Bleher
2004-07-22 8:56 ` Luke Kenneth Casson Leighton
2004-07-22 13:19 ` Daniel J Walsh
2004-07-22 14:35 ` Luke Kenneth Casson Leighton
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.