* 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 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 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-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: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 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: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
* 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 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
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.