Index: kernel/generic/src/console/console.c
===================================================================
--- kernel/generic/src/console/console.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/console/console.c	(revision 104776019e8c3fcfc0545665cd8f58eea101d0ca)
@@ -160,4 +160,5 @@
 	klog_parea.pbase = (uintptr_t) faddr;
 	klog_parea.frames = SIZE2FRAMES(sizeof(klog));
+	klog_parea.unpriv = false;
 	ddi_parea_register(&klog_parea);
 	
Index: kernel/generic/src/ddi/ddi.c
===================================================================
--- kernel/generic/src/ddi/ddi.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/ddi/ddi.c	(revision 104776019e8c3fcfc0545665cd8f58eea101d0ca)
@@ -104,13 +104,17 @@
 {
 	ASSERT(TASK);
-	ASSERT((pf % FRAME_SIZE) == 0);
-	ASSERT((vp % PAGE_SIZE) == 0);
-	
-	/*
-	 * Make sure the caller is authorised to make this syscall.
-	 */
-	cap_t caps = cap_get(TASK);
-	if (!(caps & CAP_MEM_MANAGER))
-		return EPERM;
+	
+	if ((pf % FRAME_SIZE) != 0)
+		return EBADMEM;
+	
+	if ((vp % PAGE_SIZE) != 0)
+		return EBADMEM;
+	
+	/*
+	 * Unprivileged tasks are only allowed to map pareas
+	 * which are explicitly marked as such.
+	 */
+	bool priv =
+	    ((cap_get(TASK) & CAP_MEM_MANAGER) == CAP_MEM_MANAGER);
 	
 	mem_backend_data_t backend_data;
@@ -123,14 +127,27 @@
 	
 	if (znum == (size_t) -1) {
-		/* Frames not found in any zones
-		 * -> assume it is hardware device and allow mapping
+		/*
+		 * Frames not found in any zone
+		 * -> assume it is a hardware device and allow mapping
+		 *    for privileged tasks.
 		 */
 		irq_spinlock_unlock(&zones.lock, true);
+		
+		if (!priv)
+			return EPERM;
+		
 		goto map;
 	}
 	
 	if (zones.info[znum].flags & ZONE_FIRMWARE) {
-		/* Frames are part of firmware */
+		/*
+		 * Frames are part of firmware
+		 * -> allow mapping for privileged tasks.
+		 */
 		irq_spinlock_unlock(&zones.lock, true);
+		
+		if (!priv)
+			return EPERM;
+		
 		goto map;
 	}
@@ -138,6 +155,6 @@
 	if (zone_flags_available(zones.info[znum].flags)) {
 		/*
-		 * Frames are part of physical memory, check if the memory
-		 * region is enabled for mapping.
+		 * Frames are part of physical memory, check
+		 * if the memory region is enabled for mapping.
 		 */
 		irq_spinlock_unlock(&zones.lock, true);
@@ -150,5 +167,12 @@
 		if ((!parea) || (parea->frames < pages)) {
 			mutex_unlock(&parea_lock);
-			goto err;
+			return ENOENT;
+		}
+		
+		if (!priv) {
+			if (!parea->unpriv) {
+				mutex_unlock(&parea_lock);
+				return EPERM;
+			}
 		}
 		
@@ -158,6 +182,4 @@
 	
 	irq_spinlock_unlock(&zones.lock, true);
-	
-err:
 	return ENOENT;
 	
Index: kernel/generic/src/lib/rd.c
===================================================================
--- kernel/generic/src/lib/rd.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/lib/rd.c	(revision 104776019e8c3fcfc0545665cd8f58eea101d0ca)
@@ -90,4 +90,5 @@
 	    FRAME_SIZE);
 	rd_parea.frames = SIZE2FRAMES(dsize);
+	rd_parea.unpriv = false;
 	ddi_parea_register(&rd_parea);
 
Index: kernel/generic/src/time/clock.c
===================================================================
--- kernel/generic/src/time/clock.c	(revision 8add9ca54eed14da25f4bda28ab137bf14388de8)
+++ kernel/generic/src/time/clock.c	(revision 104776019e8c3fcfc0545665cd8f58eea101d0ca)
@@ -93,4 +93,5 @@
 	clock_parea.pbase = (uintptr_t) faddr;
 	clock_parea.frames = 1;
+	clock_parea.unpriv = true;
 	ddi_parea_register(&clock_parea);
 	
@@ -100,5 +101,4 @@
 	 *
 	 */
-	sysinfo_set_item_val("clock.cacheable", NULL, (sysarg_t) true);
 	sysinfo_set_item_val("clock.faddr", NULL, (sysarg_t) faddr);
 }
