* clamav RWX
@ 2010-07-12 9:22 Russell Coker
2010-07-12 11:01 ` Török Edwin
0 siblings, 1 reply; 17+ messages in thread
From: Russell Coker @ 2010-07-12 9:22 UTC (permalink / raw)
To: SE-Linux
cli_bytecode_init_jit() in libclamav/c++/bytecode2llvm.cpp in the clamav
source tree has the following:
sys::MemoryBlock B = sys::Memory::AllocateRWX(4096, NULL, &ErrMsg);
if (B.base() == 0) {
errs() << MODULE << ErrMsg << "\n";
#ifdef __linux__
errs() << MODULE << "SELinux is preventing 'execmem' access. Run
'setsebool -P clamd_use_jit on' to allow access\n";
#endif
errs() << MODULE << "falling back to interpreter mode\n";
return 0;
} else {
sys::Memory::ReleaseRWX(B);
}
The fact that the developers assumed that SE Linux is the only mechanism that
prevents RWX access is interesting.
Now the boolean in question only applies to the clamd_t domain not the
freshclam_t domain, but for some reason freshclam uses the jit anyway. Should
we put in a dontaudit rule for freshclam_t or include it in the boolean
section so that it gets execmem access if clamd_t gets it?
Also on my system the error message about SE Linux doesn't seem to get written
to the log file, so I only found it by reading the source.
--
russell@coker.com.au
http://etbe.coker.com.au/ My Main Blog
http://doc.coker.com.au/ My Documents Blog
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 9:22 clamav RWX Russell Coker
@ 2010-07-12 11:01 ` Török Edwin
2010-07-12 11:48 ` Eric Paris
0 siblings, 1 reply; 17+ messages in thread
From: Török Edwin @ 2010-07-12 11:01 UTC (permalink / raw)
To: Russell Coker; +Cc: SE-Linux
On Mon, 12 Jul 2010 19:22:47 +1000
Russell Coker <russell@coker.com.au> wrote:
> cli_bytecode_init_jit() in libclamav/c++/bytecode2llvm.cpp in the
> clamav source tree has the following:
>
> sys::MemoryBlock B = sys::Memory::AllocateRWX(4096, NULL,
> &ErrMsg); if (B.base() == 0) {
> errs() << MODULE << ErrMsg << "\n";
> #ifdef __linux__
> errs() << MODULE << "SELinux is preventing 'execmem' access.
> Run 'setsebool -P clamd_use_jit on' to allow access\n";
> #endif
> errs() << MODULE << "falling back to interpreter mode\n";
> return 0;
> } else {
> sys::Memory::ReleaseRWX(B);
> }
>
> The fact that the developers assumed that SE Linux is the only
> mechanism that prevents RWX access is interesting.
SELinux seems to be the only one which prevents RWX in a "nice
way" (i.e. mmap of RWX fails), which allows for ClamAV to fallback to
non-JIT mode [*].
PaX for example allows the mapping and just kills the program when RWX
is attempted.
>
> Now the boolean in question only applies to the clamd_t domain not
> the freshclam_t domain, but for some reason freshclam uses the jit
> anyway.
Starting with 0.96.1 freshclam loads the databases to test them, that
is why it suddenly needs the JIT.
> Should we put in a dontaudit rule for freshclam_t or include
> it in the boolean section so that it gets execmem access if clamd_t
> gets it?
IMHO clamd, clamscan and freshclam's execmem should be controlled
by the same boolean.
>
> Also on my system the error message about SE Linux doesn't seem to
> get written to the log file, so I only found it by reading the source.
>
Yes, unfortunately libclamav doesn't have access to clamd's logfile,
and clamd redirects stderr to /dev/null.
That might change in a future release.
[*]
I have some plans to make the JIT work without RWX, since ClamAV has 2
phases:
- load DB, JIT compile bytecode (should use only RW- mapping, but
currently needs RWX)
- execute (JIT compiled) bytecode (should change mapping to be R-X)
It requires some changes to the JIT though (it still emits some stubs
that need RWX during the DB load).
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 11:01 ` Török Edwin
@ 2010-07-12 11:48 ` Eric Paris
2010-07-12 12:08 ` Russell Coker
2010-07-12 12:55 ` Török Edwin
0 siblings, 2 replies; 17+ messages in thread
From: Eric Paris @ 2010-07-12 11:48 UTC (permalink / raw)
To: Török Edwin; +Cc: Russell Coker, SE-Linux
2010/7/12 Török Edwin <edwintorok@gmail.com>:
> [*]
> I have some plans to make the JIT work without RWX, since ClamAV has 2
> phases:
> - load DB, JIT compile bytecode (should use only RW- mapping, but
> currently needs RWX)
> - execute (JIT compiled) bytecode (should change mapping to be R-X)
Just so you know that is going to require the same permissions.
(Hopefully) The only way to get around the SELinux permissions is to
have 2 separate mappings. Basically in really really rough sudo-code,
file = open(filename, RWX);
unlink(file);
truncate(file, however big you need);
exec_area = mmap(PROT_EXEC, file);
write_area = mmap(PROT_WRITE, file);
then do all of the writing to write_area and all of the executing in exec_area.
http://people.redhat.com/drepper/selinux-mem.html
Simply using mremap to change a mapping from PROT_WRITE to PROT_EXEC
will cause the same problems as just doing it at the same time.
-Eric
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 11:48 ` Eric Paris
@ 2010-07-12 12:08 ` Russell Coker
2010-07-12 12:45 ` Török Edwin
2010-07-12 12:55 ` Török Edwin
1 sibling, 1 reply; 17+ messages in thread
From: Russell Coker @ 2010-07-12 12:08 UTC (permalink / raw)
To: Eric Paris; +Cc: Török Edwin, SE-Linux
On Mon, 12 Jul 2010, Eric Paris <eparis@parisplace.org> wrote:
> > I have some plans to make the JIT work without RWX, since ClamAV has 2
> > phases:
> > - load DB, JIT compile bytecode (should use only RW- mapping, but
> > currently needs RWX)
> > - execute (JIT compiled) bytecode (should change mapping to be R-X)
>
> Just so you know that is going to require the same permissions.
> (Hopefully) The only way to get around the SELinux permissions is to
> have 2 separate mappings. Basically in really really rough sudo-code,
According to the comments the code will fall-back to interpreting the data if
WRITE/EXEC is denied.
Now given that freshclam doesn't do any serious work with the data, is
interpreting it going to cause any problem that we will care about? If we are
talking about 1 hour of CPU time vs 2 hours for jit vs interpreted for run-
time stuff then it makes a difference, but if we are talking about 1 second vs
2 seconds for freshclam then maybe there's not much point.
--
russell@coker.com.au
http://etbe.coker.com.au/ My Main Blog
http://doc.coker.com.au/ My Documents Blog
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 12:08 ` Russell Coker
@ 2010-07-12 12:45 ` Török Edwin
2010-07-12 14:32 ` Martin Orr
0 siblings, 1 reply; 17+ messages in thread
From: Török Edwin @ 2010-07-12 12:45 UTC (permalink / raw)
To: russell; +Cc: Eric Paris, SE-Linux
On Mon, 12 Jul 2010 22:08:12 +1000
Russell Coker <russell@coker.com.au> wrote:
> On Mon, 12 Jul 2010, Eric Paris <eparis@parisplace.org> wrote:
> > > I have some plans to make the JIT work without RWX, since ClamAV
> > > has 2 phases:
> > > - load DB, JIT compile bytecode (should use only RW- mapping, but
> > > currently needs RWX)
> > > - execute (JIT compiled) bytecode (should change mapping to be
> > > R-X)
> >
> > Just so you know that is going to require the same permissions.
> > (Hopefully) The only way to get around the SELinux permissions is to
> > have 2 separate mappings. Basically in really really rough
> > sudo-code,
>
> According to the comments the code will fall-back to interpreting the
> data if WRITE/EXEC is denied.
>
> Now given that freshclam doesn't do any serious work with the data,
> is interpreting it going to cause any problem that we will care
> about? If we are talking about 1 hour of CPU time vs 2 hours for jit
> vs interpreted for run- time stuff then it makes a difference, but if
> we are talking about 1 second vs 2 seconds for freshclam then maybe
> there's not much point.
>
Well the purpose of loading the database with freshclam is to avoid
causing problems to clamd. So it is important that they are either both
JIT, or both non-JIT.
If for example freshclam would crash when running the JITed code, then
it would prevent loading a faulty DB into clamd. clamd would keep
running with the last DB that worked.
If freshclam falls back to nonJIT mode, and clamd doesn't, then it
could accept the database and clamd may crash.
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 11:48 ` Eric Paris
2010-07-12 12:08 ` Russell Coker
@ 2010-07-12 12:55 ` Török Edwin
2010-07-12 16:31 ` Stephen Smalley
1 sibling, 1 reply; 17+ messages in thread
From: Török Edwin @ 2010-07-12 12:55 UTC (permalink / raw)
To: Eric Paris; +Cc: Russell Coker, SE-Linux
On Mon, 12 Jul 2010 07:48:29 -0400
Eric Paris <eparis@parisplace.org> wrote:
> 2010/7/12 Török Edwin <edwintorok@gmail.com>:
>
> > [*]
> > I have some plans to make the JIT work without RWX, since ClamAV
> > has 2 phases:
> > - load DB, JIT compile bytecode (should use only RW- mapping, but
> > currently needs RWX)
> > - execute (JIT compiled) bytecode (should change mapping to be R-X)
>
> Just so you know that is going to require the same permissions.
> (Hopefully) The only way to get around the SELinux permissions is to
> have 2 separate mappings. Basically in really really rough sudo-code,
>
> file = open(filename, RWX);
> unlink(file);
> truncate(file, however big you need);
> exec_area = mmap(PROT_EXEC, file);
> write_area = mmap(PROT_WRITE, file);
>
> then do all of the writing to write_area and all of the executing in
> exec_area.
>
> http://people.redhat.com/drepper/selinux-mem.html
Yes I've seen that page, however that is not going to be so simple.
All the relocations are done assuming that the code will be executed
where you write it to (and all absolute jumps are generated the
same way).
Changing that would be a lot of work, and could introduce new bugs.
>
> Simply using mremap to change a mapping from PROT_WRITE to PROT_EXEC
> will cause the same problems as just doing it at the same time.
Then I'd better write a small testcase before converting LLVM to do
that.
IIRC I tried something like that and worked, but I could have done
something wrong. Will try again to be sure.
Is there a boolean (other than execmem) that would allow RW -> RX
mprotect()?
Why is the 2 mappings approach more secure though?
What I want is generate some code at runtime, execute it, then maybe
change it again, and execute that. Both do just that.
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 12:45 ` Török Edwin
@ 2010-07-12 14:32 ` Martin Orr
2010-07-12 14:35 ` Török Edwin
0 siblings, 1 reply; 17+ messages in thread
From: Martin Orr @ 2010-07-12 14:32 UTC (permalink / raw)
To: Török Edwin; +Cc: russell, Eric Paris, SE-Linux
On Mon 12 Jul 13:45:28 2010, Török Edwin wrote:
> On Mon, 12 Jul 2010 22:08:12 +1000
> Russell Coker <russell@coker.com.au> wrote:
>> On Mon, 12 Jul 2010, Eric Paris <eparis@parisplace.org> wrote:
>> Now given that freshclam doesn't do any serious work with the data,
>> is interpreting it going to cause any problem that we will care
>> about? If we are talking about 1 hour of CPU time vs 2 hours for jit
>> vs interpreted for run- time stuff then it makes a difference, but if
>> we are talking about 1 second vs 2 seconds for freshclam then maybe
>> there's not much point.
>>
>
> Well the purpose of loading the database with freshclam is to avoid
> causing problems to clamd. So it is important that they are either both
> JIT, or both non-JIT.
I configured clamd not to use the JIT by putting "Bytecode false" in
clamd.conf. I put the same thing in freshclam.conf, but it continues
to try to allocate executable memory.
--
Martin Orr
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 14:32 ` Martin Orr
@ 2010-07-12 14:35 ` Török Edwin
2010-07-29 11:42 ` Martin Orr
0 siblings, 1 reply; 17+ messages in thread
From: Török Edwin @ 2010-07-12 14:35 UTC (permalink / raw)
To: Martin Orr; +Cc: russell, Eric Paris, SE-Linux
On Mon, 12 Jul 2010 15:32:42 +0100
Martin Orr <martin@martinorr.name> wrote:
> On Mon 12 Jul 13:45:28 2010, Török Edwin wrote:
> > On Mon, 12 Jul 2010 22:08:12 +1000
> > Russell Coker <russell@coker.com.au> wrote:
> >> On Mon, 12 Jul 2010, Eric Paris <eparis@parisplace.org> wrote:
> >> Now given that freshclam doesn't do any serious work with the data,
> >> is interpreting it going to cause any problem that we will care
> >> about? If we are talking about 1 hour of CPU time vs 2 hours for
> >> jit vs interpreted for run- time stuff then it makes a difference,
> >> but if we are talking about 1 second vs 2 seconds for freshclam
> >> then maybe there's not much point.
> >>
> >
> > Well the purpose of loading the database with freshclam is to avoid
> > causing problems to clamd. So it is important that they are either
> > both JIT, or both non-JIT.
>
> I configured clamd not to use the JIT by putting "Bytecode false" in
> clamd.conf. I put the same thing in freshclam.conf, but it
> continues to try to allocate executable memory.
>
That sounds like a bug, please open a bugreport at bugs.clamav.net, and
attach the output of strace freshclam.
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 12:55 ` Török Edwin
@ 2010-07-12 16:31 ` Stephen Smalley
2010-07-12 18:08 ` Török Edwin
0 siblings, 1 reply; 17+ messages in thread
From: Stephen Smalley @ 2010-07-12 16:31 UTC (permalink / raw)
To: Török Edwin; +Cc: Eric Paris, Russell Coker, SE-Linux
On Mon, 2010-07-12 at 15:55 +0300, Török Edwin wrote:
> On Mon, 12 Jul 2010 07:48:29 -0400
> Eric Paris <eparis@parisplace.org> wrote:
>
> > 2010/7/12 Török Edwin <edwintorok@gmail.com>:
> >
> > > [*]
> > > I have some plans to make the JIT work without RWX, since ClamAV
> > > has 2 phases:
> > > - load DB, JIT compile bytecode (should use only RW- mapping, but
> > > currently needs RWX)
> > > - execute (JIT compiled) bytecode (should change mapping to be R-X)
> >
> > Just so you know that is going to require the same permissions.
> > (Hopefully) The only way to get around the SELinux permissions is to
> > have 2 separate mappings. Basically in really really rough sudo-code,
> >
> > file = open(filename, RWX);
> > unlink(file);
> > truncate(file, however big you need);
> > exec_area = mmap(PROT_EXEC, file);
> > write_area = mmap(PROT_WRITE, file);
> >
> > then do all of the writing to write_area and all of the executing in
> > exec_area.
> >
> > http://people.redhat.com/drepper/selinux-mem.html
>
> Yes I've seen that page, however that is not going to be so simple.
> All the relocations are done assuming that the code will be executed
> where you write it to (and all absolute jumps are generated the
> same way).
> Changing that would be a lot of work, and could introduce new bugs.
>
> >
> > Simply using mremap to change a mapping from PROT_WRITE to PROT_EXEC
> > will cause the same problems as just doing it at the same time.
>
> Then I'd better write a small testcase before converting LLVM to do
> that.
> IIRC I tried something like that and worked, but I could have done
> something wrong. Will try again to be sure.
>
> Is there a boolean (other than execmem) that would allow RW -> RX
> mprotect()?
For a private anonymous mapping, we always check execmem if PROT_EXEC
(even for a RX mapping), as it still represents making executable
arbitrary data (not tied to any file or covered by an file-based
checks). So you have:
Private anonymous mapping RW => no checks
Private anonymous mapping RX => execmem
For a shared anonymous mapping, which internally creates a tmpfs node,
we have:
Shared anonymous mapping RW => read, write to tmpfs node
Shared anonymous mapping RX => read, execute to tmpfs node
For a private file mapping, we have:
Private file mapping RW => read to file (no write since it is COW and
the file is not modified)
Private file mapping RX => read, execute, execmod (if modified during
prior RW mapping) to file
For shared file mapping, we have:
Shared file mapping RW => read, write to file
Shared file mapping RX => read, execute to file
> Why is the 2 mappings approach more secure though?
In theory, it requires the exploit writer to find two (hopefully
independently randomized) mappings in order to both write the payload
and execute from it.
> What I want is generate some code at runtime, execute it, then maybe
> change it again, and execute that. Both do just that.
--
Stephen Smalley
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 16:31 ` Stephen Smalley
@ 2010-07-12 18:08 ` Török Edwin
2010-07-12 20:26 ` Stephen Smalley
2010-07-12 21:32 ` Russell Coker
0 siblings, 2 replies; 17+ messages in thread
From: Török Edwin @ 2010-07-12 18:08 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Eric Paris, Russell Coker, SE-Linux
On Mon, 12 Jul 2010 12:31:11 -0400
Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Mon, 2010-07-12 at 15:55 +0300, Török Edwin wrote:
> > On Mon, 12 Jul 2010 07:48:29 -0400
> > Eric Paris <eparis@parisplace.org> wrote:
> >
> > > 2010/7/12 Török Edwin <edwintorok@gmail.com>:
> > >
> > > > [*]
> > > > I have some plans to make the JIT work without RWX, since ClamAV
> > > > has 2 phases:
> > > > - load DB, JIT compile bytecode (should use only RW- mapping,
> > > > but currently needs RWX)
> > > > - execute (JIT compiled) bytecode (should change mapping to be
> > > > R-X)
> > >
> > > Just so you know that is going to require the same permissions.
> > > (Hopefully) The only way to get around the SELinux permissions is
> > > to have 2 separate mappings. Basically in really really rough
> > > sudo-code,
> > >
> > > file = open(filename, RWX);
> > > unlink(file);
> > > truncate(file, however big you need);
> > > exec_area = mmap(PROT_EXEC, file);
> > > write_area = mmap(PROT_WRITE, file);
> > >
> > > then do all of the writing to write_area and all of the executing
> > > in exec_area.
> > >
> > > http://people.redhat.com/drepper/selinux-mem.html
> >
> > Yes I've seen that page, however that is not going to be so simple.
> > All the relocations are done assuming that the code will be executed
> > where you write it to (and all absolute jumps are generated the
> > same way).
> > Changing that would be a lot of work, and could introduce new bugs.
> >
> > >
> > > Simply using mremap to change a mapping from PROT_WRITE to
> > > PROT_EXEC will cause the same problems as just doing it at the
> > > same time.
> >
> > Then I'd better write a small testcase before converting LLVM to do
> > that.
> > IIRC I tried something like that and worked, but I could have done
> > something wrong. Will try again to be sure.
> >
> > Is there a boolean (other than execmem) that would allow RW -> RX
> > mprotect()?
>
> For a private anonymous mapping, we always check execmem if PROT_EXEC
> (even for a RX mapping), as it still represents making executable
> arbitrary data (not tied to any file or covered by an file-based
> checks). So you have:
> Private anonymous mapping RW => no checks
> Private anonymous mapping RX => execmem
>
> For shared file mapping, we have:
> Shared file mapping RW => read, write to file
> Shared file mapping RX => read, execute to file
So if I map a tempfile as RW, write my JITed code to it, then mprotect
to RX will it work without 'execmem'?
>
> > Why is the 2 mappings approach more secure though?
>
> In theory, it requires the exploit writer to find two (hopefully
> independently randomized) mappings in order to both write the payload
> and execute from it.
Isn't it enough if it finds the writable mapping, writes some
exploit there (which is independent of the address), then waits till it
is eventually executed?
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 18:08 ` Török Edwin
@ 2010-07-12 20:26 ` Stephen Smalley
2010-07-13 6:29 ` Török Edwin
2010-07-12 21:32 ` Russell Coker
1 sibling, 1 reply; 17+ messages in thread
From: Stephen Smalley @ 2010-07-12 20:26 UTC (permalink / raw)
To: Török Edwin; +Cc: Eric Paris, Russell Coker, SE-Linux
On Mon, 2010-07-12 at 21:08 +0300, Török Edwin wrote:
> On Mon, 12 Jul 2010 12:31:11 -0400
> Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> > On Mon, 2010-07-12 at 15:55 +0300, Török Edwin wrote:
> > > On Mon, 12 Jul 2010 07:48:29 -0400
> > > Eric Paris <eparis@parisplace.org> wrote:
> > >
> > > > 2010/7/12 Török Edwin <edwintorok@gmail.com>:
> > > >
> > > > > [*]
> > > > > I have some plans to make the JIT work without RWX, since ClamAV
> > > > > has 2 phases:
> > > > > - load DB, JIT compile bytecode (should use only RW- mapping,
> > > > > but currently needs RWX)
> > > > > - execute (JIT compiled) bytecode (should change mapping to be
> > > > > R-X)
> > > >
> > > > Just so you know that is going to require the same permissions.
> > > > (Hopefully) The only way to get around the SELinux permissions is
> > > > to have 2 separate mappings. Basically in really really rough
> > > > sudo-code,
> > > >
> > > > file = open(filename, RWX);
> > > > unlink(file);
> > > > truncate(file, however big you need);
> > > > exec_area = mmap(PROT_EXEC, file);
> > > > write_area = mmap(PROT_WRITE, file);
> > > >
> > > > then do all of the writing to write_area and all of the executing
> > > > in exec_area.
> > > >
> > > > http://people.redhat.com/drepper/selinux-mem.html
> > >
> > > Yes I've seen that page, however that is not going to be so simple.
> > > All the relocations are done assuming that the code will be executed
> > > where you write it to (and all absolute jumps are generated the
> > > same way).
> > > Changing that would be a lot of work, and could introduce new bugs.
> > >
> > > >
> > > > Simply using mremap to change a mapping from PROT_WRITE to
> > > > PROT_EXEC will cause the same problems as just doing it at the
> > > > same time.
> > >
> > > Then I'd better write a small testcase before converting LLVM to do
> > > that.
> > > IIRC I tried something like that and worked, but I could have done
> > > something wrong. Will try again to be sure.
> > >
> > > Is there a boolean (other than execmem) that would allow RW -> RX
> > > mprotect()?
> >
> > For a private anonymous mapping, we always check execmem if PROT_EXEC
> > (even for a RX mapping), as it still represents making executable
> > arbitrary data (not tied to any file or covered by an file-based
> > checks). So you have:
> > Private anonymous mapping RW => no checks
> > Private anonymous mapping RX => execmem
> >
> > For shared file mapping, we have:
> > Shared file mapping RW => read, write to file
> > Shared file mapping RX => read, execute to file
>
> So if I map a tempfile as RW, write my JITed code to it, then mprotect
> to RX will it work without 'execmem'?
That would remove the requirement for execmem, yes. But clamd_t and
freshclam_t would then require appropriate permissions to the file,
including create, unlink, read, write, and execute. You can avoid the
create+unlink requirement by mapping /dev/zero or using MAP_SHARED|
MAP_ANONYMOUS, but you'd still need RWX to the file. So I'm not sure
what we gain there.
> >
> > > Why is the 2 mappings approach more secure though?
> >
> > In theory, it requires the exploit writer to find two (hopefully
> > independently randomized) mappings in order to both write the payload
> > and execute from it.
>
> Isn't it enough if it finds the writable mapping, writes some
> exploit there (which is independent of the address), then waits till it
> is eventually executed?
Yes, although you have to time that correctly.
--
Stephen Smalley
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 18:08 ` Török Edwin
2010-07-12 20:26 ` Stephen Smalley
@ 2010-07-12 21:32 ` Russell Coker
1 sibling, 0 replies; 17+ messages in thread
From: Russell Coker @ 2010-07-12 21:32 UTC (permalink / raw)
To: Török Edwin; +Cc: Stephen Smalley, Eric Paris, SE-Linux
On Tue, 13 Jul 2010, Török Edwin <edwintorok@gmail.com> wrote:
> So if I map a tempfile as RW, write my JITed code to it, then mprotect
> to RX will it work without 'execmem'?
In this case I think that there are two viable options. One is to prevent
execmem for both freshclam_t and clamd_t and have them both interpret the
data, a performance cost for a security benefit. The other is to allow them
both execmem access for best performance. I have already submitted a patch to
the policy list to implement this.
--
russell@coker.com.au
http://etbe.coker.com.au/ My Main Blog
http://doc.coker.com.au/ My Documents Blog
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 20:26 ` Stephen Smalley
@ 2010-07-13 6:29 ` Török Edwin
2010-07-13 6:41 ` Russell Coker
2010-07-13 15:26 ` Stephen Smalley
0 siblings, 2 replies; 17+ messages in thread
From: Török Edwin @ 2010-07-13 6:29 UTC (permalink / raw)
To: Stephen Smalley; +Cc: Eric Paris, Russell Coker, SE-Linux
On Mon, 12 Jul 2010 16:26:54 -0400
Stephen Smalley <sds@tycho.nsa.gov> wrote:
> On Mon, 2010-07-12 at 21:08 +0300, Török Edwin wrote:
> > On Mon, 12 Jul 2010 12:31:11 -0400
> > Stephen Smalley <sds@tycho.nsa.gov> wrote:
> >
> > > On Mon, 2010-07-12 at 15:55 +0300, Török Edwin wrote:
> > > > On Mon, 12 Jul 2010 07:48:29 -0400
> > > > Eric Paris <eparis@parisplace.org> wrote:
> > > >
> > > > > 2010/7/12 Török Edwin <edwintorok@gmail.com>:
> > > > >
> > > > > > [*]
> > > > > > I have some plans to make the JIT work without RWX, since
> > > > > > ClamAV has 2 phases:
> > > > > > - load DB, JIT compile bytecode (should use only RW-
> > > > > > mapping, but currently needs RWX)
> > > > > > - execute (JIT compiled) bytecode (should change mapping
> > > > > > to be R-X)
> > > > >
> > > > > Just so you know that is going to require the same
> > > > > permissions. (Hopefully) The only way to get around the
> > > > > SELinux permissions is to have 2 separate mappings.
> > > > > Basically in really really rough sudo-code,
> > > > >
> > > > > file = open(filename, RWX);
> > > > > unlink(file);
> > > > > truncate(file, however big you need);
> > > > > exec_area = mmap(PROT_EXEC, file);
> > > > > write_area = mmap(PROT_WRITE, file);
> > > > >
> > > > > then do all of the writing to write_area and all of the
> > > > > executing in exec_area.
> > > > >
> > > > > http://people.redhat.com/drepper/selinux-mem.html
> > > >
> > > > Yes I've seen that page, however that is not going to be so
> > > > simple. All the relocations are done assuming that the code
> > > > will be executed where you write it to (and all absolute jumps
> > > > are generated the same way).
> > > > Changing that would be a lot of work, and could introduce new
> > > > bugs.
> > > >
> > > > >
> > > > > Simply using mremap to change a mapping from PROT_WRITE to
> > > > > PROT_EXEC will cause the same problems as just doing it at the
> > > > > same time.
> > > >
> > > > Then I'd better write a small testcase before converting LLVM
> > > > to do that.
> > > > IIRC I tried something like that and worked, but I could have
> > > > done something wrong. Will try again to be sure.
> > > >
> > > > Is there a boolean (other than execmem) that would allow RW ->
> > > > RX mprotect()?
> > >
> > > For a private anonymous mapping, we always check execmem if
> > > PROT_EXEC (even for a RX mapping), as it still represents making
> > > executable arbitrary data (not tied to any file or covered by an
> > > file-based checks). So you have:
> > > Private anonymous mapping RW => no checks
> > > Private anonymous mapping RX => execmem
> > >
> > > For shared file mapping, we have:
> > > Shared file mapping RW => read, write to file
> > > Shared file mapping RX => read, execute to file
> >
> > So if I map a tempfile as RW, write my JITed code to it, then
> > mprotect to RX will it work without 'execmem'?
>
> That would remove the requirement for execmem, yes. But clamd_t and
> freshclam_t would then require appropriate permissions to the file,
> including create, unlink, read, write,
I would have these permissions for something in /tmp, right?
> and execute.
I probably wouldn't have this though.
> You can avoid the
> create+unlink requirement by mapping /dev/zero or using MAP_SHARED|
> MAP_ANONYMOUS, but you'd still need RWX to the file. So I'm not sure
> what we gain there.
If I can change the mapping from RW <-> RX, then the mapping is
writable only for a brief period (DB reload), so an exploit can't take
advantage of the RWX mapping (since there is no RWX mapping).
Thats better than allowing 'execmem' for the entire process, isn't it?
Best regards,
--Edwin
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-13 6:29 ` Török Edwin
@ 2010-07-13 6:41 ` Russell Coker
2010-09-23 20:12 ` Török Edwin
2010-07-13 15:26 ` Stephen Smalley
1 sibling, 1 reply; 17+ messages in thread
From: Russell Coker @ 2010-07-13 6:41 UTC (permalink / raw)
To: Török Edwin, SE-Linux
On Tue, 13 Jul 2010, Török Edwin <edwintorok@gmail.com> wrote:
> If I can change the mapping from RW <-> RX, then the mapping is
> writable only for a brief period (DB reload), so an exploit can't take
> advantage of the RWX mapping (since there is no RWX mapping).
> Thats better than allowing 'execmem' for the entire process, isn't it?
That sounds like a good benefit.
--
russell@coker.com.au
http://etbe.coker.com.au/ My Main Blog
http://doc.coker.com.au/ My Documents Blog
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-13 6:29 ` Török Edwin
2010-07-13 6:41 ` Russell Coker
@ 2010-07-13 15:26 ` Stephen Smalley
1 sibling, 0 replies; 17+ messages in thread
From: Stephen Smalley @ 2010-07-13 15:26 UTC (permalink / raw)
To: Török Edwin; +Cc: Eric Paris, Russell Coker, SE-Linux
On Tue, 2010-07-13 at 09:29 +0300, Török Edwin wrote:
> On Mon, 12 Jul 2010 16:26:54 -0400
> Stephen Smalley <sds@tycho.nsa.gov> wrote:
>
> > On Mon, 2010-07-12 at 21:08 +0300, Török Edwin wrote:
> > > On Mon, 12 Jul 2010 12:31:11 -0400
> > > Stephen Smalley <sds@tycho.nsa.gov> wrote:
> > >
> > > > On Mon, 2010-07-12 at 15:55 +0300, Török Edwin wrote:
> > > > > On Mon, 12 Jul 2010 07:48:29 -0400
> > > > > Eric Paris <eparis@parisplace.org> wrote:
> > > > >
> > > > > > 2010/7/12 Török Edwin <edwintorok@gmail.com>:
> > > > > >
> > > > > > > [*]
> > > > > > > I have some plans to make the JIT work without RWX, since
> > > > > > > ClamAV has 2 phases:
> > > > > > > - load DB, JIT compile bytecode (should use only RW-
> > > > > > > mapping, but currently needs RWX)
> > > > > > > - execute (JIT compiled) bytecode (should change mapping
> > > > > > > to be R-X)
> > > > > >
> > > > > > Just so you know that is going to require the same
> > > > > > permissions. (Hopefully) The only way to get around the
> > > > > > SELinux permissions is to have 2 separate mappings.
> > > > > > Basically in really really rough sudo-code,
> > > > > >
> > > > > > file = open(filename, RWX);
> > > > > > unlink(file);
> > > > > > truncate(file, however big you need);
> > > > > > exec_area = mmap(PROT_EXEC, file);
> > > > > > write_area = mmap(PROT_WRITE, file);
> > > > > >
> > > > > > then do all of the writing to write_area and all of the
> > > > > > executing in exec_area.
> > > > > >
> > > > > > http://people.redhat.com/drepper/selinux-mem.html
> > > > >
> > > > > Yes I've seen that page, however that is not going to be so
> > > > > simple. All the relocations are done assuming that the code
> > > > > will be executed where you write it to (and all absolute jumps
> > > > > are generated the same way).
> > > > > Changing that would be a lot of work, and could introduce new
> > > > > bugs.
> > > > >
> > > > > >
> > > > > > Simply using mremap to change a mapping from PROT_WRITE to
> > > > > > PROT_EXEC will cause the same problems as just doing it at the
> > > > > > same time.
> > > > >
> > > > > Then I'd better write a small testcase before converting LLVM
> > > > > to do that.
> > > > > IIRC I tried something like that and worked, but I could have
> > > > > done something wrong. Will try again to be sure.
> > > > >
> > > > > Is there a boolean (other than execmem) that would allow RW ->
> > > > > RX mprotect()?
> > > >
> > > > For a private anonymous mapping, we always check execmem if
> > > > PROT_EXEC (even for a RX mapping), as it still represents making
> > > > executable arbitrary data (not tied to any file or covered by an
> > > > file-based checks). So you have:
> > > > Private anonymous mapping RW => no checks
> > > > Private anonymous mapping RX => execmem
> > > >
> > > > For shared file mapping, we have:
> > > > Shared file mapping RW => read, write to file
> > > > Shared file mapping RX => read, execute to file
> > >
> > > So if I map a tempfile as RW, write my JITed code to it, then
> > > mprotect to RX will it work without 'execmem'?
> >
> > That would remove the requirement for execmem, yes. But clamd_t and
> > freshclam_t would then require appropriate permissions to the file,
> > including create, unlink, read, write,
>
> I would have these permissions for something in /tmp, right?
>
> > and execute.
>
> I probably wouldn't have this though.
>
> > You can avoid the
> > create+unlink requirement by mapping /dev/zero or using MAP_SHARED|
> > MAP_ANONYMOUS, but you'd still need RWX to the file. So I'm not sure
> > what we gain there.
>
> If I can change the mapping from RW <-> RX, then the mapping is
> writable only for a brief period (DB reload), so an exploit can't take
> advantage of the RWX mapping (since there is no RWX mapping).
> Thats better than allowing 'execmem' for the entire process, isn't it?
Allowing execmem just permits the process to perform a mmap or mprotect
of an anonymous mapping with PROT_EXEC. It doesn't automatically apply
PROT_EXEC to any mappings (it isn't the same as marking the executable
as requiring an executable stack).
--
Stephen Smalley
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] 17+ messages in thread
* Re: clamav RWX
2010-07-12 14:35 ` Török Edwin
@ 2010-07-29 11:42 ` Martin Orr
0 siblings, 0 replies; 17+ messages in thread
From: Martin Orr @ 2010-07-29 11:42 UTC (permalink / raw)
To: Török Edwin; +Cc: russell, Eric Paris, SE-Linux
On Mon 12 Jul 15:35:21 2010, Török Edwin wrote:
> On Mon, 12 Jul 2010 15:32:42 +0100
> Martin Orr <martin@martinorr.name> wrote:
>
>> On Mon 12 Jul 13:45:28 2010, Török Edwin wrote:
>> > Well the purpose of loading the database with freshclam is to avoid
>> > causing problems to clamd. So it is important that they are either
>> > both JIT, or both non-JIT.
>>
>> I configured clamd not to use the JIT by putting "Bytecode false" in
>> clamd.conf. I put the same thing in freshclam.conf, but it
>> continues to try to allocate executable memory.
>>
>
> That sounds like a bug, please open a bugreport at bugs.clamav.net, and
> attach the output of strace freshclam.
I just realised that "Bytecode false" doesn't do what I thought it
does: for some reason I had thought it just disabled the JIT, but in
fact it disables bytecode altogether.
Nevertheless it still seems that freshclam shouldn't need RWX memory
if bytecode is disabled, so I reported this as bug 2149.
--
Martin Orr
--
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] 17+ messages in thread
* Re: clamav RWX
2010-07-13 6:41 ` Russell Coker
@ 2010-09-23 20:12 ` Török Edwin
0 siblings, 0 replies; 17+ messages in thread
From: Török Edwin @ 2010-09-23 20:12 UTC (permalink / raw)
To: SE-Linux; +Cc: russell, Stephen Smalley, Eric Paris
Hi,
A comment on this bug reminded me that we haven't found any solution
for the JIT-under-SELinux issue (except double mapping):
https://bugzilla.redhat.com/show_bug.cgi?id=573191#c29
As discussed last time, the RW <-> RX change would be needed only during
a brief period (DB reload).
Using a shared mapping would trade RWX requirements on memory for
RWX requirements on a file which is not better.
I have some new ideas though.
1. new protection, lets call it execmem_trustedonly
Some observations first:
- there is 1 thread in clamd that reloads the database
- if that thread is compromised it is game over anyway (someone can
load a malformed signature that causes clamd to quit, load empty DB,
etc.)
- hence that thread is somewhat "trusted" already
- if you find a way to exploit that thread, then execmem protection
won't help, you can do almost anything with ClamAV already, all you
need is write access to memory
- the official databases are digitally signed, and ClamAV by default
won't load bytecode from unsigned databases (it will for normal
signatures of course)
It'd be good if clamd could, on startup, tell the OS that it has a
*single* thread that needs RW <-> RX transitions. The OS could check
that the SELinux policy allows that, lets call it execmem_trustedonly.
Not sure what the proper mechanism would be to do this, maybe
some prctl() call, or some mechanism similar to dropping root
privileges:
- if SELinux policy allows execmem_trustedonly the main thread starts
with this capability (doing RW <-> RX transitions)
- it can atomically transfer this capability to other threads
(permanently losing it, with no transfer back possible)
- it can completely turn off the capability if it doesn't need it
The DB reload thread happens to be clamd's main thread, so it would
have this capability. As discussed this thread is the most trusted in
clamd, if you found a way to make it execute arbitrary code then
execmem protections will get you no additional protection anyway.
If one of the scanner threads is exploited, then execmem protections
would trigger and stop it. The DB reload thread would be able to
use the JIT, and all would be good.
2. Investigate if LLVM can do relocations to a different map. In fact
it already does relocations, but it assumes the code will run in the
same place as original. Also there might be some absolute addresses
emitted.
If yes then the 2 maps approach would work (codegen to one, exec
another).
3. Once I codegened to the writable map, I don't need it anymore and
will probably free it. Wouldn't it be great if the OS could relocate
the executable mapping to the same place the writable mapping was?
We know for sure there is enough space there.
mremap() seems to be able to do this, and seems to automatically unmap
whatever was in place of the target address so it seems to be atomic
too.
Would this work for SELinux?
It would go like this:
create map pairs at addresses X(RW) and Y (RX) linked by a file as
described in the no execmem docs.
codegen to map at address X as usual.
When done, use mremap() to move the executable mapping from address Y
to X, atomically unmapping the existing RW mapping at address X.
I'm open to other ideas too of course.
Best regards,
--Edwin
--
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] 17+ messages in thread
end of thread, other threads:[~2010-09-23 20:12 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-07-12 9:22 clamav RWX Russell Coker
2010-07-12 11:01 ` Török Edwin
2010-07-12 11:48 ` Eric Paris
2010-07-12 12:08 ` Russell Coker
2010-07-12 12:45 ` Török Edwin
2010-07-12 14:32 ` Martin Orr
2010-07-12 14:35 ` Török Edwin
2010-07-29 11:42 ` Martin Orr
2010-07-12 12:55 ` Török Edwin
2010-07-12 16:31 ` Stephen Smalley
2010-07-12 18:08 ` Török Edwin
2010-07-12 20:26 ` Stephen Smalley
2010-07-13 6:29 ` Török Edwin
2010-07-13 6:41 ` Russell Coker
2010-09-23 20:12 ` Török Edwin
2010-07-13 15:26 ` Stephen Smalley
2010-07-12 21:32 ` Russell Coker
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.