Bugtraq mailing list archives

Re: KKIS19990914.004b: ShareDream - shared memory - ipc vulnerability


From: hno () HEM PASSAGEN SE (Henrik Nordstrom)
Date: Wed, 15 Sep 1999 01:57:57 +0200


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 <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;
}



Current thread: