On Tue, 2016-09-13 at 13:27 +0200, Otto Moerbeek wrote:
> On Thu, Sep 08, 2016 at 06:42:33PM -0400, Daniel Micay wrote:
> 
> > A bit off-topic: 'J' enables junk-on-init which is for debugging,
> > but it
> > also currently has security improvements for large allocations.
> > There's
> > only partial junk-on-free by default (half a page), and 'U' disables
> > large allocation junk-on-free without 'J'. I think it would make
> > sense
> > to remove those optimizations since it's fine if the cost scales up
> > with
> > larger allocations and losing the guarantee of not leaking data via
> > uninitialized memory with 'U' is not great. Using 'U' is quite
> > expensive
> > regardless, and adds some pathological performance cases for small
> > size
> > allocations which is more important. I ended up removing both of
> > those
> > optimizations for the CopperheadOS port.
> 
> I would prefer to see a diff with this. For me, that should be easier
> to understand than you description.

This is the diff from the CopperheadOS port which won't apply directly
to malloc.c in OpenBSD, but should explain what I mean since it's just a
few lines. Just ignore the part where it removes malloc_junk=2, which is
because junk-on-init is split out (so this obsoleted the extra mode).

The current OpenBSD code only wipes up to MALLOC_MAXCHUNK with junk @ 1,
and it similarly doesn't wipe at all with 'U' (even though junk-on-free
also serves the purpose of preventing information leaks, not just
mitigating use-after-free). IMO, optimizing large allocation perf like
this isn't worthwhile.

diff --git a/libc/bionic/omalloc.c b/libc/bionic/omalloc.c
index e451d79..9277ee7 100644
--- a/libc/bionic/omalloc.c
+++ b/libc/bionic/omalloc.c
@@ -504,7 +504,7 @@ map(struct dir_info *d, void *hint, size_t sz, int 
zero_fill)
                                        madvise(p, sz, MADV_NORMAL);
                                if (zero_fill)
                                        memset(p, 0, sz);
-                               else if (mopts.malloc_junk == 2 &&
+                               else if (mopts.malloc_junk &&
                                    mopts.malloc_freeunmap)
                                        memset(p, SOME_FREEJUNK, sz);
                                return p;
@@ -524,7 +524,7 @@ map(struct dir_info *d, void *hint, size_t sz, int 
zero_fill)
                d->free_regions_size -= psz;
                if (zero_fill)
                        memset(p, 0, sz);
-               else if (mopts.malloc_junk == 2 && mopts.malloc_freeunmap)
+               else if (mopts.malloc_junk && mopts.malloc_freeunmap)
                        memset(p, SOME_FREEJUNK, sz);
                return p;
        }
@@ -603,7 +603,7 @@ omalloc_parseopt(char opt)
                mopts.malloc_junk = 0;
                break;
        case 'J':
-               mopts.malloc_junk = 2;
+               mopts.malloc_junk = 1;
                break;
        case 'i':
                mopts.malloc_junk_init = 0;
@@ -1517,8 +1517,7 @@ ofree(struct dir_info *pool, void *p)
                        STATS_SUB(pool->malloc_guarded, mopts.malloc_guard);
                }
                if (mopts.malloc_junk && !mopts.malloc_freeunmap) {
-                       size_t amt = mopts.malloc_junk == 1 ? MALLOC_MAXCHUNK :
-                           PAGEROUND(sz) - mopts.malloc_guard;
+                       size_t amt = PAGEROUND(sz) - mopts.malloc_guard;
                        memset(p, SOME_FREEJUNK, amt);
                }
                unmap(pool, p, PAGEROUND(sz));

Reply via email to