Re: OT: howto remove SHM that was attached by shmat

Marc-Christian Petersen <[email protected]> Sat, 17 Apr 2004 17:58:41 +0200
Newsgroups gmane.linux.wolk.devel
Organization Working Overloaded Linux Kernel
Message-ID <200404171758.41747@WOLK>
On Saturday 17 April 2004 17:29, Marc-Christian Petersen wrote:

Hi again,

> Attached a patch ontop of 2.4.20-WOLK4.14s. Patch untested yet. Compiles at
> least. This stuff is also in 2.2-secure for ages. And now I ask myself why
> I didn't merge that into 2.4-WOLK earlier. I'll forward port it to 2.6-WOLK
> in the next minutes ...

ok, that patch is bogus. Attached one actually works :)

ciao, Marc
grsecurity-1.9.14+-harden-shm-from-openwall-v2.patch (text/x-diff, 3.7 KB)
--- old/Documentation/Configure.help	2004-04-02 00:01:13.000000000 +0200
+++ new/Documentation/Configure.help	2004-04-17 17:22:11.000000000 +0200
@@ -26758,6 +26758,22 @@ CONFIG_GRKERNSEC_TPE_ALL
   root.  If the sysctl option is enabled, a sysctl option with name 
   "tpe_restrict_all" is created.
 
+Destroy shared memory segments not in use
+CONFIG_GRKERNSEC_HARDEN_SHM
+  Linux lets you set resource limits, including on how much memory one
+  process can consume, via setrlimit(2). Unfortunately, shared memory
+  segments are allowed to exist without association with any process,
+  and thus might not be counted against any resource limits. This option
+  automatically destroys shared memory segments when their attach count
+  becomes zero after a detach or a process termination. It will also
+  destroy segments that were created, but never attached to, on exit from
+  the process. (In case you're curious, the only use left for IPC_RMID is
+  to immediately destroy an unattached segment.) Of course, this breaks
+  the way things are defined, so some applications might stop working.
+  Note that this feature will do you no good unless you also configure
+  your resource limits (in particular, RLIMIT_AS and RLIMIT_NPROC). Most
+  systems don't need this.
+
 Randomized PIDs
 CONFIG_GRKERNSEC_RANDPID
   If you say Y here, all PIDs created on the system will be
--- old/ipc/shm.c	Sat Aug  3 00:39:46 2002
+++ new/ipc/shm.c	Sat Apr 17 02:13:55 2004
@@ -212,14 +212,41 @@ static void shm_close (struct vm_area_st
 	shp->shm_lprid = current->pid;
 	shp->shm_dtim = CURRENT_TIME;
 	shp->shm_nattch--;
+#ifdef CONFIG_GRKERNSEC_HARDEN_SHM
+	if(shp->shm_nattch == 0) {
+		shp->shm_flags |= SHM_DEST;
+		shm_destroy (shp);
+	}
+#else
 	if(shp->shm_nattch == 0 &&
 	   shp->shm_flags & SHM_DEST)
 		shm_destroy (shp);
+#endif
 	else
 		shm_unlock(id);
 	up (&shm_ids.sem);
 }
 
+#ifdef CONFIG_GRKERNSEC_HARDEN_SHM
+void shm_exit (void)
+{
+	int i;
+	struct shmid_kernel *shp;
+
+	for (i = 0; i <= shm_ids.max_id; i++) {
+		shp = shm_get(i);
+		if (!shp) continue;
+
+		if (shp->shm_cprid != current->pid) continue;
+
+		if (shp->shm_nattch <= 0) {
+			shp->shm_flags |= SHM_DEST;
+			shm_destroy (shp);
+		}
+	}
+}
+#endif
+
 static int shm_mmap(struct file * file, struct vm_area_struct * vma)
 {
 #if defined (CONFIG_SHM_LARGEPAGE)
--- old/ipc/util.c	Mon Aug 25 11:44:44 2003
+++ new/ipc/util.c	Sat Apr 17 02:13:55 2004
@@ -352,9 +352,16 @@ int ipc_parse_version (int *cmd)
 
 void sem_exit (void)
 {
-    return;
+	return;
 }
 
+#ifdef CONFIG_GRKERNSEC_HARDEN_SHM
+void shm_exit (void)
+{
+	return;
+}
+#endif
+
 asmlinkage long sys_semget (key_t key, int nsems, int semflg)
 {
 	return -ENOSYS;
--- old/kernel/exit.c	Thu Nov 28 23:53:15 2002
+++ new/kernel/exit.c	Sat Apr 17 02:13:55 2004
@@ -34,6 +34,9 @@
 #endif
 
 extern void sem_exit (void);
+#ifdef CONFIG_GRKERNSEC_HARDEN_SHM
+extern void shm_exit (void);
+#endif
 extern struct task_struct *child_reaper;
 
 int sysctl_warn_preempt = 1;		/* Warn about preempted tasks still holding locks */
@@ -606,6 +609,9 @@ fake_volatile:
 
 	lock_kernel();
 	sem_exit();
+#ifdef CONFIG_GRKERNSEC_HARDEN_SHM
+	shm_exit();
+#endif
 	__exit_files(tsk);
 	__exit_fs(tsk);
 	exit_namespace(tsk);
--- old/grsecurity/Config.in	2004-03-16 16:45:47.000000000 +0100
+++ new/grsecurity/Config.in	2004-04-17 17:18:57.000000000 +0200
@@ -363,6 +363,9 @@ if [ "$CONFIG_GRKERNSEC_TPE" != "n" ]; t
 bool '   Partially restrict non-root users' CONFIG_GRKERNSEC_TPE_ALL
 int  '   GID for untrusted users:' CONFIG_GRKERNSEC_TPE_GID 1005
 fi
+if [ "$CONFIG_SYSVIPC" = "y" ]; then
+bool 'Destroy shared memory segments not in use' CONFIG_GRKERNSEC_HARDEN_SHM
+fi
 endmenu
 mainmenu_option next_comment
 comment 'Network Protections'