Date: Wed, 15 Sep 1999 01:57:57 +0200
From: Henrik Nordstrom <hno@HEM.PASSAGEN.SE>
Subject: Re: KKIS19990914.004b: ShareDream - shared memory - ipc
To: BUGTRAQ@SECURITYFOCUS.COM
This is a multi-part message in MIME format.
--------------33C58AFA3CE85E0572267A4
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Attached is a trivial Linux-2.2.12 patch wich adds add a procfs entry
for tuning the limit of shared memory allocable.
/proc/sys/kernel/shmmax Max number of shared memory pages
Attached is also a small hack for freeing unreferenced shared memory
pages and printing interesting details of available shared memory
segments (such as who created the segment, and when).
I am assuming others have made similar patches and tools before, but no
effective limit on shared memory exists in base Linux-2.2.12.
--
Henrik Nordstrom
Robert 'Shadow' Paj1k wrote:
[snip]
> Raport title : Shared Memory DoS - IPC vulnerability (Linux
> abuse as example)
> Problem found by : Robert Pajak (shadow@security.kki.pl),
> probably other ppl found that first - one of them is
> lcamtuf, Solar Designer is probably other...
[snip]
> This is due to fact that shared memory segments can exist without
> beeing bind with processes. To protect you should diable this
> operations, or use Solar Designer's stack patch with limits set,
> etc...
[snip]
--------------33C58AFA3CE85E0572267A4
Content-Type: text/plain; charset=us-ascii; name="ipc_limit.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="ipc_limit.patch"
--- linux/ipc/shm.c.orig Wed Sep 15 00:44:11 1999
+++ linux/ipc/shm.c Wed Sep 15 00:44:36 1999
@@ -68,6 +68,8 @@
return -1;
}
+int shmall = SHMALL;
+
/*
* allocate new shmid_kernel and pgtable. protected by shm_segs[id] = NOID.
*/
@@ -79,7 +81,7 @@
if (size < SHMMIN)
return -EINVAL;
- if (shm_tot + numpages >= SHMALL)
+ if (shm_tot + numpages >= shmall)
return -ENOSPC;
for (id = 0; id < SHMMNI; id++)
if (shm_segs[id] == IPC_UNUSED) {
@@ -233,7 +235,7 @@
shminfo.shmmni = SHMMNI;
shminfo.shmmax = shmmax;
shminfo.shmmin = SHMMIN;
- shminfo.shmall = SHMALL;
+ shminfo.shmall = shmall;
shminfo.shmseg = SHMSEG;
if(copy_to_user (buf, &shminfo, sizeof(struct shminfo)))
goto out;
--- linux/kernel/sysctl.c.orig Mon Aug 9 21:05:13 1999
+++ linux/kernel/sysctl.c Wed Sep 15 00:41:19 1999
@@ -47,6 +47,7 @@
#endif
#ifdef CONFIG_SYSVIPC
extern int shmmax;
+extern int shmall;
#endif
#ifdef __sparc__
@@ -213,6 +214,8 @@
0644, NULL, &proc_dointvec},
#ifdef CONFIG_SYSVIPC
{KERN_SHMMAX, "shmmax", &shmmax, sizeof (int),
+ 0644, NULL, &proc_dointvec},
+ {KERN_SHMMAX, "shmall", &shmall, sizeof (int),
0644, NULL, &proc_dointvec},
#endif
#ifdef CONFIG_MAGIC_SYSRQ
--------------33C58AFA3CE85E0572267A4
Content-Type: text/plain; charset=us-ascii; name="free_shmem.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="free_shmem.c"
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <time.h>
int main(void)
{
int i, id;
struct shminfo shmi;
struct shmid_ds sds;
shmctl(0, IPC_INFO, (void *)&shmi);
for(i=0; i<shmi.shmmni;i++) {
if ((id = shmctl(i, SHM_STAT, &sds)) >= 0) {
printf("SHM %d: size=%d cuid=%d cgid=%d cpid=%d lpid=%d uses=%d created %s",
id, sds.shm_segsz, sds.shm_perm.cuid, sds.shm_perm.cgid,
sds.shm_cpid, sds.shm_lpid, sds.shm_nattch,
ctime(&sds.shm_ctime));
if (sds.shm_nattch == 0) {
shmctl(id, IPC_RMID, NULL);
printf("SHM segment %d freed\n", id);
}
}
}
return 0;
}
--------------33C58AFA3CE85E0572267A4--