linux/ipc/ipc_sysctl.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2007
   3 *
   4 *  Author: Eric Biederman <ebiederm@xmision.com>
   5 *
   6 *  This program is free software; you can redistribute it and/or
   7 *  modify it under the terms of the GNU General Public License as
   8 *  published by the Free Software Foundation, version 2 of the
   9 *  License.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/ipc.h>
  14#include <linux/nsproxy.h>
  15#include <linux/sysctl.h>
  16#include <linux/uaccess.h>
  17
  18#ifdef CONFIG_IPC_NS
  19static void *get_ipc(ctl_table *table)
  20{
  21        char *which = table->data;
  22        struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
  23        which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
  24        return which;
  25}
  26#else
  27#define get_ipc(T) ((T)->data)
  28#endif
  29
  30#ifdef CONFIG_PROC_FS
  31static int proc_ipc_dointvec(ctl_table *table, int write, struct file *filp,
  32        void __user *buffer, size_t *lenp, loff_t *ppos)
  33{
  34        struct ctl_table ipc_table;
  35        memcpy(&ipc_table, table, sizeof(ipc_table));
  36        ipc_table.data = get_ipc(table);
  37
  38        return proc_dointvec(&ipc_table, write, filp, buffer, lenp, ppos);
  39}
  40
  41static int proc_ipc_doulongvec_minmax(ctl_table *table, int write,
  42        struct file *filp, void __user *buffer, size_t *lenp, loff_t *ppos)
  43{
  44        struct ctl_table ipc_table;
  45        memcpy(&ipc_table, table, sizeof(ipc_table));
  46        ipc_table.data = get_ipc(table);
  47
  48        return proc_doulongvec_minmax(&ipc_table, write, filp, buffer,
  49                                        lenp, ppos);
  50}
  51
  52#else
  53#define proc_ipc_doulongvec_minmax NULL
  54#define proc_ipc_dointvec          NULL
  55#endif
  56
  57#ifdef CONFIG_SYSCTL_SYSCALL
  58/* The generic sysctl ipc data routine. */
  59static int sysctl_ipc_data(ctl_table *table, int __user *name, int nlen,
  60                void __user *oldval, size_t __user *oldlenp,
  61                void __user *newval, size_t newlen)
  62{
  63        size_t len;
  64        void *data;
  65
  66        /* Get out of I don't have a variable */
  67        if (!table->data || !table->maxlen)
  68                return -ENOTDIR;
  69
  70        data = get_ipc(table);
  71        if (!data)
  72                return -ENOTDIR;
  73
  74        if (oldval && oldlenp) {
  75                if (get_user(len, oldlenp))
  76                        return -EFAULT;
  77                if (len) {
  78                        if (len > table->maxlen)
  79                                len = table->maxlen;
  80                        if (copy_to_user(oldval, data, len))
  81                                return -EFAULT;
  82                        if (put_user(len, oldlenp))
  83                                return -EFAULT;
  84                }
  85        }
  86
  87        if (newval && newlen) {
  88                if (newlen > table->maxlen)
  89                        newlen = table->maxlen;
  90
  91                if (copy_from_user(data, newval, newlen))
  92                        return -EFAULT;
  93        }
  94        return 1;
  95}
  96#else
  97#define sysctl_ipc_data NULL
  98#endif
  99
 100static struct ctl_table ipc_kern_table[] = {
 101        {
 102                .ctl_name       = KERN_SHMMAX,
 103                .procname       = "shmmax",
 104                .data           = &init_ipc_ns.shm_ctlmax,
 105                .maxlen         = sizeof (init_ipc_ns.shm_ctlmax),
 106                .mode           = 0644,
 107                .proc_handler   = proc_ipc_doulongvec_minmax,
 108                .strategy       = sysctl_ipc_data,
 109        },
 110        {
 111                .ctl_name       = KERN_SHMALL,
 112                .procname       = "shmall",
 113                .data           = &init_ipc_ns.shm_ctlall,
 114                .maxlen         = sizeof (init_ipc_ns.shm_ctlall),
 115                .mode           = 0644,
 116                .proc_handler   = proc_ipc_doulongvec_minmax,
 117                .strategy       = sysctl_ipc_data,
 118        },
 119        {
 120                .ctl_name       = KERN_SHMMNI,
 121                .procname       = "shmmni",
 122                .data           = &init_ipc_ns.shm_ctlmni,
 123                .maxlen         = sizeof (init_ipc_ns.shm_ctlmni),
 124                .mode           = 0644,
 125                .proc_handler   = proc_ipc_dointvec,
 126                .strategy       = sysctl_ipc_data,
 127        },
 128        {
 129                .ctl_name       = KERN_MSGMAX,
 130                .procname       = "msgmax",
 131                .data           = &init_ipc_ns.msg_ctlmax,
 132                .maxlen         = sizeof (init_ipc_ns.msg_ctlmax),
 133                .mode           = 0644,
 134                .proc_handler   = proc_ipc_dointvec,
 135                .strategy       = sysctl_ipc_data,
 136        },
 137        {
 138                .ctl_name       = KERN_MSGMNI,
 139                .procname       = "msgmni",
 140                .data           = &init_ipc_ns.msg_ctlmni,
 141                .maxlen         = sizeof (init_ipc_ns.msg_ctlmni),
 142                .mode           = 0644,
 143                .proc_handler   = proc_ipc_dointvec,
 144                .strategy       = sysctl_ipc_data,
 145        },
 146        {
 147                .ctl_name       = KERN_MSGMNB,
 148                .procname       =  "msgmnb",
 149                .data           = &init_ipc_ns.msg_ctlmnb,
 150                .maxlen         = sizeof (init_ipc_ns.msg_ctlmnb),
 151                .mode           = 0644,
 152                .proc_handler   = proc_ipc_dointvec,
 153                .strategy       = sysctl_ipc_data,
 154        },
 155        {
 156                .ctl_name       = KERN_SEM,
 157                .procname       = "sem",
 158                .data           = &init_ipc_ns.sem_ctls,
 159                .maxlen         = 4*sizeof (int),
 160                .mode           = 0644,
 161                .proc_handler   = proc_ipc_dointvec,
 162                .strategy       = sysctl_ipc_data,
 163        },
 164        {}
 165};
 166
 167static struct ctl_table ipc_root_table[] = {
 168        {
 169                .ctl_name       = CTL_KERN,
 170                .procname       = "kernel",
 171                .mode           = 0555,
 172                .child          = ipc_kern_table,
 173        },
 174        {}
 175};
 176
 177static int __init ipc_sysctl_init(void)
 178{
 179        register_sysctl_table(ipc_root_table);
 180        return 0;
 181}
 182
 183__initcall(ipc_sysctl_init);
 184
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.