Re: Grsec/PaX and Exec-shield

2003-11-04 Thread spender
> Also note that I use LSM on all my kernels, so anything that conflicts with 
> LSM is something that I have no ability to test and therefore no interest in 
> maintaining.  I'm sure I could get PaX working with LSM, but it would take 
> some work.  Anyway I'll look into this matter after I upload an exec-shield 
> package.

I've spared you your precious time and gone ahead and done this for you.  
Funny thing is that the latest version of LSM for 2.4 is still at 
2.4.20.  Trying to patch a clean 2.4.22 kernel with this results in 
rejects in 9 files.  Here're the contents of the rejects:

***
*** 329,335 
  };

  #define MAY_PTRACE(p) \
- (p==current||(p->p_pptr==current&&(p->ptrace & 
PT_PTRACED)&&p->state==TASK_STOPPED))


  static int mem_open(struct inode* inode, struct file* file)
--- 329,335 
  };

  #define MAY_PTRACE(p) \
+ (p==current||(p->p_pptr==current&&(p->ptrace & 
PT_PTRACED)&&p->state==TASK_STOPPED&&security_ops->ptrace(current,p)==0))


  static int mem_open(struct inode* inode, struct file* file)
***
*** 1418,1423 
if (!sb)
goto out;
}

ret = -EINVAL;
switch (cmds) {
--- 1421,1430 
if (!sb)
goto out;
}
+
+   ret = security_ops->quotactl (cmds, type, id, sb);
+   if (ret)
+   goto out;

ret = -EINVAL;
switch (cmds) {
***
*** 75,86 

  static kmem_cache_t * inode_cachep;

- #define alloc_inode() \
-((struct inode *) kmem_cache_alloc(inode_cachep, SLAB_KERNEL))
  static void destroy_inode(struct inode *inode)
  {
if (inode_has_buffers(inode))
BUG();
kmem_cache_free(inode_cachep, (inode));
  }

--- 76,101 

  static kmem_cache_t * inode_cachep;

+ static inline struct inode *alloc_inode(void)
+ {
+   struct inode *inode;
+
+   inode = ((struct inode *) kmem_cache_alloc(inode_cachep, 
SLAB_KERNEL));
+   if (!inode)
+   return NULL;
+   inode->i_security = NULL;
+   if (security_ops->inode_alloc_security(inode)) {
+   kmem_cache_free(inode_cachep, (inode));
+   return NULL;
+   }
+   return inode;
+ }
+
  static void destroy_inode(struct inode *inode)
  {
if (inode_has_buffers(inode))
BUG();
+   security_ops->inode_free_security(inode);
kmem_cache_free(inode_cachep, (inode));
  }

***
*** 27,32 
  #include 
  #include 
  #include 

  #include 

--- 27,33 
  #include 
  #include 
  #include 
+ #include 

  #include 

***
*** 1044,1063 

  asmlinkage long sys_sethostname(char *name, int len)
  {
int errno;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
down_write(&uts_sem);
-   errno = -EFAULT;
-   if (!copy_from_user(system_utsname.nodename, name, len)) {
-   system_utsname.nodename[len] = 0;
-   errno = 0;
-   }
up_write(&uts_sem);
-   return errno;
  }

  asmlinkage long sys_gethostname(char *name, int len)
--- 1043,1067 

  asmlinkage long sys_sethostname(char *name, int len)
  {
+   char nodename[__NEW_UTS_LEN+1];
int errno;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
+   if (copy_from_user(nodename, name, len))
+   return -EFAULT;
+   nodename[len] = 0;
+
+   errno = security_ops->sethostname(nodename);
+   if (errno)
+   return errno;
+
down_write(&uts_sem);
+   memcpy(system_utsname.nodename, nodename, len+1);
up_write(&uts_sem);
+   return 0;
  }

  asmlinkage long sys_gethostname(char *name, int len)
***
*** 1083,1101 
   */
  asmlinkage long sys_setdomainname(char *name, int len)
  {
int errno;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;

down_write(&uts_sem);
-   errno = -EFAULT;
-   if (!copy_from_user(system_utsname.domainname, name, len)) {
-   errno = 0;
-   system_utsname.domainname[len] = 0;
-   }
up_write(&uts_sem);
return errno;
  }
--- 1087,1109 
   */
  asmlinkage long sys_setdomainname(char *name, int len)
  {
+   char domainname[__NEW_UTS_LEN+1];
int errno;

if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (len < 0 || len > __NEW_UTS_LEN)
return -EINVAL;
+   if (copy_from_user(domainname, name, len))
+   return -EFAULT;
+   domainname[len] = 0;
+
+   errno = security_ops->setdomainname(domainname);
+   if (errno)
+   return errno;

down_write(&uts_sem);
+   memcpy(

Re: Grsec/PaX and Exec-shield

2003-11-04 Thread spender
On Tue, Nov 04, 2003 at 06:49:58PM +0100, Ingo Molnar wrote:
> 
> On Tue, 4 Nov 2003 [EMAIL PROTECTED] wrote:
> 
> > [...] Are you so certain that Exec-shield stops execution in shared
> > library bss/data? [...]
> 
> no, it doesnt, this is the main (and pretty much only) substantial
> difference between exec-shield and PaX.

Well that sounds quite a bit different than what you had to say about 
these yesterday:
"these are caught by exec-shield too, and are quite important categories to
catch."  Clearly both cannot be correct at the same time.

> Exec-shield will stop execution in
> ET_EXEC binary's bss/data but it will not stop code injection into library
> bss/data. Here is the 'protection matrix' of all the overflowable and
> shellcodable virtual memory areas:
> 

That's not quite correct.  Exec-shield "can" stop, but "will" stop is a 
completely different matter.  I'll let the bugfixed paxtest tell this 
story, however.

> If you mean exec-shield=2 then it is 'forcing' exec-shield and is only
> recommended for testing purposes.

For the benefit of the readers that might have missed this subtle 
attempt at diverting the main point of my argument: exec-shield=2 means 
enabling exec-shield on all binaries but the ones it is disabled for.  
This would be a secure-by-default design, and yet it's being recommended 
for "testing purposes" only?  Note that PaX enables itself on all 
binaries by default, and that Ingo here does not argue that 
exec-shield=2 could result in a non-working system.   Basically, his 
following argument, which I cannot refute, is that if exec-shield is 
DISABLED BY DEFAULT ON ALL BINARIES, then it results in a working 
system.

Now, I remember some complaining about having to chpax java if you run 
it and PaX breaks it.  How is that more work than running exec-shield in 
=1 mode, and having to explicitly enable it on all binaries you think 
should have protection, since you don't recommend =2 for production 
machines?

Or, through what mechanism have you devised to notify the user when an 
application he thought was protected by exec-shield decides to mprotect 
an anonymous mapping rwx, thus making the main executable's bss and data 
sections executable?  Viewing the process' maps file isn't going to tell 
you what kind of protection the process currently has.  How about if 
someone mprotects a page of the stack rwx?  Whoops, entire address space 
because executable.  I'm also curious, given the rest of your model, how 
the lack of trampoline emulation is a security feature.  From your 
announcement:

To provide as good protection as possible, there's no trampoline
workaround in the exec-shield code - ie. exec-limit violations in the
trampoline case are never let through. Applications that need to rely on
gcc trampolines will have to use the per-binary ELF flag to make the 
stack executable again.


This all sounds very contradictory to your point that there's only one 
substantial difference between PaX and Exec-shield (funny how it was 
never mentioned that PaX is a true per-page implementation, while yours
is much more coarse grained...that sounds pretty substantial too).

Though, I don't know what I'm talking about here.  Clearly every Debian 
developer who was kind enough to make useless non-technical posts to 
this thread know much more about this subject than I do.  So please, 
listen to your in house "security experts" instead of me.  They're 
probably better for a good laugh, anyways.

-Brad




Re: Grsec/PaX and Exec-shield

2003-11-04 Thread spender
> yes. It's a compatible opt-in for something that cannot be enabled for all
> binaries, instead of an opt-out. You say it's a bug, i say it's a feature.  
> A really bad analogy: it's like spam, you want to opt-in not opt-out ;)

That is indeed a really bad analogy.  Security shouldn't be as unwanted 
as spam.
> 
> > [...] Note that PaX enables itself on all binaries by default, and that
> > Ingo here does not argue that exec-shield=2 could result in a
> > non-working system.  Basically, his following argument, which I cannot
> > refute, is that if exec-shield is DISABLED BY DEFAULT ON ALL BINARIES,
> > then it results in a working system.
> 
> my main argument is that on a PT_GNU_STACK-recompiled system, you'll see
> that the overwhelming majority of binaries and libraries have a non-exec
> stack almost straight away. With some extra tweaking and patching it's up
> to 99.9%.
> 
> [ or you can manually force on the feature for every binary, if you dont
> have a PT_GNU_STACK system, via exec-shield=2, and disable exec-shield on
> a per binary basis, if you want/need to. ]
> 
> i'm not sure why you are fighting the PT_GNU_STACK concept - it's not
> connected to exec-shield at all - just take the ELF loader bits from the
> exec-shield patch and use it in PaX - it will be for the better to get rid
> of a fair share of chpax use. (Like you changed the library layout in PaX
> to match that of exec-shield.)
> 
> if you could get rid of the 1.5 GB VM limitation of PaX and if you could
> change it to use PT_GNU_STACK to set the process stack's protection bits
> then i think there's no need for exec-shield - PaX will provide better
> protection at no cost and no tradeoffs. I did and still do exec-shield to
> solve a problem. If something else does it better with no tradeoffs then
> all the better, one less maintainance headache :-)
> 
> > Now, I remember some complaining about having to chpax java if you run
> > it and PaX breaks it.  How is that more work than running exec-shield in
> > =1 mode, and having to explicitly enable it on all binaries you think
> > should have protection, since you don't recommend =2 for production
> > machines?
> 
> you dont have to explicitly enable it on all binaries you think should
> have protection - the compiler will do this just fine via PT_GNU_STACK. It
> is a property of the binary, not some policy question, whether an
> application needs an executable stack or not.
> 
> where does PaX re-enable stack executability if an application dlopen()s a
> library that needs an executable stack - because eg. it is using gcc
> trampolines? Can you enable PaX for Mozilla and guarantee that no plugin
> will ever need an executable stack?

If a library uses trampolines, PaX doesn't need to enable stack 
executability because it has trampoline emulation.  I enable PaX on 
mozilla and use several plugins including flash with no problems.

> java (or any other non-PT_GNU_STACK third party app) will just default to
> exec-shield-off.
> 
> > Viewing the process' maps file isn't going to tell you what kind of
> > protection the process currently has. [...]

Sorry, I should have said "what protection the process had a millisecond 
before you decided to check its maps file"  It's this kind of "quantum 
security" (while you don't observe it, it could be doing what you want 
or nothing at all) that I wouldn't want as an administrator.  If a 
binary decides to create a mapping with some bad protections, in 
PaX, the administrator would be notified.  In Exec-shield, this 
kind of behavior will affect the executability of sections of the address
space that were previously non-executable and the administrator might 
never know, even if he had the same script as you checking processes on 
the system.

> this is an old announcement, and says other things too that are not the
> case anymore. E.g. this area got reworked since then and these (rare but
> existing) apps/libs are detected automatically via the PT_GNU_STACK
> mechanism.

but is it not still true that you don't have trampoline emulation: if an 
application uses trampolines the solution in exec-shield is to make the 
entire stack executable?

> really, if you think granularity is a big issue for everything else but
> library bss/data then feel free to install Fedora and check out the
> mappings. It just doesnt happen all that often anymore that an app
> triggers some really bad protection layout, and if it happens, it's
> fixable in a nonintrusive way. The important thing is to have protection
> here and now for 99% of the layouts in a generic distribution. [with the
> caveat of library bss/data, as you correctly observed.]

I'm making a big issue of the granularity because you make a big issue 
of the 1.5GB limit.  While granularity in your case actually is an issue 
for all exec-shield apps, the fact is I've received no reports of anyone 
running into address space limits with PaX.  So I'll agree that the 
granularity in cases other than librarie