diff --git a/jobs.c b/jobs.c index 6c2ca13..38e7b39 100644 --- a/jobs.c +++ b/jobs.c @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.118 2016/01/21 18:24:41 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.119 2016/02/24 01:44:45 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -45,8 +45,8 @@ struct proc { int state; int status; /* wait status */ /* process command string from vistree */ - char command[256 - (ALLOC_SIZE + sizeof(Proc *) + sizeof(pid_t) + - 2 * sizeof(int))]; + char command[256 - (ALLOC_OVERHEAD + sizeof(Proc *) + + sizeof(pid_t) + 2 * sizeof(int))]; }; /* Notify/print flag - j_print() argument */ diff --git a/lalloc.c b/lalloc.c index 4eca6a5..98aabde 100644 --- a/lalloc.c +++ b/lalloc.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2009, 2010, 2011, 2013, 2014 + * Copyright (c) 2009, 2010, 2011, 2013, 2014, 2016 * mirabilos * * Provided that these terms and disclaimer and all copyright notices @@ -19,8 +19,11 @@ */ #include "sh.h" +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS +#include +#endif -__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.23 2015/11/29 17:05:01 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.24 2016/02/24 01:44:46 tg Exp $"); /* build with CPPFLAGS+= -DUSE_REALLOC_MALLOC=0 on ancient systems */ #if defined(USE_REALLOC_MALLOC) && (USE_REALLOC_MALLOC == 0) @@ -29,13 +32,66 @@ __RCSID("$MirOS: src/bin/mksh/lalloc.c,v 1.23 2015/11/29 17:05:01 tg Exp $"); #define remalloc(p,n) realloc_osi((p), (n)) #endif -#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE) static ALLOC_ITEM *findptr(ALLOC_ITEM **, char *, Area *); +#ifndef MKSH_ALLOC_CATCH_UNDERRUNS +#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) % ALLOC_SIZE) +#else +#define ALLOC_ISUNALIGNED(p) (((size_t)(p)) & 4095) +#undef remalloc +#undef free_osimalloc + +static void +free_osimalloc(void *ptr) +{ + struct lalloc *lp = ptr; + + if (munmap(lp, lp->len)) + err(1, "free_osimalloc"); +} + +static void * +remalloc(void *ptr, size_t size) +{ + struct lalloc *lp, *lold = ptr; + + size = (size + 4095) & ~(size_t)4095; + + if (lold && lold->len >= size) + return (ptr); + + if ((lp = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, (off_t)0)) == MAP_FAILED) + err(1, "remalloc: mmap(%zu)", size); + if (ALLOC_ISUNALIGNED(lp)) + errx(1, "remalloc: unaligned(%p)", lp); + if (mprotect(((char *)lp) + 4096, 4096, PROT_NONE)) + err(1, "remalloc: mprotect"); + lp->len = size; + + if (lold) { + memcpy(((char *)lp) + 8192, ((char *)lold) + 8192, + lold->len - 8192); + if (munmap(lold, lold->len)) + err(1, "remalloc: munmap"); + } + + return (lp); +} +#endif + void ainit(Area *ap) { +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + if (sysconf(_SC_PAGESIZE) != 4096) { + fprintf(stderr, "mksh: fatal: pagesize %lu not 4096!\n", + sysconf(_SC_PAGESIZE)); + fflush(stderr); + abort(); + } +#endif /* area pointer is an ALLOC_ITEM, just the head of the list */ ap->next = NULL; } @@ -70,7 +126,7 @@ findptr(ALLOC_ITEM **lpp, char *ptr, Area *ap) internal_errorf("rogue pointer %zX", (size_t)ptr); #endif } - return (ap); + return ((void *)ap); } void * @@ -103,7 +159,7 @@ aresize(void *ptr, size_t numb, Area *ap) internal_errorf(Toomem, numb); /* this only works because Area is an ALLOC_ITEM */ lp->next = ap->next; - ap->next = lp; + ap->next = (void *)lp; /* return user item address */ return ((char *)lp + ALLOC_SIZE); } @@ -125,7 +181,7 @@ afree(void *ptr, Area *ap) void afreeall(Area *ap) { - ALLOC_ITEM *lp; + Area *lp; /* traverse group (linked list) */ while ((lp = ap->next) != NULL) { diff --git a/main.c b/main.c index e93a142..132d00a 100644 --- a/main.c +++ b/main.c @@ -34,7 +34,7 @@ #include #endif -__RCSID("$MirOS: src/bin/mksh/main.c,v 1.307 2016/01/21 18:24:42 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/main.c,v 1.308 2016/02/24 01:44:46 tg Exp $"); extern char **environ; @@ -130,6 +130,9 @@ rndsetup(void) /* introduce variation (and yes, second arg MBZ for portability) */ mksh_TIME(bufptr->tv); +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + mprotect(((char *)bufptr) + 4096, 4096, PROT_READ | PROT_WRITE); +#endif h = chvt_rndsetup(bufptr, sizeof(*bufptr)); afree(cp, APERM); diff --git a/sh.h b/sh.h index b38e1e6..715bb21 100644 --- a/sh.h +++ b/sh.h @@ -175,9 +175,9 @@ #endif #ifdef EXTERN -__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.760 2016/01/21 19:58:13 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.761 2016/02/24 01:44:46 tg Exp $"); #endif -#define MKSH_VERSION "R52 2016/01/21" +#define MKSH_VERSION "R52 2016/02/23" /* arithmetic types: C implementation */ #if !HAVE_CAN_INTTYPES @@ -699,16 +699,29 @@ im_sorry_dave(void) /* 1. internal structure */ +struct lalloc_area { + struct lalloc_area *next; +}; + struct lalloc { - struct lalloc *next; + struct lalloc_area *next; +#ifdef MKSH_ALLOC_CATCH_UNDERRUNS + size_t len; + char dummy[8192 - sizeof(struct lalloc_area *) - sizeof(size_t)]; +#endif }; /* 2. sizes */ #define ALLOC_ITEM struct lalloc #define ALLOC_SIZE (sizeof(ALLOC_ITEM)) +#ifndef MKSH_ALLOC_CATCH_UNDERRUNS +#define ALLOC_OVERHEAD ALLOC_SIZE +#else +#define ALLOC_OVERHEAD 0 +#endif -/* 3. group structure (only the same for lalloc.c) */ -typedef struct lalloc Area; +/* 3. group structure */ +typedef struct lalloc_area Area; EXTERN Area aperm; /* permanent object space */ @@ -1073,7 +1086,7 @@ EXTERN bool builtin_spec; EXTERN char *current_wd; /* input line size */ -#define LINE (4096 - ALLOC_SIZE) +#define LINE (4096 - ALLOC_OVERHEAD) /* * Minimum required space to work with on a line - if the prompt leaves * less space than this on a line, the prompt is truncated.