1b886d83cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2a5494dcdSEric W. Biederman /* 3a5494dcdSEric W. Biederman * Copyright (C) 2007 4a5494dcdSEric W. Biederman * 5a5494dcdSEric W. Biederman * Author: Eric Biederman <ebiederm@xmision.com> 6a5494dcdSEric W. Biederman */ 7a5494dcdSEric W. Biederman 8a5494dcdSEric W. Biederman #include <linux/module.h> 9a5494dcdSEric W. Biederman #include <linux/ipc.h> 10a5494dcdSEric W. Biederman #include <linux/nsproxy.h> 11a5494dcdSEric W. Biederman #include <linux/sysctl.h> 12a5494dcdSEric W. Biederman #include <linux/uaccess.h> 135563cabdSMichal Clapinski #include <linux/capability.h> 14ae5e1b22SPavel Emelyanov #include <linux/ipc_namespace.h> 156546bc42SNadia Derbey #include <linux/msg.h> 161f5c135eSAlexey Gladkov #include <linux/slab.h> 17*8d5b1a9fSAlexey Gladkov #include <linux/cred.h> 186546bc42SNadia Derbey #include "util.h" 19a5494dcdSEric W. Biederman 20a5c5928bSJoe Perches static int proc_ipc_dointvec_minmax_orphans(struct ctl_table *table, int write, 2132927393SChristoph Hellwig void *buffer, size_t *lenp, loff_t *ppos) 22b34a6b1dSVasiliy Kulikov { 23dd141a49SAlexey Gladkov struct ipc_namespace *ns = 24dd141a49SAlexey Gladkov container_of(table->data, struct ipc_namespace, shm_rmid_forced); 251f5c135eSAlexey Gladkov int err; 261f5c135eSAlexey Gladkov 27dd141a49SAlexey Gladkov err = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 28b34a6b1dSVasiliy Kulikov 29b34a6b1dSVasiliy Kulikov if (err < 0) 30b34a6b1dSVasiliy Kulikov return err; 31b34a6b1dSVasiliy Kulikov if (ns->shm_rmid_forced) 32b34a6b1dSVasiliy Kulikov shm_destroy_orphaned(ns); 33b34a6b1dSVasiliy Kulikov return err; 34b34a6b1dSVasiliy Kulikov } 35b34a6b1dSVasiliy Kulikov 360050ee05SManfred Spraul static int proc_ipc_auto_msgmni(struct ctl_table *table, int write, 3732927393SChristoph Hellwig void *buffer, size_t *lenp, loff_t *ppos) 389eefe520SNadia Derbey { 399eefe520SNadia Derbey struct ctl_table ipc_table; 400050ee05SManfred Spraul int dummy = 0; 419eefe520SNadia Derbey 429eefe520SNadia Derbey memcpy(&ipc_table, table, sizeof(ipc_table)); 430050ee05SManfred Spraul ipc_table.data = &dummy; 449eefe520SNadia Derbey 450050ee05SManfred Spraul if (write) 460050ee05SManfred Spraul pr_info_once("writing to auto_msgmni has no effect"); 479eefe520SNadia Derbey 480050ee05SManfred Spraul return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos); 499eefe520SNadia Derbey } 509eefe520SNadia Derbey 518c81ddd2SWaiman Long static int proc_ipc_sem_dointvec(struct ctl_table *table, int write, 52fff1662cSTobias Klauser void *buffer, size_t *lenp, loff_t *ppos) 538c81ddd2SWaiman Long { 54dd141a49SAlexey Gladkov struct ipc_namespace *ns = 55dd141a49SAlexey Gladkov container_of(table->data, struct ipc_namespace, sem_ctls); 568c81ddd2SWaiman Long int ret, semmni; 571f5c135eSAlexey Gladkov 588c81ddd2SWaiman Long semmni = ns->sem_ctls[3]; 591f5c135eSAlexey Gladkov ret = proc_dointvec(table, write, buffer, lenp, ppos); 608c81ddd2SWaiman Long 618c81ddd2SWaiman Long if (!ret) 62def7343fSAlexey Gladkov ret = sem_check_semmni(ns); 638c81ddd2SWaiman Long 648c81ddd2SWaiman Long /* 658c81ddd2SWaiman Long * Reset the semmni value if an error happens. 668c81ddd2SWaiman Long */ 678c81ddd2SWaiman Long if (ret) 688c81ddd2SWaiman Long ns->sem_ctls[3] = semmni; 698c81ddd2SWaiman Long return ret; 708c81ddd2SWaiman Long } 718c81ddd2SWaiman Long 725ac893b8SWaiman Long int ipc_mni = IPCMNI; 735ac893b8SWaiman Long int ipc_mni_shift = IPCMNI_SHIFT; 7499db46eaSManfred Spraul int ipc_min_cycle = RADIX_TREE_MAP_SIZE; 759eefe520SNadia Derbey 761f5c135eSAlexey Gladkov static struct ctl_table ipc_sysctls[] = { 77a5494dcdSEric W. Biederman { 78a5494dcdSEric W. Biederman .procname = "shmmax", 79a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlmax, 80a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlmax), 81a5494dcdSEric W. Biederman .mode = 0644, 821f5c135eSAlexey Gladkov .proc_handler = proc_doulongvec_minmax, 83a5494dcdSEric W. Biederman }, 84a5494dcdSEric W. Biederman { 85a5494dcdSEric W. Biederman .procname = "shmall", 86a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlall, 87a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlall), 88a5494dcdSEric W. Biederman .mode = 0644, 891f5c135eSAlexey Gladkov .proc_handler = proc_doulongvec_minmax, 90a5494dcdSEric W. Biederman }, 91a5494dcdSEric W. Biederman { 92a5494dcdSEric W. Biederman .procname = "shmmni", 93a5494dcdSEric W. Biederman .data = &init_ipc_ns.shm_ctlmni, 94a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.shm_ctlmni), 95a5494dcdSEric W. Biederman .mode = 0644, 961f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 97eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO, 986730e658SWaiman Long .extra2 = &ipc_mni, 99a5494dcdSEric W. Biederman }, 100a5494dcdSEric W. Biederman { 101b34a6b1dSVasiliy Kulikov .procname = "shm_rmid_forced", 102b34a6b1dSVasiliy Kulikov .data = &init_ipc_ns.shm_rmid_forced, 103b34a6b1dSVasiliy Kulikov .maxlen = sizeof(init_ipc_ns.shm_rmid_forced), 104b34a6b1dSVasiliy Kulikov .mode = 0644, 105b34a6b1dSVasiliy Kulikov .proc_handler = proc_ipc_dointvec_minmax_orphans, 106dd141a49SAlexey Gladkov .extra1 = SYSCTL_ZERO, 107dd141a49SAlexey Gladkov .extra2 = SYSCTL_ONE, 108b34a6b1dSVasiliy Kulikov }, 109b34a6b1dSVasiliy Kulikov { 110a5494dcdSEric W. Biederman .procname = "msgmax", 111a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmax, 112a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmax), 113a5494dcdSEric W. Biederman .mode = 0644, 1141f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 115eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO, 116eec4844fSMatteo Croce .extra2 = SYSCTL_INT_MAX, 117a5494dcdSEric W. Biederman }, 118a5494dcdSEric W. Biederman { 119a5494dcdSEric W. Biederman .procname = "msgmni", 120a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmni, 121a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmni), 122a5494dcdSEric W. Biederman .mode = 0644, 1231f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 124eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO, 1256730e658SWaiman Long .extra2 = &ipc_mni, 126a5494dcdSEric W. Biederman }, 127a5494dcdSEric W. Biederman { 1280050ee05SManfred Spraul .procname = "auto_msgmni", 1290050ee05SManfred Spraul .data = NULL, 1300050ee05SManfred Spraul .maxlen = sizeof(int), 1310050ee05SManfred Spraul .mode = 0644, 1320050ee05SManfred Spraul .proc_handler = proc_ipc_auto_msgmni, 133eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO, 134eec4844fSMatteo Croce .extra2 = SYSCTL_ONE, 1350050ee05SManfred Spraul }, 1360050ee05SManfred Spraul { 137a5494dcdSEric W. Biederman .procname = "msgmnb", 138a5494dcdSEric W. Biederman .data = &init_ipc_ns.msg_ctlmnb, 139a5494dcdSEric W. Biederman .maxlen = sizeof(init_ipc_ns.msg_ctlmnb), 140a5494dcdSEric W. Biederman .mode = 0644, 1411f5c135eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 142eec4844fSMatteo Croce .extra1 = SYSCTL_ZERO, 143eec4844fSMatteo Croce .extra2 = SYSCTL_INT_MAX, 144a5494dcdSEric W. Biederman }, 145a5494dcdSEric W. Biederman { 146a5494dcdSEric W. Biederman .procname = "sem", 147a5494dcdSEric W. Biederman .data = &init_ipc_ns.sem_ctls, 148a5494dcdSEric W. Biederman .maxlen = 4*sizeof(int), 149a5494dcdSEric W. Biederman .mode = 0644, 1508c81ddd2SWaiman Long .proc_handler = proc_ipc_sem_dointvec, 151a5494dcdSEric W. Biederman }, 15203f59566SStanislav Kinsbursky #ifdef CONFIG_CHECKPOINT_RESTORE 15303f59566SStanislav Kinsbursky { 15403f59566SStanislav Kinsbursky .procname = "sem_next_id", 15503f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_SEM_IDS].next_id, 15603f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_SEM_IDS].next_id), 1570889f44eSAlexey Gladkov .mode = 0444, 1580889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 1590889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO, 1600889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX, 16103f59566SStanislav Kinsbursky }, 16203f59566SStanislav Kinsbursky { 16303f59566SStanislav Kinsbursky .procname = "msg_next_id", 16403f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_MSG_IDS].next_id, 16503f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_MSG_IDS].next_id), 1660889f44eSAlexey Gladkov .mode = 0444, 1670889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 1680889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO, 1690889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX, 17003f59566SStanislav Kinsbursky }, 17103f59566SStanislav Kinsbursky { 17203f59566SStanislav Kinsbursky .procname = "shm_next_id", 17303f59566SStanislav Kinsbursky .data = &init_ipc_ns.ids[IPC_SHM_IDS].next_id, 17403f59566SStanislav Kinsbursky .maxlen = sizeof(init_ipc_ns.ids[IPC_SHM_IDS].next_id), 1750889f44eSAlexey Gladkov .mode = 0444, 1760889f44eSAlexey Gladkov .proc_handler = proc_dointvec_minmax, 1770889f44eSAlexey Gladkov .extra1 = SYSCTL_ZERO, 1780889f44eSAlexey Gladkov .extra2 = SYSCTL_INT_MAX, 17903f59566SStanislav Kinsbursky }, 18003f59566SStanislav Kinsbursky #endif 181a5494dcdSEric W. Biederman {} 182a5494dcdSEric W. Biederman }; 183a5494dcdSEric W. Biederman 1841f5c135eSAlexey Gladkov static struct ctl_table_set *set_lookup(struct ctl_table_root *root) 185a5494dcdSEric W. Biederman { 1861f5c135eSAlexey Gladkov return ¤t->nsproxy->ipc_ns->ipc_set; 1871f5c135eSAlexey Gladkov } 1881f5c135eSAlexey Gladkov 1891f5c135eSAlexey Gladkov static int set_is_seen(struct ctl_table_set *set) 1901f5c135eSAlexey Gladkov { 1911f5c135eSAlexey Gladkov return ¤t->nsproxy->ipc_ns->ipc_set == set; 1921f5c135eSAlexey Gladkov } 1931f5c135eSAlexey Gladkov 194*8d5b1a9fSAlexey Gladkov static void ipc_set_ownership(struct ctl_table_header *head, 195*8d5b1a9fSAlexey Gladkov struct ctl_table *table, 196*8d5b1a9fSAlexey Gladkov kuid_t *uid, kgid_t *gid) 197*8d5b1a9fSAlexey Gladkov { 198*8d5b1a9fSAlexey Gladkov struct ipc_namespace *ns = 199*8d5b1a9fSAlexey Gladkov container_of(head->set, struct ipc_namespace, ipc_set); 200*8d5b1a9fSAlexey Gladkov 201*8d5b1a9fSAlexey Gladkov kuid_t ns_root_uid = make_kuid(ns->user_ns, 0); 202*8d5b1a9fSAlexey Gladkov kgid_t ns_root_gid = make_kgid(ns->user_ns, 0); 203*8d5b1a9fSAlexey Gladkov 204*8d5b1a9fSAlexey Gladkov *uid = uid_valid(ns_root_uid) ? ns_root_uid : GLOBAL_ROOT_UID; 205*8d5b1a9fSAlexey Gladkov *gid = gid_valid(ns_root_gid) ? ns_root_gid : GLOBAL_ROOT_GID; 206*8d5b1a9fSAlexey Gladkov } 207*8d5b1a9fSAlexey Gladkov 2080889f44eSAlexey Gladkov static int ipc_permissions(struct ctl_table_header *head, struct ctl_table *table) 2090889f44eSAlexey Gladkov { 2100889f44eSAlexey Gladkov int mode = table->mode; 2110889f44eSAlexey Gladkov 2120889f44eSAlexey Gladkov #ifdef CONFIG_CHECKPOINT_RESTORE 213*8d5b1a9fSAlexey Gladkov struct ipc_namespace *ns = 214*8d5b1a9fSAlexey Gladkov container_of(head->set, struct ipc_namespace, ipc_set); 2150889f44eSAlexey Gladkov 2160889f44eSAlexey Gladkov if (((table->data == &ns->ids[IPC_SEM_IDS].next_id) || 2170889f44eSAlexey Gladkov (table->data == &ns->ids[IPC_MSG_IDS].next_id) || 2180889f44eSAlexey Gladkov (table->data == &ns->ids[IPC_SHM_IDS].next_id)) && 2190889f44eSAlexey Gladkov checkpoint_restore_ns_capable(ns->user_ns)) 2200889f44eSAlexey Gladkov mode = 0666; 221*8d5b1a9fSAlexey Gladkov else 2220889f44eSAlexey Gladkov #endif 223*8d5b1a9fSAlexey Gladkov { 224*8d5b1a9fSAlexey Gladkov kuid_t ns_root_uid; 225*8d5b1a9fSAlexey Gladkov kgid_t ns_root_gid; 226*8d5b1a9fSAlexey Gladkov 227*8d5b1a9fSAlexey Gladkov ipc_set_ownership(head, table, &ns_root_uid, &ns_root_gid); 228*8d5b1a9fSAlexey Gladkov 229*8d5b1a9fSAlexey Gladkov if (uid_eq(current_euid(), ns_root_uid)) 230*8d5b1a9fSAlexey Gladkov mode >>= 6; 231*8d5b1a9fSAlexey Gladkov 232*8d5b1a9fSAlexey Gladkov else if (in_egroup_p(ns_root_gid)) 233*8d5b1a9fSAlexey Gladkov mode >>= 3; 234*8d5b1a9fSAlexey Gladkov } 235*8d5b1a9fSAlexey Gladkov 236*8d5b1a9fSAlexey Gladkov mode &= 7; 237*8d5b1a9fSAlexey Gladkov 238*8d5b1a9fSAlexey Gladkov return (mode << 6) | (mode << 3) | mode; 2390889f44eSAlexey Gladkov } 2400889f44eSAlexey Gladkov 2411f5c135eSAlexey Gladkov static struct ctl_table_root set_root = { 2421f5c135eSAlexey Gladkov .lookup = set_lookup, 2430889f44eSAlexey Gladkov .permissions = ipc_permissions, 244*8d5b1a9fSAlexey Gladkov .set_ownership = ipc_set_ownership, 245a5494dcdSEric W. Biederman }; 246a5494dcdSEric W. Biederman 2471f5c135eSAlexey Gladkov bool setup_ipc_sysctls(struct ipc_namespace *ns) 2481f5c135eSAlexey Gladkov { 2491f5c135eSAlexey Gladkov struct ctl_table *tbl; 2501f5c135eSAlexey Gladkov 2511f5c135eSAlexey Gladkov setup_sysctl_set(&ns->ipc_set, &set_root, set_is_seen); 2521f5c135eSAlexey Gladkov 2531f5c135eSAlexey Gladkov tbl = kmemdup(ipc_sysctls, sizeof(ipc_sysctls), GFP_KERNEL); 2541f5c135eSAlexey Gladkov if (tbl) { 2551f5c135eSAlexey Gladkov int i; 2561f5c135eSAlexey Gladkov 2571f5c135eSAlexey Gladkov for (i = 0; i < ARRAY_SIZE(ipc_sysctls); i++) { 25838cd5b12SAlexey Gladkov if (tbl[i].data == &init_ipc_ns.shm_ctlmax) 2591f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlmax; 2601f5c135eSAlexey Gladkov 26138cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_ctlall) 2621f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlall; 2631f5c135eSAlexey Gladkov 26438cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_ctlmni) 2651f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_ctlmni; 2661f5c135eSAlexey Gladkov 26738cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.shm_rmid_forced) 2681f5c135eSAlexey Gladkov tbl[i].data = &ns->shm_rmid_forced; 2691f5c135eSAlexey Gladkov 27038cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmax) 2711f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmax; 2721f5c135eSAlexey Gladkov 27338cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmni) 2741f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmni; 2751f5c135eSAlexey Gladkov 27638cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.msg_ctlmnb) 2771f5c135eSAlexey Gladkov tbl[i].data = &ns->msg_ctlmnb; 2781f5c135eSAlexey Gladkov 27938cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.sem_ctls) 2801f5c135eSAlexey Gladkov tbl[i].data = &ns->sem_ctls; 2811f5c135eSAlexey Gladkov #ifdef CONFIG_CHECKPOINT_RESTORE 28238cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_SEM_IDS].next_id) 2831f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_SEM_IDS].next_id; 2841f5c135eSAlexey Gladkov 28538cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_MSG_IDS].next_id) 2861f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_MSG_IDS].next_id; 2871f5c135eSAlexey Gladkov 28838cd5b12SAlexey Gladkov else if (tbl[i].data == &init_ipc_ns.ids[IPC_SHM_IDS].next_id) 2891f5c135eSAlexey Gladkov tbl[i].data = &ns->ids[IPC_SHM_IDS].next_id; 2901f5c135eSAlexey Gladkov #endif 29138cd5b12SAlexey Gladkov else 2921f5c135eSAlexey Gladkov tbl[i].data = NULL; 2931f5c135eSAlexey Gladkov } 2941f5c135eSAlexey Gladkov 295bff97cf1SJoel Granados ns->ipc_sysctls = __register_sysctl_table(&ns->ipc_set, 296bff97cf1SJoel Granados "kernel", tbl, 297bff97cf1SJoel Granados ARRAY_SIZE(ipc_sysctls)); 2981f5c135eSAlexey Gladkov } 2991f5c135eSAlexey Gladkov if (!ns->ipc_sysctls) { 3001f5c135eSAlexey Gladkov kfree(tbl); 3011f5c135eSAlexey Gladkov retire_sysctl_set(&ns->ipc_set); 3021f5c135eSAlexey Gladkov return false; 3031f5c135eSAlexey Gladkov } 3041f5c135eSAlexey Gladkov 3051f5c135eSAlexey Gladkov return true; 3061f5c135eSAlexey Gladkov } 3071f5c135eSAlexey Gladkov 3081f5c135eSAlexey Gladkov void retire_ipc_sysctls(struct ipc_namespace *ns) 3091f5c135eSAlexey Gladkov { 3101f5c135eSAlexey Gladkov struct ctl_table *tbl; 3111f5c135eSAlexey Gladkov 3121f5c135eSAlexey Gladkov tbl = ns->ipc_sysctls->ctl_table_arg; 3131f5c135eSAlexey Gladkov unregister_sysctl_table(ns->ipc_sysctls); 3141f5c135eSAlexey Gladkov retire_sysctl_set(&ns->ipc_set); 3151f5c135eSAlexey Gladkov kfree(tbl); 3161f5c135eSAlexey Gladkov } 3171f5c135eSAlexey Gladkov 318a5494dcdSEric W. Biederman static int __init ipc_sysctl_init(void) 319a5494dcdSEric W. Biederman { 3201f5c135eSAlexey Gladkov if (!setup_ipc_sysctls(&init_ipc_ns)) { 3211f5c135eSAlexey Gladkov pr_warn("ipc sysctl registration failed\n"); 3221f5c135eSAlexey Gladkov return -ENOMEM; 3231f5c135eSAlexey Gladkov } 324a5494dcdSEric W. Biederman return 0; 325a5494dcdSEric W. Biederman } 326a5494dcdSEric W. Biederman 3276d08a256SDavidlohr Bueso device_initcall(ipc_sysctl_init); 3285ac893b8SWaiman Long 3295ac893b8SWaiman Long static int __init ipc_mni_extend(char *str) 3305ac893b8SWaiman Long { 3315ac893b8SWaiman Long ipc_mni = IPCMNI_EXTEND; 3325ac893b8SWaiman Long ipc_mni_shift = IPCMNI_EXTEND_SHIFT; 33399db46eaSManfred Spraul ipc_min_cycle = IPCMNI_EXTEND_MIN_CYCLE; 3345ac893b8SWaiman Long pr_info("IPCMNI extended to %d.\n", ipc_mni); 3355ac893b8SWaiman Long return 0; 3365ac893b8SWaiman Long } 3375ac893b8SWaiman Long early_param("ipcmni_extend", ipc_mni_extend); 338