Made the mprotect() fix for SDL_SoftStretch() more general for hardened linux, etc. SDL-1.2
authorSam Lantinga <slouken@libsdl.org>
Sat, 29 Dec 2007 05:18:33 +0000
branchSDL-1.2
changeset 4109cd2ab40f1219
parent 4108 3feb94233f90
child 4110 b896fb0d4f9f
Made the mprotect() fix for SDL_SoftStretch() more general for hardened linux, etc.
configure.in
include/SDL_config.h.in
src/video/SDL_stretch.c
     1.1 --- a/configure.in	Sat Dec 29 03:50:29 2007 +0000
     1.2 +++ b/configure.in	Sat Dec 29 05:18:33 2007 +0000
     1.3 @@ -16,9 +16,9 @@
     1.4  #
     1.5  SDL_MAJOR_VERSION=1
     1.6  SDL_MINOR_VERSION=2
     1.7 -SDL_MICRO_VERSION=12
     1.8 -SDL_INTERFACE_AGE=1
     1.9 -SDL_BINARY_AGE=12
    1.10 +SDL_MICRO_VERSION=13
    1.11 +SDL_INTERFACE_AGE=2
    1.12 +SDL_BINARY_AGE=13
    1.13  SDL_VERSION=$SDL_MAJOR_VERSION.$SDL_MINOR_VERSION.$SDL_MICRO_VERSION
    1.14  
    1.15  AC_SUBST(SDL_MAJOR_VERSION)
    1.16 @@ -146,7 +146,7 @@
    1.17      if test x$ac_cv_func_strtod = xyes; then
    1.18          AC_DEFINE(HAVE_STRTOD)
    1.19      fi
    1.20 -    AC_CHECK_FUNCS(malloc calloc realloc free getenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf iconv sigaction setjmp nanosleep)
    1.21 +    AC_CHECK_FUNCS(malloc calloc realloc free getenv putenv unsetenv qsort abs bcopy memset memcpy memmove strlen strlcpy strlcat strdup _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp sscanf snprintf vsnprintf iconv sigaction setjmp nanosleep mprotect)
    1.22  
    1.23      AC_CHECK_LIB(iconv, libiconv_open, [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -liconv"])
    1.24      AC_CHECK_LIB(m, pow, [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
     2.1 --- a/include/SDL_config.h.in	Sat Dec 29 03:50:29 2007 +0000
     2.2 +++ b/include/SDL_config.h.in	Sat Dec 29 05:18:33 2007 +0000
     2.3 @@ -136,6 +136,7 @@
     2.4  #undef HAVE_CLOCK_GETTIME
     2.5  #undef HAVE_DLVSYM
     2.6  #undef HAVE_GETPAGESIZE
     2.7 +#undef HAVE_MPROTECT
     2.8  
     2.9  #else
    2.10  /* We may need some replacement for stdarg.h here */
     3.1 --- a/src/video/SDL_stretch.c	Sat Dec 29 03:50:29 2007 +0000
     3.2 +++ b/src/video/SDL_stretch.c	Sat Dec 29 05:18:33 2007 +0000
     3.3 @@ -42,14 +42,15 @@
     3.4  
     3.5  #ifdef USE_ASM_STRETCH
     3.6  
     3.7 -/* OpenBSD has non-executable memory by default, so use mprotect() */
     3.8 -#ifdef __OpenBSD__
     3.9 -#define USE_MPROTECT
    3.10 -#endif
    3.11 -#ifdef USE_MPROTECT
    3.12 +#ifdef HAVE_MPROTECT
    3.13  #include <sys/types.h>
    3.14  #include <sys/mman.h>
    3.15  #endif
    3.16 +#ifdef __GNUC__
    3.17 +#define PAGE_ALIGNED __attribute__((__aligned__(4096)))
    3.18 +#else
    3.19 +#define PAGE_ALIGNED
    3.20 +#endif
    3.21  
    3.22  #if defined(_M_IX86) || defined(i386)
    3.23  #define PREFIX16	0x66
    3.24 @@ -62,7 +63,7 @@
    3.25  #error Need assembly opcodes for this architecture
    3.26  #endif
    3.27  
    3.28 -static unsigned char copy_row[4096];
    3.29 +static unsigned char copy_row[4096] PAGE_ALIGNED;
    3.30  
    3.31  static int generate_rowbytes(int src_w, int dst_w, int bpp)
    3.32  {
    3.33 @@ -70,6 +71,7 @@
    3.34  		int bpp;
    3.35  		int src_w;
    3.36  		int dst_w;
    3.37 +		int status;
    3.38  	} last;
    3.39  
    3.40  	int i;
    3.41 @@ -80,11 +82,12 @@
    3.42  	/* See if we need to regenerate the copy buffer */
    3.43  	if ( (src_w == last.src_w) &&
    3.44  	     (dst_w == last.dst_w) && (bpp == last.bpp) ) {
    3.45 -		return(0);
    3.46 +		return(last.status);
    3.47  	}
    3.48  	last.bpp = bpp;
    3.49  	last.src_w = src_w;
    3.50  	last.dst_w = dst_w;
    3.51 +	last.status = -1;
    3.52  
    3.53  	switch (bpp) {
    3.54  	    case 1:
    3.55 @@ -100,9 +103,6 @@
    3.56  		SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp);
    3.57  		return(-1);
    3.58  	}
    3.59 -#ifdef USE_MPROTECT
    3.60 -	mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_WRITE|PROT_EXEC);
    3.61 -#endif
    3.62  	pos = 0x10000;
    3.63  	inc = (src_w << 16) / dst_w;
    3.64  	eip = copy_row;
    3.65 @@ -122,15 +122,23 @@
    3.66  	}
    3.67  	*eip++ = RETURN;
    3.68  
    3.69 -	/* Verify that we didn't overflow (too late) */
    3.70 +	/* Verify that we didn't overflow (too late!!!) */
    3.71  	if ( eip > (copy_row+sizeof(copy_row)) ) {
    3.72  		SDL_SetError("Copy buffer overflow");
    3.73  		return(-1);
    3.74  	}
    3.75 +#ifdef HAVE_MPROTECT
    3.76 +	/* Make the code executable */
    3.77 +	if ( mprotect(copy_row, sizeof(copy_row), PROT_READ|PROT_WRITE|PROT_EXEC) < 0 ) {
    3.78 +		SDL_SetError("Couldn't make copy buffer executable");
    3.79 +		return(-1);
    3.80 +	}
    3.81 +#endif
    3.82 +	last.status = 0;
    3.83  	return(0);
    3.84  }
    3.85  
    3.86 -#else
    3.87 +#endif /* USE_ASM_STRETCH */
    3.88  
    3.89  #define DEFINE_COPY_ROW(name, type)			\
    3.90  void name(type *src, int src_w, type *dst, int dst_w)	\
    3.91 @@ -154,8 +162,6 @@
    3.92  DEFINE_COPY_ROW(copy_row2, Uint16)
    3.93  DEFINE_COPY_ROW(copy_row4, Uint32)
    3.94  
    3.95 -#endif /* USE_ASM_STRETCH */
    3.96 -
    3.97  /* The ASM code doesn't handle 24-bpp stretch blits */
    3.98  void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w)
    3.99  {
   3.100 @@ -195,9 +201,12 @@
   3.101  	Uint8 *dstp;
   3.102  	SDL_Rect full_src;
   3.103  	SDL_Rect full_dst;
   3.104 -#if defined(USE_ASM_STRETCH) && defined(__GNUC__)
   3.105 +#ifdef USE_ASM_STRETCH
   3.106 +	SDL_bool use_asm = SDL_TRUE;
   3.107 +#ifdef __GNUC__
   3.108  	int u1, u2;
   3.109  #endif
   3.110 +#endif /* USE_ASM_STRETCH */
   3.111  	const int bpp = dst->format->BytesPerPixel;
   3.112  
   3.113  	if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) {
   3.114 @@ -266,9 +275,9 @@
   3.115  
   3.116  #ifdef USE_ASM_STRETCH
   3.117  	/* Write the opcodes for this stretch */
   3.118 -	if ( (bpp != 3) &&
   3.119 +	if ( (bpp == 3) ||
   3.120  	     (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) {
   3.121 -		return(-1);
   3.122 +		use_asm = SDL_FALSE;
   3.123  	}
   3.124  #endif
   3.125  
   3.126 @@ -283,11 +292,7 @@
   3.127  			pos -= 0x10000L;
   3.128  		}
   3.129  #ifdef USE_ASM_STRETCH
   3.130 -		switch (bpp) {
   3.131 -		    case 3:
   3.132 -			copy_row3(srcp, srcrect->w, dstp, dstrect->w);
   3.133 -			break;
   3.134 -		    default:
   3.135 +		if (use_asm) {
   3.136  #ifdef __GNUC__
   3.137  			__asm__ __volatile__ (
   3.138  			"call *%4"
   3.139 @@ -311,9 +316,8 @@
   3.140  #else
   3.141  #error Need inline assembly for this compiler
   3.142  #endif
   3.143 -			break;
   3.144 -		}
   3.145 -#else
   3.146 +		} else
   3.147 +#endif
   3.148  		switch (bpp) {
   3.149  		    case 1:
   3.150  			copy_row1(srcp, srcrect->w, dstp, dstrect->w);
   3.151 @@ -330,7 +334,6 @@
   3.152  			          (Uint32 *)dstp, dstrect->w);
   3.153  			break;
   3.154  		}
   3.155 -#endif
   3.156  		pos += inc;
   3.157  	}
   3.158