Hello there,
I just wondered, whether the security mechanisms implemented in SELinux would be able to protect the system from the exploit (not the occurrence) of Buffer Overflows.
Let's assume, the security mechanism and the kernel are sane & safe. An application runs in "underpriviledged" mode, that is the policy permits the application to read file A and read & write to file B. Now, if the application tries to go berserk, the policy control mechanism will take it out and shoot it. But if somehow a buffer within the application gets an overflow, will it be able to acces memory areas, that belong to other applications?
Thank you,
JanP
-- You have received this message because you are subscribed to the selinux 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.From: Jesse Pollard <pollard_at_tomcat.admin.navo.hpc.mil>
>
> Hello there,
>
> I just wondered, whether the security mechanisms implemented in SELinux
> would be able to protect the system from the exploit (not the occurrence)
> of Buffer Overflows.
Simple answer: No.
> Let's assume, the security mechanism and the kernel are sane & safe. An
> application runs in "underpriviledged" mode, that is the policy permits
> the application to read file A and read & write to file B. Now, if the
> application tries to go berserk, the policy control mechanism will take it
> out and shoot it. But if somehow a buffer within the application gets an
> overflow, will it be able to acces memory areas, that belong to other
> applications?
The buffer overlow will only access current process memory. If that process can attach to other memory (via /proc or /dev/kmem) then anything goes.
The problem is significant, but no solution currently exists.
Depends on hardware support -
IF the hardware allows read/write access to memory and denies execute access to read/write memory (instruction space is execute only) THEN and only then can buffer overflows be properly limited.
You still have the problem of causing an "exec" to another program. But that is (partially) a different problem. This can be addressed.
If an executable image on disk is not permitted to "fork/exec/..." then it can be prevented. That is one of the advantages to static linking over using shared libraries. The static link will only have the system calls included that it requires. If the program doesn't use fork/exec system call, then it would not be included.
If this is combined with hardware protection above, then the exec system call could not be invoked.
Invoking the system call currently can be done by loading the system call invokation on the stack, with parameters and the pointer to the stack area containing this executable code (replacing the return address of the caller; then allowing the current function to complete.
If the stack cannot be exected it fails.
If the return address on the stack points to an exec function, then the exec will be executed, using the other parameters on the stack (loaded via the overflow).
If the exec function doesn't exist in the text image then it fails.
If the privileges of the process doesn't include exec, then it would also fail, even if the exec system call were included.
This combined with the non-executable rw memory (stack and data) then a reasonable amount can be done to shield against buffer overflows.
Unfortuanately, protection of rw memory is not available on Intel.
Other patforms may vary.
You also have the problem with the GNU C compiler generating "trampoline" functions on the stack to implement function nesting. C++ requires these or their equivalent.
Any opinions expressed are solely my own.
-- You have received this message because you are subscribed to the selinux 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.From: Jan Petranek <jan.petranek_at_student.uni-tuebingen.de>
On Fri, 18 May 2001, Jesse Pollard wrote:
> Date: Fri, 18 May 2001 12:04:46 -0500 (CDT)
> From: Jesse Pollard <pollard@tomcat.admin.navo.hpc.mil>
> To: "bcarver2@austin.ibm.com NSA Selinux Mailinglist"
> <selinux@tycho.nsa.gov>
> Subject: Re: Immunity against Buffer Overflows / exploits
>
> --------- Received message begins Here ---------
>
> >
> > Hello there,
> >
> > I just wondered, whether the security mechanisms implemented in SELinux
> > would be able to protect the system from the exploit (not the occurrence)
> > of Buffer Overflows.
>
> Simple answer: No.
>
> > Let's assume, the security mechanism and the kernel are sane & safe. An
> > application runs in "underpriviledged" mode, that is the policy permits
> > the application to read file A and read & write to file B. Now, if the
> > application tries to go berserk, the policy control mechanism will take it
> > out and shoot it. But if somehow a buffer within the application gets an
> > overflow, will it be able to acces memory areas, that belong to other
> > applications?
>
> The buffer overlow will only access current process memory. If that
> process can attach to other memory (via /proc or /dev/kmem) then
> anything goes.
I'm not sure, if I fully got that. So, basically, the application has only it's _own_ memory for data and it's own instruction stack, is that correct? And, as long as the policy is intact, whatever will happen in this overwritten buffer will not be able to do anything that the application was not allowed to. Of course, if the application was allowed to mess with memory directly, we will be in deep trouble. But even standard linux should be able to keep userprocesses from doing so. (I tried on this machine to mess with /proc and /dev/kmem as a user, no way. Admittedly, I did it in a very dilletant way with cat /dev/kmem )
> The problem is significant, but no solution currently exists.
>
> Depends on hardware support -
> IF the hardware allows read/write access to memory and denies
> execute access to read/write memory (instruction space is execute
> only) THEN and only then can buffer overflows be properly limited.
>
> You still have the problem of causing an "exec" to another program. But
> that is (partially) a different problem. This can be addressed.
>
> If an executable image on disk is not permitted to "fork/exec/..." then
> it can be prevented. That is one of the advantages to static linking
> over using shared libraries. The static link will only have the system
> calls included that it requires. If the program doesn't use fork/exec
> system call, then it would not be included.
>
> If this is combined with hardware protection above, then the exec system
> call could not be invoked.
>
> Invoking the system call currently can be done by loading the system call
> invokation on the stack, with parameters and the pointer to the stack area
> containing this executable code (replacing the return address of the caller;
> then allowing the current function to complete.
>
> If the stack cannot be exected it fails.
>
> If the return address on the stack points to an exec function, then the
> exec will be executed, using the other parameters on the stack (loaded via
> the overflow).
>
> If the exec function doesn't exist in the text image then it fails.
>
> If the privileges of the process doesn't include exec, then it would
> also fail, even if the exec system call were included.
>
> This combined with the non-executable rw memory (stack and data) then
> a reasonable amount can be done to shield against buffer overflows.
>
> Unfortuanately, protection of rw memory is not available on Intel.
> A: If you can read it, it is executable.
> B: If you can write it; you can read it. (see A)
>
> Other patforms may vary.
So I see, the question is now, to which extend security can be done in software and where do we have to fondle with hardware.
Thanks you,
JanP
-- You have received this message because you are subscribed to the selinux 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.From: edm_at_tycho.ncsc.mil
Actually, selinux provides a very effective defense against the exploitation of buffer overflows. Here's why:
A typical use of the buffer overflow attack is for the attacker to execute a shell or some other program (such as a compiler as the internet virus did.) Under selinux, only certain domains are allowed to execute a shell or another program for that matter. If the policy does not allow the domain that the program is executing in to exec a shell or another process (or fork for that matter), a policy violation occurs and the attack is stopped. In addition, even if the process can execute another program only programs that have the proper type allowed by the policy can be executed within a particular domain.
These restrictions apply to "privileged" (or root) processes as well. Root under selinux is not like root under linux, it's restricted. All system processes are each setup to execute in their own domain. These domains have only the privileges that are necessary for its process to execute. For example, if fingerd is attacked using buffer overflow, the policy will prevent it from executing another program. In addition, even if that attacker is able to inject extensive code into the process space, that code will only be able to access those objects that the policy restricts the fingerd's domain to.
However, if the policy allows for that domain type to access /dev/mem (or any file that allows access to system memory) then the system can be attack. It is important to note, however, that the policy has to allow for a given domain type to access this and any domain that needs this type of access needs review. -->Under selinux only programs that execute in the klogd and the xserver domains have this access.<--
gene
>> > Hello there,
>> >
>> > I just wondered, whether the security mechanisms implemented in SELinux
>> > would be able to protect the system from the exploit (not the
occurrence)
>> > of Buffer Overflows.
>>
>> Simple answer: No.
>>
>> > Let's assume, the security mechanism and the kernel are sane & safe. An
>> > application runs in "underpriviledged" mode, that is the policy permits
>> > the application to read file A and read & write to file B. Now, if the
>> > application tries to go berserk, the policy control mechanism will take
it
>> > out and shoot it. But if somehow a buffer within the application gets
an
>> > overflow, will it be able to acces memory areas, that belong to other
>> > applications?
>>
>> The buffer overlow will only access current process memory. If that
>> process can attach to other memory (via /proc or /dev/kmem) then
>> anything goes.
>
>I'm not sure, if I fully got that. So, basically, the application
>has only it's _own_ memory for data and it's own instruction stack, is
>that correct? And, as long as the policy is intact, whatever will happen
>in this overwritten buffer will not be able to do anything that the
>application was not allowed to. Of course, if the application was allowed
>to mess with memory directly, we will be in deep trouble. But even
>standard linux should be able to keep userprocesses from doing so.
>(I tried on this machine to mess with /proc and /dev/kmem as a user, no
>way. Admittedly, I did it in a very dilletant way with cat /dev/kmem )
>
>> The problem is significant, but no solution currently exists.
>>
>> Depends on hardware support -
>> IF the hardware allows read/write access to memory and denies
>> execute access to read/write memory (instruction space is execute
>> only) THEN and only then can buffer overflows be properly
limited.
>>
>> You still have the problem of causing an "exec" to another program. But
>> that is (partially) a different problem. This can be addressed.
>>
>> If an executable image on disk is not permitted to "fork/exec/..." then
>> it can be prevented. That is one of the advantages to static linking
>> over using shared libraries. The static link will only have the system
>> calls included that it requires. If the program doesn't use fork/exec
>> system call, then it would not be included.
>>
>> If this is combined with hardware protection above, then the exec system
>> call could not be invoked.
>>
>> Invoking the system call currently can be done by loading the system call
>> invokation on the stack, with parameters and the pointer to the stack
area
>> containing this executable code (replacing the return address of the
caller;
>> then allowing the current function to complete.
>>
>> If the stack cannot be exected it fails.
>>
>> If the return address on the stack points to an exec function, then the
>> exec will be executed, using the other parameters on the stack (loaded
via
>> the overflow).
>>
>> If the exec function doesn't exist in the text image then it fails.
>>
>> If the privileges of the process doesn't include exec, then it would
>> also fail, even if the exec system call were included.
>>
>> This combined with the non-executable rw memory (stack and data) then
>> a reasonable amount can be done to shield against buffer overflows.
>>
>> Unfortuanately, protection of rw memory is not available on Intel.
>> A: If you can read it, it is executable.
>> B: If you can write it; you can read it. (see A)
>>
>> Other patforms may vary.
>
>So I see, the question is now, to which extend security can be done in
>software and where do we have to fondle with hardware.
>
>Thanks you,
>
>JanP
>
>
>--
>You have received this message because you are subscribed to the selinux
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.
-- You have received this message because you are subscribed to the selinux 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.From: Jesse Pollard <pollard_at_tomcat.admin.navo.hpc.mil>
edm@tycho.ncsc.mil:
>
> Actually, selinux provides a very effective defense against the exploitation
> of buffer overflows. Here's why:
>
> A typical use of the buffer overflow attack is for the attacker to execute a
> shell or some other program (such as a compiler as the internet virus did.)
> Under selinux, only certain domains are allowed to execute a shell or
> another program for that matter. If the policy does not allow the domain
> that the program is executing in to exec a shell or another process (or fork
> for that matter), a policy violation occurs and the attack is stopped. In
> addition, even if the process can execute another program only programs that
> have the proper type allowed by the policy can be executed within a
> particular domain.
True, as far as it goes. The buffer overflow can:
> These restrictions apply to "privileged" (or root) processes as well. Root
> under selinux is not like root under linux, it's restricted. All system
> processes are each setup to execute in their own domain. These domains have
> only the privileges that are necessary for its process to execute. For
> example, if fingerd is attacked using buffer overflow, the policy will
> prevent it from executing another program. In addition, even if that
> attacker is able to inject extensive code into the process space, that code
> will only be able to access those objects that the policy restricts the
> fingerd's domain to.
It IS limited to only what the domain permits a process to do directly. Indirectly, the process could become a shell anyway.
> However, if the policy allows for that domain type to access /dev/mem (or
> any file that allows access to system memory) then the system can be attack.
> It is important to note, however, that the policy has to allow for a given
> domain type to access this and any domain that needs this type of access
> needs review. -->Under selinux only programs that execute in the klogd and
> the xserver domains have this access.<--
In any case, the BEST that can be done is to limit the process into a sandbox that only occupies memory. This also means that the original process couldn't do that much that was usefull anyway.
Look at a sample memory layout (this is not exact):
low:
program text (read only?) static data (read write) heap (read write) stack (read write) shared text (read only)
My arguments are still limited to Intel 32 bit only (and limited there to explainations of why "non-exec stack" doesn't stop penetrations).
There is no execute only flag on memory.
Penetration can replace any writable memory. It may reuse the shared text/ program text for libraries.
The program may remain in the heap and stack space. Any program running here can do whatever the domain allows. If the domain "allowed" the initial penetration, then there is a channel that can be used to load yet more of a program in.
Since /tmp is normally available, there is a LOT of expansion ability if the penetrated program can use mmap...
Other hardware controls do change this. Even Intel could be better if the memory management hardware had execute capability separate from read; and separate from write. Once that is possible then the initial penetration would fail.
> >> > Hello there,
> >> >
> >> > I just wondered, whether the security mechanisms implemented in SELinux
> >> > would be able to protect the system from the exploit (not the
> occurrence)
> >> > of Buffer Overflows.
> >>
> >> Simple answer: No.
> >>
> >> > Let's assume, the security mechanism and the kernel are sane & safe. An
> >> > application runs in "underpriviledged" mode, that is the policy permits
> >> > the application to read file A and read & write to file B. Now, if the
> >> > application tries to go berserk, the policy control mechanism will take
> it
> >> > out and shoot it. But if somehow a buffer within the application gets
> an
> >> > overflow, will it be able to acces memory areas, that belong to other
> >> > applications?
> >>
> >> The buffer overlow will only access current process memory. If that
> >> process can attach to other memory (via /proc or /dev/kmem) then
> >> anything goes.
> >
> >I'm not sure, if I fully got that. So, basically, the application
> >has only it's _own_ memory for data and it's own instruction stack, is
> >that correct? And, as long as the policy is intact, whatever will happen
> >in this overwritten buffer will not be able to do anything that the
> >application was not allowed to. Of course, if the application was allowed
> >to mess with memory directly, we will be in deep trouble. But even
> >standard linux should be able to keep userprocesses from doing so.
> >(I tried on this machine to mess with /proc and /dev/kmem as a user, no
> >way. Admittedly, I did it in a very dilletant way with cat /dev/kmem )
> >
> >> The problem is significant, but no solution currently exists.
> >>
> >> Depends on hardware support -
> >> IF the hardware allows read/write access to memory and denies
> >> execute access to read/write memory (instruction space is execute
> >> only) THEN and only then can buffer overflows be properly
> limited.
> >>
> >> You still have the problem of causing an "exec" to another program. But
> >> that is (partially) a different problem. This can be addressed.
> >>
> >> If an executable image on disk is not permitted to "fork/exec/..." then
> >> it can be prevented. That is one of the advantages to static linking
> >> over using shared libraries. The static link will only have the system
> >> calls included that it requires. If the program doesn't use fork/exec
> >> system call, then it would not be included.
> >>
> >> If this is combined with hardware protection above, then the exec system
> >> call could not be invoked.
> >>
> >> Invoking the system call currently can be done by loading the system call
> >> invokation on the stack, with parameters and the pointer to the stack
> area
> >> containing this executable code (replacing the return address of the
> caller;
> >> then allowing the current function to complete.
> >>
> >> If the stack cannot be exected it fails.
> >>
> >> If the return address on the stack points to an exec function, then the
> >> exec will be executed, using the other parameters on the stack (loaded
> via
> >> the overflow).
> >>
> >> If the exec function doesn't exist in the text image then it fails.
> >>
> >> If the privileges of the process doesn't include exec, then it would
> >> also fail, even if the exec system call were included.
> >>
> >> This combined with the non-executable rw memory (stack and data) then
> >> a reasonable amount can be done to shield against buffer overflows.
> >>
> >> Unfortuanately, protection of rw memory is not available on Intel.
> >> A: If you can read it, it is executable.
> >> B: If you can write it; you can read it. (see A)
> >>
> >> Other patforms may vary.
> >
> >So I see, the question is now, to which extend security can be done in
> >software and where do we have to fondle with hardware.
> >
> >Thanks you,
> >
> >JanP
> >
> >
> >--
> >You have received this message because you are subscribed to the selinux
> 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.
>
> --
> You have received this message because you are subscribed to the selinux 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.
>
Any opinions expressed are solely my own.
-- You have received this message because you are subscribed to the selinux 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.From: edm_at_tycho.ncsc.mil
>edm@tycho.ncsc.mil:
>>
>> Actually, selinux provides a very effective defense against the
exploitation
>> of buffer overflows. Here's why:
>>
>> A typical use of the buffer overflow attack is for the attacker to
execute a
>> shell or some other program (such as a compiler as the internet virus
did.)
>> Under selinux, only certain domains are allowed to execute a shell or
>> another program for that matter. If the policy does not allow the domain
>> that the program is executing in to exec a shell or another process (or
fork
>> for that matter), a policy violation occurs and the attack is stopped. In
>> addition, even if the process can execute another program only programs
that
>> have the proper type allowed by the policy can be executed within a
>> particular domain.
>
>True, as far as it goes. The buffer overflow can:
> 1. reload current process memory (it used to be called an "overlay")
> 2. start execution of the reloaded memory (may be a shell or equivalent)
> 3. which resets the stack, frees data space and generally becomes a
> new process via a simulated exec.
Agreed, I assumed that by some means (e.g. no policy violation) you can do the above.
>
>> These restrictions apply to "privileged" (or root) processes as well.
Root
>> under selinux is not like root under linux, it's restricted. All system
>> processes are each setup to execute in their own domain. These domains
have
>> only the privileges that are necessary for its process to execute. For
>> example, if fingerd is attacked using buffer overflow, the policy will
>> prevent it from executing another program. In addition, even if that
>> attacker is able to inject extensive code into the process space, that
code
>> will only be able to access those objects that the policy restricts the
>> fingerd's domain to.
>
>It IS limited to only what the domain permits a process to do directly.
>Indirectly, the process could become a shell anyway.
To be more specific, in certain instances one can inject a program and that program can be a shell. Even then, that "shell" will be confined by the policy.
>
>> However, if the policy allows for that domain type to access /dev/mem (or
>> any file that allows access to system memory) then the system can be
attack.
>> It is important to note, however, that the policy has to allow for a
given
>> domain type to access this and any domain that needs this type of access
>> needs review. -->Under selinux only programs that execute in the klogd
and
>> the xserver domains have this access.<--
>
>In any case, the BEST that can be done is to limit the process into a
>sandbox that only occupies memory. This also means that the original
process
>couldn't do that much that was usefull anyway.
Not necessarily true. After working on selinux policies for quite a while, I
can tell you that under selinux these confined processes can do quite a bit
(read useful stuff)
and I can still have confidence that if you were able to change the code (by
injection) you will still be contained. Type enforcement is quite powerful.
Here's where we diverge. You seem to be defining "penetration" as subverting (or taking over) the currently executing process by injecting data/code. No argument there. If you are worried about that, selinux will not stop this from happening to any program that has an "input" of some sort and is vulnerable to some sort buffer overflow attack. However, I can possibly create a front end (or wrapper) that could protect a program that I feel that may be vulnerable and use the type enforcement to ensure that input always follows that path.
Selinux assumes that the program is already penetrated. So, I "don't care" what code is there because I have still confined its actions.
The below is true, but it doesn't change my statements about what selinux can do. It does mean that one can attempt to attack programs by injecting data. However, under selinux these programs are still confined.
>
>Look at a sample memory layout (this is not exact):
>
>low:
> program text (read only?)
> static data (read write)
> heap (read write)
> stack (read write)
> shared text (read only)
>high:
>
>My arguments are still limited to Intel 32 bit only (and limited there to
>explainations of why "non-exec stack" doesn't stop penetrations).
>
>There is no execute only flag on memory.
>
>Penetration can replace any writable memory. It may reuse the shared text/
>program text for libraries.
>
>The program may remain in the heap and stack space. Any program running
>here can do whatever the domain allows. If the domain "allowed" the initial
>penetration, then there is a channel that can be used to load yet more
>of a program in.
>
>Since /tmp is normally available, there is a LOT of expansion ability if
>the penetrated program can use mmap...
>
>Other hardware controls do change this. Even Intel could be better if the
>memory management hardware had execute capability separate from read; and
>separate from write. Once that is possible then the initial penetration
>would fail.
Actually the i386 archtecture (still) does have this capability when you use its segementation. Too bad current OS's don't use it.
gene
===snip, snip=====
-- You have received this message because you are subscribed to the selinux 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.From: Jesse Pollard <pollard_at_tomcat.admin.navo.hpc.mil>
edm@tycho.ncsc.mil:
>>Other hardware controls do change this. Even Intel could be better if the
>>memory management hardware had execute capability separate from read; and
>>separate from write. Once that is possible then the initial penetration
>>would fail.
>
>Actually the i386 archtecture (still) does have this capability when you use
>its segementation. Too bad current OS's don't use it.
Perhaps a 2.5 or 2.7 issue to change the memory management to segmented+paging for designated processes ...?
It's time to get new documentation...
Any opinions expressed are solely my own.
-- You have received this message because you are subscribed to the selinux 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 archive was generated by hypermail 2.2.0 on Wed 11 Jun 2008 - 08:10:53 EDT