Subject: Re: KKIS19990914.004b: ShareDream - shared memory - ipc vulnerability To: BUGTRAQ@SECURITYFOCUS.COM 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] --- 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 #include #include #include #include int main(void) { int i, id; struct shminfo shmi; struct shmid_ds sds; shmctl(0, IPC_INFO, (void *)&shmi); for(i=0; i= 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; }