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 ([EMAIL PROTECTED]),
>                        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;
}

Reply via email to