diff --git a/src/header/stdlib/mod.rs b/src/header/stdlib/mod.rs
index eb157f70fc0e41584b6c8ebe1e9bea0e46db9e95..b1170693b6bf85749d61da9923ecac17bce9ef24 100644
--- a/src/header/stdlib/mod.rs
+++ b/src/header/stdlib/mod.rs
@@ -1,7 +1,7 @@
 //! stdlib implementation for Redox, following http://pubs.opengroup.org/onlinepubs/7908799/xsh/stdlib.h.html
 
-use core::{intrinsics, iter, mem, ptr, slice};
 use core::convert::TryFrom;
+use core::{intrinsics, iter, mem, ptr, slice};
 use rand::distributions::{Alphanumeric, Distribution, Uniform};
 use rand::prng::XorShiftRng;
 use rand::rngs::JitterRng;
@@ -582,6 +582,31 @@ pub extern "C" fn nrand48(xsubi: [c_ushort; 3]) -> c_long {
     unimplemented!();
 }
 
+#[no_mangle]
+pub unsafe extern "C" fn posix_memalign(
+    memptr: *mut *mut c_void,
+    alignment: size_t,
+    size: size_t,
+) -> c_int {
+    const void_ptr_size: usize = mem::size_of::<*mut c_void>();
+
+    /* Check that alignment is:
+     * a) a multiple of sizeof(void *)
+     * b) a power-of-two multiple of sizeof(void *). Integer division as
+     *    below gives the correct result once a) is ensured. */
+    if alignment % void_ptr_size == 0 && (alignment / void_ptr_size).is_power_of_two() {
+        let ptr = platform::alloc_align(size, alignment);
+        if !ptr.is_null() {
+            *memptr = ptr;
+            0
+        } else {
+            ENOMEM
+        }
+    } else {
+        EINVAL
+    }
+}
+
 // #[no_mangle]
 pub extern "C" fn ptsname(fildes: c_int) -> *mut c_char {
     unimplemented!();
diff --git a/tests/stdlib/alloc.c b/tests/stdlib/alloc.c
index 4089262fad5c88bd62c37babde91a978bca2bcce..c2353fdefa57908b41879c1a52fc1e633f1dad09 100644
--- a/tests/stdlib/alloc.c
+++ b/tests/stdlib/alloc.c
@@ -12,10 +12,13 @@ int main(void) {
     size_t sample_realloc_size = sample_alloc_size + 1;
     
     /* ensure values are mapped to variables */
+    size_t zero = 0;
     size_t max_size = SIZE_MAX;
     size_t aligned_alloc_alignment = 128;
     size_t aligned_alloc_goodsize = 256;
     size_t aligned_alloc_badsize = 257;
+    size_t nonpow2_mul_voidptr_size = 3*sizeof(void *);
+    size_t pow2_mul_voidptr_size = 4*sizeof(void *);
     
     int i;
     
@@ -139,4 +142,74 @@ int main(void) {
     printf("valloc (SIZE_MAX)     : %p, errno: %d = %s\n",
         ptr_valloc_maxsize, valloc_maxsize_errno,
         strerror(valloc_maxsize_errno));
+    
+    errno = 0;
+    void * ptr_posix_memalign = NULL;
+    int posix_memalign_return = posix_memalign(&ptr_posix_memalign, pow2_mul_voidptr_size, sample_alloc_size);
+    int posix_memalign_errno = errno;
+    printf("posix_memalign:\n");
+    printf("                        %p, return value: %d = %s,\n",
+        ptr_posix_memalign,
+        posix_memalign_return, strerror(posix_memalign_return));
+    /* strerror() can only be called once in a printf call for correct
+     * results */
+    printf("                        errno: %d = %s\n",
+        posix_memalign_errno,
+        strerror(posix_memalign_errno));
+    
+    errno = 0;
+    void * ptr_posix_memalign_align0 = NULL;
+    int posix_memalign_align0_return = posix_memalign(&ptr_posix_memalign_align0, zero, sample_alloc_size);
+    int posix_memalign_align0_errno = errno;
+    printf("posix_memalign (alignment 0):\n");
+    printf("                        %p, return value: %d = %s,\n",
+        ptr_posix_memalign_align0,
+        posix_memalign_align0_return,
+        strerror(posix_memalign_align0_return));
+    
+    printf("                        errno: %d = %s\n",
+        posix_memalign_align0_errno,
+        strerror(posix_memalign_align0_errno));
+    
+    errno = 0;
+    void * ptr_posix_memalign_nonpow2mul = NULL;
+    int posix_memalign_nonpow2mul_return = posix_memalign(&ptr_posix_memalign_nonpow2mul, nonpow2_mul_voidptr_size, sample_alloc_size);
+    int posix_memalign_nonpow2mul_errno = errno;
+    printf("posix_memalign (non-power-of-two multiple of sizeof(void *)):\n");
+    printf("                        %p, return value: %d = %s,\n",
+        ptr_posix_memalign_nonpow2mul,
+        posix_memalign_nonpow2mul_return,
+        strerror(posix_memalign_nonpow2mul_return));
+    
+    printf("                        errno: %d = %s\n",
+        posix_memalign_nonpow2mul_errno,
+        strerror(posix_memalign_nonpow2mul_errno));
+    
+    errno = 0;
+    void * ptr_posix_memalign_size0 = NULL;
+    int posix_memalign_size0_return = posix_memalign(&ptr_posix_memalign_size0, pow2_mul_voidptr_size, zero);
+    int posix_memalign_size0_errno = errno;
+    printf("posix_memalign (size 0):\n");
+    printf("                        %p, return value: %d = %s,\n",
+        ptr_posix_memalign_size0,
+        posix_memalign_size0_return,
+        strerror(posix_memalign_size0_return));
+    
+    printf("                        errno: %d = %s\n",
+        posix_memalign_size0_errno,
+        strerror(posix_memalign_size0_errno));
+    
+    errno = 0;
+    void * ptr_posix_memalign_maxsize = NULL;
+    int posix_memalign_maxsize_return = posix_memalign(&ptr_posix_memalign_maxsize, pow2_mul_voidptr_size, max_size);
+    int posix_memalign_maxsize_errno = errno;
+    printf("posix_memalign (SIZE_MAX):\n");
+    printf("                        %p, return value: %d = %s,\n",
+        ptr_posix_memalign_maxsize,
+        posix_memalign_maxsize_return,
+        strerror(posix_memalign_maxsize_return));
+    
+    printf("                        errno: %d = %s\n",
+        posix_memalign_maxsize_errno,
+        strerror(posix_memalign_maxsize_errno));
 }