root/ipc/ipc_sysctl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_ipc
  2. proc_ipc_dointvec
  3. proc_ipc_dointvec_minmax
  4. proc_ipc_dointvec_minmax_orphans
  5. proc_ipc_doulongvec_minmax
  6. proc_ipc_auto_msgmni
  7. proc_ipc_sem_dointvec
  8. ipc_sysctl_init
  9. ipc_mni_extend

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Copyright (C) 2007
   4  *
   5  *  Author: Eric Biederman <ebiederm@xmision.com>
   6  */
   7 
   8 #include <linux/module.h>
   9 #include <linux/ipc.h>
  10 #include <linux/nsproxy.h>
  11 #include <linux/sysctl.h>
  12 #include <linux/uaccess.h>
  13 #include <linux/ipc_namespace.h>
  14 #include <linux/msg.h>
  15 #include "util.h"
  16 
  17 static void *get_ipc(struct ctl_table *table)
  18 {
  19         char *which = table->data;
  20         struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
  21         which = (which - (char *)&init_ipc_ns) + (char *)ipc_ns;
  22         return which;
  23 }
  24 
  25 #ifdef CONFIG_PROC_SYSCTL
  26 static int proc_ipc_dointvec(struct ctl_table *table, int write,
  27         void __user *buffer, size_t *lenp, loff_t *ppos)
  28 {
  29         struct ctl_table ipc_table;
  30 
  31         memcpy(&ipc_table, table, sizeof(ipc_table));
  32         ipc_table.data = get_ipc(table);
  33 
  34         return proc_dointvec(&ipc_table, write, buffer, lenp, ppos);
  35 }
  36 
  37 static int proc_ipc_dointvec_minmax(struct ctl_table *table, int write,
  38         void __user *buffer, size_t *lenp, loff_t *ppos)
  39 {
  40         struct ctl_table ipc_table;
  41 
  42         memcpy(&ipc_table, table, sizeof(ipc_table));
  43         ipc_table.data = get_ipc(table);
  44 
  45         return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
  46 }
  47 
  48 static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write,
  49         void __user *buffer, size_t *lenp, loff_t *ppos)
  50 {
  51         struct ipc_namespace *ns = current->nsproxy->ipc_ns;
  52         int err = proc_ipc_dointvec_minmax(table, write, buffer, lenp, ppos);
  53 
  54         if (err < 0)
  55                 return err;
  56         if (ns->shm_rmid_forced)
  57                 shm_destroy_orphaned(ns);
  58         return err;
  59 }
  60 
  61 static int proc_ipc_doulongvec_minmax(struct ctl_table *table, int write,
  62         void __user *buffer, size_t *lenp, loff_t *ppos)
  63 {
  64         struct ctl_table ipc_table;
  65         memcpy(&ipc_table, table, sizeof(ipc_table));
  66         ipc_table.data = get_ipc(table);
  67 
  68         return proc_doulongvec_minmax(&ipc_table, write, buffer,
  69                                         lenp, ppos);
  70 }
  71 
  72 static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,
  73         void __user *buffer, size_t *lenp, loff_t *ppos)
  74 {
  75         struct ctl_table ipc_table;
  76         int dummy = 0;
  77 
  78         memcpy(&ipc_table, table, sizeof(ipc_table));
  79         ipc_table.data = &dummy;
  80 
  81         if (write)
  82                 pr_info_once("writing to auto_msgmni has no effect");
  83 
  84         return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
  85 }
  86 
  87 static int proc_ipc_sem_dointvec(struct ctl_table *table, int write,
  88         void __user *buffer, size_t *lenp, loff_t *ppos)
  89 {
  90         int ret, semmni;
  91         struct ipc_namespace *ns = current->nsproxy->ipc_ns;
  92 
  93         semmni = ns->sem_ctls[3];
  94         ret = proc_ipc_dointvec(table, write, buffer, lenp, ppos);
  95 
  96         if (!ret)
  97                 ret = sem_check_semmni(current->nsproxy->ipc_ns);
  98 
  99         /*
 100          * Reset the semmni value if an error happens.
 101          */
 102         if (ret)
 103                 ns->sem_ctls[3] = semmni;
 104         return ret;
 105 }
 106 
 107 #else
 108 #define proc_ipc_doulongvec_minmax NULL
 109 #define proc_ipc_dointvec          NULL
 110 #define proc_ipc_dointvec_minmax   NULL
 111 #define proc_ipc_dointvec_minmax_orphans   NULL
 112 #define proc_ipc_auto_msgmni       NULL
 113 #define proc_ipc_sem_dointvec      NULL
 114 #endif
 115 
 116 int ipc_mni = IPCMNI;
 117 int ipc_mni_shift = IPCMNI_SHIFT;
 118 int ipc_min_cycle = RADIX_TREE_MAP_SIZE;
 119 
 120 static struct ctl_table ipc_kern_table[] = {
 121         {
 122                 .procname       = "shmmax",
 123                 .data           = &init_ipc_ns.shm_ctlmax,
 124                 .maxlen         = sizeof(init_ipc_ns.shm_ctlmax),
 125                 .mode           = 0644,
 126                 .proc_handler   = proc_ipc_doulongvec_minmax,
 127         },
 128         {
 129                 .procname       = "shmall",
 130                 .data           = &init_ipc_ns.shm_ctlall,
 131                 .maxlen         = sizeof(init_ipc_ns.shm_ctlall),
 132                 .mode           = 0644,
 133                 .proc_handler   = proc_ipc_doulongvec_minmax,
 134         },
 135         {
 136                 .procname       = "shmmni",
 137                 .data           = &init_ipc_ns.shm_ctlmni,
 138                 .maxlen         = sizeof(init_ipc_ns.shm_ctlmni),
 139                 .mode           = 0644,
 140                 .proc_handler   = proc_ipc_dointvec_minmax,
 141                 .extra1         = SYSCTL_ZERO,
 142                 .extra2         = &ipc_mni,
 143         },
 144         {
 145                 .procname       = "shm_rmid_forced",
 146                 .data           = &init_ipc_ns.shm_rmid_forced,
 147                 .maxlen         = sizeof(init_ipc_ns.shm_rmid_forced),
 148                 .mode           = 0644,
 149                 .proc_handler   = proc_ipc_dointvec_minmax_orphans,
 150                 .extra1         = SYSCTL_ZERO,
 151                 .extra2         = SYSCTL_ONE,
 152         },
 153         {
 154                 .procname       = "msgmax",
 155                 .data           = &init_ipc_ns.msg_ctlmax,
 156                 .maxlen         = sizeof(init_ipc_ns.msg_ctlmax),
 157                 .mode           = 0644,
 158                 .proc_handler   = proc_ipc_dointvec_minmax,
 159                 .extra1         = SYSCTL_ZERO,
 160                 .extra2         = SYSCTL_INT_MAX,
 161         },
 162         {
 163                 .procname       = "msgmni",
 164                 .data           = &init_ipc_ns.msg_ctlmni,
 165                 .maxlen         = sizeof(init_ipc_ns.msg_ctlmni),
 166                 .mode           = 0644,
 167                 .proc_handler   = proc_ipc_dointvec_minmax,
 168                 .extra1         = SYSCTL_ZERO,
 169                 .extra2         = &ipc_mni,
 170         },
 171         {
 172                 .procname       = "auto_msgmni",
 173                 .data           = NULL,
 174                 .maxlen         = sizeof(int),
 175                 .mode           = 0644,
 176                 .proc_handler   = proc_ipc_auto_msgmni,
 177                 .extra1         = SYSCTL_ZERO,
 178                 .extra2         = SYSCTL_ONE,
 179         },
 180         {
 181                 .procname       =  "msgmnb",
 182                 .data           = &init_ipc_ns.msg_ctlmnb,
 183                 .maxlen         = sizeof(init_ipc_ns.msg_ctlmnb),
 184                 .mode           = 0644,
 185                 .proc_handler   = proc_ipc_dointvec_minmax,
 186                 .extra1         = SYSCTL_ZERO,
 187                 .extra2         = SYSCTL_INT_MAX,
 188         },
 189         {
 190                 .procname       = "sem",
 191                 .data           = &init_ipc_ns.sem_ctls,
 192                 .maxlen         = 4*sizeof(int),
 193                 .mode           = 0644,
 194                 .proc_handler   = proc_ipc_sem_dointvec,
 195         },
 196 #ifdef CONFIG_CHECKPOINT_RESTORE
 197         {
 198                 .procname       = "sem_next_id",
 199                 .data           = &init_ipc_ns.ids[IPC_SEM_IDS].next_id,
 200                 .maxlen         = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id),
 201                 .mode           = 0644,
 202                 .proc_handler   = proc_ipc_dointvec_minmax,
 203                 .extra1         = SYSCTL_ZERO,
 204                 .extra2         = SYSCTL_INT_MAX,
 205         },
 206         {
 207                 .procname       = "msg_next_id",
 208                 .data           = &init_ipc_ns.ids[IPC_MSG_IDS].next_id,
 209                 .maxlen         = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id),
 210                 .mode           = 0644,
 211                 .proc_handler   = proc_ipc_dointvec_minmax,
 212                 .extra1         = SYSCTL_ZERO,
 213                 .extra2         = SYSCTL_INT_MAX,
 214         },
 215         {
 216                 .procname       = "shm_next_id",
 217                 .data           = &init_ipc_ns.ids[IPC_SHM_IDS].next_id,
 218                 .maxlen         = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id),
 219                 .mode           = 0644,
 220                 .proc_handler   = proc_ipc_dointvec_minmax,
 221                 .extra1         = SYSCTL_ZERO,
 222                 .extra2         = SYSCTL_INT_MAX,
 223         },
 224 #endif
 225         {}
 226 };
 227 
 228 static struct ctl_table ipc_root_table[] = {
 229         {
 230                 .procname       = "kernel",
 231                 .mode           = 0555,
 232                 .child          = ipc_kern_table,
 233         },
 234         {}
 235 };
 236 
 237 static int __init ipc_sysctl_init(void)
 238 {
 239         register_sysctl_table(ipc_root_table);
 240         return 0;
 241 }
 242 
 243 device_initcall(ipc_sysctl_init);
 244 
 245 static int __init ipc_mni_extend(char *str)
 246 {
 247         ipc_mni = IPCMNI_EXTEND;
 248         ipc_mni_shift = IPCMNI_EXTEND_SHIFT;
 249         ipc_min_cycle = IPCMNI_EXTEND_MIN_CYCLE;
 250         pr_info("IPCMNI extended to %d.\n", ipc_mni);
 251         return 0;
 252 }
 253 early_param("ipcmni_extend", ipc_mni_extend);

/* [<][>][^][v][top][bottom][index][help] */