62 #include <sys/cdefs.h>
65 #include "opt_compat.h"
66 #include "opt_sysvipc.h"
68 #include <sys/param.h>
69 #include <sys/systm.h>
70 #include <sys/kernel.h>
71 #include <sys/limits.h>
73 #include <sys/sysctl.h>
76 #include <sys/malloc.h>
78 #include <sys/module.h>
79 #include <sys/mutex.h>
80 #include <sys/racct.h>
81 #include <sys/resourcevar.h>
83 #include <sys/syscall.h>
84 #include <sys/syscallsubr.h>
85 #include <sys/sysent.h>
86 #include <sys/sysproto.h>
89 #include <security/mac/mac_framework.h>
92 #include <vm/vm_param.h>
94 #include <vm/vm_object.h>
95 #include <vm/vm_map.h>
96 #include <vm/vm_page.h>
97 #include <vm/vm_pager.h>
99 FEATURE(sysv_shm,
"System V shared memory segments support");
101 static MALLOC_DEFINE(M_SHM,
"shm",
"SVID compatible shared memory segments");
106 int mode,
int segnum);
108 #define SHMSEG_FREE 0x0200
109 #define SHMSEG_REMOVED 0x0400
110 #define SHMSEG_ALLOCATED 0x0800
111 #define SHMSEG_WANTED 0x1000
139 #define SHMMAXPGS 131072
142 #define SHMMAX (SHMMAXPGS*PAGE_SIZE)
154 #define SHMALL (SHMMAXPGS)
169 "Maximum shared memory segment size");
171 "Minimum shared memory segment size");
173 "Number of shared memory identifiers");
175 "Number of segments per process");
177 "Maximum number of pages available for shared memory");
179 &
shm_use_phys, 0,
"Enable/Disable locking of shared memory pages in core");
182 "Enable/Disable attachment to attached segments marked for removal");
185 "Current number of shared memory segments allocated");
195 shmsegs[i].u.shm_perm.key == key)
200 static struct shmid_kernel *
204 struct shmid_kernel *shmseg;
206 segnum = IPCID_TO_IX(shmid);
213 shmseg->u.shm_perm.seq != IPCID_TO_SEQ(shmid))
218 static struct shmid_kernel *
221 struct shmid_kernel *shmseg;
235 struct shmid_kernel *shmseg;
241 vm_object_deallocate(shmseg->object);
242 shmseg->object = NULL;
243 size = round_page(shmseg->u.shm_segsz);
248 mac_sysvshm_cleanup(shmseg);
259 struct shmid_kernel *shmseg;
265 segnum = IPCID_TO_IX(shmmap_s->
shmid);
267 size = round_page(shmseg->u.shm_segsz);
268 result = vm_map_remove(&vm->vm_map, shmmap_s->
va, shmmap_s->
va + size);
269 if (result != KERN_SUCCESS)
271 shmmap_s->
shmid = -1;
273 if ((--shmseg->u.shm_nattch <= 0) &&
281 #ifndef _SYS_SYSPROTO_H_
291 struct proc *p = td->td_proc;
294 struct shmid_kernel *shmsegptr;
302 shmmap_s = p->p_vmspace->vm_shm;
303 if (shmmap_s == NULL) {
307 for (i = 0; i <
shminfo.shmseg; i++, shmmap_s++) {
308 if (shmmap_s->
shmid != -1 &&
309 shmmap_s->
va == (vm_offset_t)uap->
shmaddr) {
319 error = mac_sysvshm_check_shmdt(td->td_ucred, shmsegptr);
329 #ifndef _SYS_SYSPROTO_H_
343 struct proc *p = td->td_proc;
345 struct shmid_kernel *shmseg;
347 vm_offset_t attach_va;
356 shmmap_s = p->p_vmspace->vm_shm;
357 if (shmmap_s == NULL) {
368 if (p->p_vmspace->vm_shm != NULL) {
369 free(shmmap_s, M_SHM);
370 shmmap_s = p->p_vmspace->vm_shm;
372 for (i = 0; i <
shminfo.shmseg; i++)
373 shmmap_s[i].shmid = -1;
374 p->p_vmspace->vm_shm = shmmap_s;
378 if (shmseg == NULL) {
382 error =
ipcperm(td, &shmseg->u.shm_perm,
383 (shmflg & SHM_RDONLY) ? IPC_R : IPC_R|IPC_W);
387 error = mac_sysvshm_check_shmat(td->td_ucred, shmseg, shmflg);
391 for (i = 0; i <
shminfo.shmseg; i++) {
392 if (shmmap_s->
shmid == -1)
400 size = round_page(shmseg->u.shm_segsz);
402 if ((shmflg & SHM_RDONLY) == 0)
403 prot |= VM_PROT_WRITE;
404 flags = MAP_ANON | MAP_SHARED;
407 if (shmflg & SHM_RND) {
408 attach_va = (vm_offset_t)shmaddr & ~(SHMLBA-1);
409 }
else if (((vm_offset_t)shmaddr & (SHMLBA-1)) == 0) {
410 attach_va = (vm_offset_t)shmaddr;
421 attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
426 vm_object_reference(shmseg->object);
427 rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
428 0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
429 VMFS_OPTIMAL_SPACE, prot, prot, MAP_INHERIT_SHARE);
430 if (rv != KERN_SUCCESS) {
431 vm_object_deallocate(shmseg->object);
436 shmmap_s->
va = attach_va;
438 shmseg->u.shm_lpid = p->p_pid;
440 shmseg->u.shm_nattch++;
441 td->td_retval[0] = attach_va;
464 struct shmid_kernel *shmseg;
487 struct shm_info shm_info;
489 shm_info.shm_rss = 0;
490 shm_info.shm_tot = 0;
491 shm_info.shm_swp = 0;
492 shm_info.swap_attempts = 0;
493 shm_info.swap_successes = 0;
494 memcpy(buf, &shm_info,
sizeof(shm_info));
496 *bufsz =
sizeof(shm_info);
505 if (shmseg == NULL) {
510 error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, cmd);
517 error =
ipcperm(td, &shmseg->u.shm_perm, IPC_R);
520 memcpy(buf, &shmseg->u,
sizeof(
struct shmid_ds));
522 *bufsz =
sizeof(
struct shmid_ds);
524 td->td_retval[0] = IXSEQ_TO_IPCID(shmid, shmseg->u.shm_perm);
527 struct shmid_ds *shmid;
529 shmid = (
struct shmid_ds *)buf;
530 error =
ipcperm(td, &shmseg->u.shm_perm, IPC_M);
533 shmseg->u.shm_perm.uid = shmid->shm_perm.uid;
534 shmseg->u.shm_perm.gid = shmid->shm_perm.gid;
535 shmseg->u.shm_perm.mode =
536 (shmseg->u.shm_perm.mode & ~ACCESSPERMS) |
537 (shmid->shm_perm.mode & ACCESSPERMS);
542 error =
ipcperm(td, &shmseg->u.shm_perm, IPC_M);
545 shmseg->u.shm_perm.key = IPC_PRIVATE;
547 if (shmseg->u.shm_nattch <= 0) {
565 #ifndef _SYS_SYSPROTO_H_
586 if (uap->
cmd == IPC_INFO || uap->
cmd == SHM_INFO ||
587 uap->
cmd == SHM_STAT)
591 if (uap->
cmd == IPC_SET) {
592 if ((error = copyin(uap->
buf, &buf,
sizeof(
struct shmid_ds))))
603 error = copyout(&buf, uap->
buf, bufsz);
610 td->td_retval[0] = -1;
623 struct shmid_kernel *shmseg;
634 error = tsleep(shmseg, PLOCK | PCATCH,
"shmget", 0);
639 if ((uap->
shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
642 error = mac_sysvshm_check_shmget(td->td_ucred, shmseg, uap->
shmflg);
646 if (uap->
size != 0 && uap->
size > shmseg->u.shm_segsz)
648 td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
658 int i, segnum, shmid;
660 struct ucred *cred = td->td_ucred;
661 struct shmid_kernel *shmseg;
662 vm_object_t shm_object;
670 size = round_page(uap->
size);
687 PROC_LOCK(td->td_proc);
688 if (
racct_add(td->td_proc, RACCT_NSHM, 1)) {
689 PROC_UNLOCK(td->td_proc);
692 if (
racct_add(td->td_proc, RACCT_SHMSIZE, size)) {
694 PROC_UNLOCK(td->td_proc);
697 PROC_UNLOCK(td->td_proc);
704 shmseg->u.shm_perm.key = uap->
key;
705 shmseg->u.shm_perm.seq = (shmseg->u.shm_perm.seq + 1) & 0x7fff;
706 shmid = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
712 shm_object = vm_pager_allocate(
shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
713 0, size, VM_PROT_DEFAULT, 0, cred);
714 if (shm_object == NULL) {
716 PROC_LOCK(td->td_proc);
718 racct_sub(td->td_proc, RACCT_SHMSIZE, size);
719 PROC_UNLOCK(td->td_proc);
723 VM_OBJECT_LOCK(shm_object);
724 vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
725 vm_object_set_flag(shm_object, OBJ_NOSPLIT);
726 VM_OBJECT_UNLOCK(shm_object);
728 shmseg->object = shm_object;
729 shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid;
730 shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
731 shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode &
SHMSEG_WANTED) |
733 shmseg->cred =
crhold(cred);
734 shmseg->u.shm_segsz = uap->
size;
735 shmseg->u.shm_cpid = td->td_proc->p_pid;
736 shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
737 shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
739 mac_sysvshm_create(cred, shmseg);
752 td->td_retval[0] = shmid;
756 #ifndef _SYS_SYSPROTO_H_
774 mode = uap->
shmflg & ACCESSPERMS;
775 if (uap->
key != IPC_PRIVATE) {
784 if ((uap->
shmflg & IPC_CREAT) == 0) {
797 struct proc *p1, *p2;
805 shmmap_s =
malloc(size, M_SHM, M_WAITOK);
806 bcopy(p1->p_vmspace->vm_shm, shmmap_s, size);
807 p2->p_vmspace->vm_shm = shmmap_s;
808 for (i = 0; i <
shminfo.shmseg; i++, shmmap_s++)
809 if (shmmap_s->
shmid != -1)
820 if ((base = vm->vm_shm) != NULL) {
823 for (i = 0, shm = base; i <
shminfo.shmseg; i++, shm++) {
824 if (shm->
shmid != -1)
836 struct shmid_kernel *newsegs;
841 newsegs =
malloc(
shminfo.shmmni *
sizeof(*newsegs), M_SHM, M_WAITOK);
843 bcopy(&
shmsegs[i], &newsegs[i],
sizeof(newsegs[0]));
844 for (; i <
shminfo.shmmni; i++) {
857 SYSCALL_INIT_HELPER(shmat),
858 SYSCALL_INIT_HELPER(shmctl),
859 SYSCALL_INIT_HELPER(shmdt),
860 SYSCALL_INIT_HELPER(shmget),
861 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
862 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
863 SYSCALL_INIT_HELPER_COMPAT(freebsd7_shmctl),
865 #if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
866 SYSCALL_INIT_HELPER(shmsys),
872 #include <compat/compat32bit/compat32bit.h>
873 #include <compat/compat32bit/compat32bit_ipc.h>
874 #include <compat/compat32bit/compat32bit_proto.h>
875 #include <compat/compat32bit/compat32bit_signal.h>
876 #include <compat/compat32bit/compat32bit_syscall.h>
877 #include <compat/compat32bit/compat32bit_util.h>
879 static struct syscall_helper_data shm32_syscalls[] = {
880 SYSCALL32_INIT_HELPER_COMPAT(shmat),
881 SYSCALL32_INIT_HELPER_COMPAT(shmdt),
882 SYSCALL32_INIT_HELPER_COMPAT(shmget),
883 SYSCALL32_INIT_HELPER(compat32bit_shmsys),
884 SYSCALL32_INIT_HELPER(compat32bit_shmctl),
885 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
886 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
887 SYSCALL32_INIT_HELPER(freebsd7_compat32bit_shmctl),
899 if (TUNABLE_ULONG_FETCH(
"kern.ipc.shmmaxpgs", &
shminfo.shmall) != 0)
900 printf(
"kern.ipc.shmmaxpgs is now called kern.ipc.shmall!\n");
902 TUNABLE_ULONG_FETCH(
"kern.ipc.shmall", &
shminfo.shmall);
905 for (i = PAGE_SIZE; i > 0; i--) {
911 TUNABLE_ULONG_FETCH(
"kern.ipc.shmmin", &
shminfo.shmmin);
912 TUNABLE_ULONG_FETCH(
"kern.ipc.shmmni", &
shminfo.shmmni);
913 TUNABLE_ULONG_FETCH(
"kern.ipc.shmseg", &
shminfo.shmseg);
914 TUNABLE_INT_FETCH(
"kern.ipc.shm_use_phys", &
shm_use_phys);
935 error = syscall32_helper_register(shm32_syscalls);
951 syscall32_helper_unregister(shm32_syscalls);
957 mac_sysvshm_destroy(&
shmsegs[i]);
965 vm_object_deallocate(
shmsegs[i].
object);
980 #if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
982 struct ipc_perm_old shm_perm;
993 struct oshmctl_args {
996 struct oshmid_ds *ubuf;
1000 oshmctl(
struct thread *td,
struct oshmctl_args *uap)
1004 struct shmid_kernel *shmseg;
1005 struct oshmid_ds outbuf;
1011 if (shmseg == NULL) {
1017 error =
ipcperm(td, &shmseg->u.shm_perm, IPC_R);
1021 error = mac_sysvshm_check_shmctl(td->td_ucred, shmseg, uap->cmd);
1025 ipcperm_new2old(&shmseg->u.shm_perm, &outbuf.shm_perm);
1026 outbuf.shm_segsz = shmseg->u.shm_segsz;
1027 outbuf.shm_cpid = shmseg->u.shm_cpid;
1028 outbuf.shm_lpid = shmseg->u.shm_lpid;
1029 outbuf.shm_nattch = shmseg->u.shm_nattch;
1030 outbuf.shm_atime = shmseg->u.shm_atime;
1031 outbuf.shm_dtime = shmseg->u.shm_dtime;
1032 outbuf.shm_ctime = shmseg->u.shm_ctime;
1033 outbuf.shm_handle = shmseg->object;
1034 error = copyout(&outbuf, uap->ubuf,
sizeof(outbuf));
1039 error = freebsd7_shmctl(td, (
struct freebsd7_shmctl_args *)uap);
1051 static sy_call_t *shmcalls[] = {
1052 (sy_call_t *)
sys_shmat, (sy_call_t *)oshmctl,
1054 (sy_call_t *)freebsd7_shmctl
1072 if (uap->which < 0 ||
1073 uap->which >=
sizeof(shmcalls)/
sizeof(shmcalls[0]))
1076 error = (*shmcalls[uap->which])(td, &uap->a2);
1086 compat32bit_shmsys(
struct thread *td,
struct compat32bit_shmsys_args *uap)
1089 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1090 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1091 switch (uap->which) {
1096 ap.shmaddr = PTRIN(uap->a3);
1097 ap.shmflg = uap->a4;
1098 return (
sysent[SYS_shmat].sy_call(td, &ap));
1104 return (
sysent[SYS_shmdt].sy_call(td, &ap));
1111 ap.shmflg = uap->a4;
1112 return (
sysent[SYS_shmget].sy_call(td, &ap));
1115 struct freebsd7_compat32bit_shmctl_args ap;
1119 ap.buf = PTRIN(uap->a4);
1120 return (freebsd7_compat32bit_shmctl(td, &ap));
1127 return (
nosys(td, NULL));
1131 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1132 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1134 freebsd7_compat32bit_shmctl(
struct thread *td,
1135 struct freebsd7_compat32bit_shmctl_args *uap)
1139 struct shmid_ds shmid_ds;
1140 struct shm_info shm_info;
1144 struct shmid_ds32_old shmid_ds32;
1145 struct shm_info32 shm_info32;
1146 struct shminfo32 shminfo32;
1150 if (uap->cmd == IPC_SET) {
1151 if ((error = copyin(uap->buf, &u32.shmid_ds32,
1152 sizeof(u32.shmid_ds32))))
1154 compat32bit_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
1155 &u.shmid_ds.shm_perm);
1156 CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1157 CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1158 CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1159 CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1160 CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1161 CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1162 CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1165 error =
kern_shmctl(td, uap->shmid, uap->cmd, (
void *)&u, &sz);
1172 CP(u.shminfo, u32.shminfo32, shmmax);
1173 CP(u.shminfo, u32.shminfo32, shmmin);
1174 CP(u.shminfo, u32.shminfo32, shmmni);
1175 CP(u.shminfo, u32.shminfo32, shmseg);
1176 CP(u.shminfo, u32.shminfo32, shmall);
1177 error = copyout(&u32.shminfo32, uap->buf,
1178 sizeof(u32.shminfo32));
1181 CP(u.shm_info, u32.shm_info32, used_ids);
1182 CP(u.shm_info, u32.shm_info32, shm_rss);
1183 CP(u.shm_info, u32.shm_info32, shm_tot);
1184 CP(u.shm_info, u32.shm_info32, shm_swp);
1185 CP(u.shm_info, u32.shm_info32, swap_attempts);
1186 CP(u.shm_info, u32.shm_info32, swap_successes);
1187 error = copyout(&u32.shm_info32, uap->buf,
1188 sizeof(u32.shm_info32));
1192 compat32bit_ipcperm_old_out(&u.shmid_ds.shm_perm,
1193 &u32.shmid_ds32.shm_perm);
1194 if (u.shmid_ds.shm_segsz > INT32_MAX)
1195 u32.shmid_ds32.shm_segsz = INT32_MAX;
1197 CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1198 CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1199 CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1200 CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1201 CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1202 CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1203 CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1204 u32.shmid_ds32.shm_internal = 0;
1205 error = copyout(&u32.shmid_ds32, uap->buf,
1206 sizeof(u32.shmid_ds32));
1213 td->td_retval[0] = -1;
1220 compat32bit_shmctl(
struct thread *td,
struct compat32bit_shmctl_args *uap)
1224 struct shmid_ds shmid_ds;
1225 struct shm_info shm_info;
1229 struct shmid_ds32 shmid_ds32;
1230 struct shm_info32 shm_info32;
1231 struct shminfo32 shminfo32;
1235 if (uap->cmd == IPC_SET) {
1236 if ((error = copyin(uap->buf, &u32.shmid_ds32,
1237 sizeof(u32.shmid_ds32))))
1239 compat32bit_ipcperm_in(&u32.shmid_ds32.shm_perm,
1240 &u.shmid_ds.shm_perm);
1241 CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1242 CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1243 CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1244 CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1245 CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1246 CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1247 CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1250 error =
kern_shmctl(td, uap->shmid, uap->cmd, (
void *)&u, &sz);
1257 CP(u.shminfo, u32.shminfo32, shmmax);
1258 CP(u.shminfo, u32.shminfo32, shmmin);
1259 CP(u.shminfo, u32.shminfo32, shmmni);
1260 CP(u.shminfo, u32.shminfo32, shmseg);
1261 CP(u.shminfo, u32.shminfo32, shmall);
1262 error = copyout(&u32.shminfo32, uap->buf,
1263 sizeof(u32.shminfo32));
1266 CP(u.shm_info, u32.shm_info32, used_ids);
1267 CP(u.shm_info, u32.shm_info32, shm_rss);
1268 CP(u.shm_info, u32.shm_info32, shm_tot);
1269 CP(u.shm_info, u32.shm_info32, shm_swp);
1270 CP(u.shm_info, u32.shm_info32, swap_attempts);
1271 CP(u.shm_info, u32.shm_info32, swap_successes);
1272 error = copyout(&u32.shm_info32, uap->buf,
1273 sizeof(u32.shm_info32));
1277 compat32bit_ipcperm_out(&u.shmid_ds.shm_perm,
1278 &u32.shmid_ds32.shm_perm);
1279 if (u.shmid_ds.shm_segsz > INT32_MAX)
1280 u32.shmid_ds32.shm_segsz = INT32_MAX;
1282 CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1283 CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1284 CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1285 CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1286 CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1287 CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1288 CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1289 error = copyout(&u32.shmid_ds32, uap->buf,
1290 sizeof(u32.shmid_ds32));
1297 td->td_retval[0] = -1;
1303 #if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1304 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1307 #define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1310 #ifndef _SYS_SYSPROTO_H_
1311 struct freebsd7_shmctl_args {
1314 struct shmid_ds_old *
buf;
1318 freebsd7_shmctl(td, uap)
1320 struct freebsd7_shmctl_args *uap;
1323 struct shmid_ds_old old;
1324 struct shmid_ds
buf;
1332 if (uap->cmd == IPC_INFO || uap->cmd == SHM_INFO ||
1333 uap->cmd == SHM_STAT)
1337 if (uap->cmd == IPC_SET) {
1338 if ((error = copyin(uap->buf, &old,
sizeof(old))))
1340 ipcperm_old2new(&old.shm_perm, &
buf.shm_perm);
1341 CP(old,
buf, shm_segsz);
1342 CP(old,
buf, shm_lpid);
1343 CP(old,
buf, shm_cpid);
1344 CP(old,
buf, shm_nattch);
1345 CP(old,
buf, shm_atime);
1346 CP(old,
buf, shm_dtime);
1347 CP(old,
buf, shm_ctime);
1350 error =
kern_shmctl(td, uap->shmid, uap->cmd, (
void *)&
buf, &bufsz);
1357 ipcperm_new2old(&
buf.shm_perm, &old.shm_perm);
1358 if (
buf.shm_segsz > INT_MAX)
1359 old.shm_segsz = INT_MAX;
1361 CP(
buf, old, shm_segsz);
1362 CP(
buf, old, shm_lpid);
1363 CP(
buf, old, shm_cpid);
1364 if (
buf.shm_nattch > SHRT_MAX)
1365 old.shm_nattch = SHRT_MAX;
1367 CP(
buf, old, shm_nattch);
1368 CP(
buf, old, shm_atime);
1369 CP(
buf, old, shm_dtime);
1370 CP(
buf, old, shm_ctime);
1371 old.shm_internal = NULL;
1372 error = copyout(&old, uap->buf,
sizeof(old));
1379 td->td_retval[0] = -1;
1416 DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST);
rlim_t lim_max(struct proc *p, int which)
int prison_allow(struct ucred *cred, unsigned flag)
int kern_shmctl(struct thread *td, int shmid, int cmd, void *buf, size_t *bufsz)
int syscall_helper_unregister(struct syscall_helper_data *sd)
int ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
SYSCTL_ULONG(_kern_ipc, OID_AUTO, shmmax, CTLFLAG_RW,&shminfo.shmmax, 0,"Maximum shared memory segment size")
volatile time_t time_second
int racct_add(struct proc *p, int resource, uint64_t amount)
static struct shmid_kernel * shm_find_segment_by_shmid(int)
void racct_sub_cred(struct ucred *cred, int resource, uint64_t amount)
int syscall_helper_register(struct syscall_helper_data *sd)
static struct shmid_kernel * shm_find_segment_by_shmidx(int)
static void shm_deallocate_segment(struct shmid_kernel *)
static int shm_allow_removed
SYSCTL_INT(_kern_ipc, OID_AUTO, shm_use_phys, CTLFLAG_RW,&shm_use_phys, 0,"Enable/Disable locking of shared memory pages in core")
void * malloc(unsigned long size, struct malloc_type *mtp, int flags)
void(* shmexit_hook)(struct vmspace *)
static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *)
static int shmget_allocate_segment(struct thread *td, struct shmget_args *uap, int mode)
int nosys(struct thread *td, struct nosys_args *args)
static int shmget_existing(struct thread *td, struct shmget_args *uap, int mode, int segnum)
void racct_sub(struct proc *p, int resource, uint64_t amount)
static void shmrealloc(void)
static struct syscall_helper_data shm_syscalls[]
static void shmexit_myhook(struct vmspace *vm)
static int sysctl_shmsegs(SYSCTL_HANDLER_ARGS)
void(* shmfork_hook)(struct proc *, struct proc *)
DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST)
void crfree(struct ucred *cr)
int kern_shmat(struct thread *td, int shmid, const void *shmaddr, int shmflg)
SYSCTL_PROC(_kern_ipc, OID_AUTO, shmsegs, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0, sysctl_shmsegs,"","Current number of shared memory segments allocated")
struct ucred * crhold(struct ucred *cr)
int sys_shmctl(struct thread *td, struct shmctl_args *uap)
int sys_shmdt(struct thread *td, struct shmdt_args *uap)
void free(void *addr, struct malloc_type *mtp)
int printf(const char *fmt,...)
static int sysvshm_modload(struct module *, int, void *)
int sys_shmget(struct thread *td, struct shmget_args *uap)
MODULE_VERSION(sysvshm, 1)
FEATURE(sysv_shm,"System V shared memory segments support")
static MALLOC_DEFINE(M_SHM,"shm","SVID compatible shared memory segments")
static struct shmid_kernel * shmsegs
static moduledata_t sysvshm_mod
int sys_shmat(struct thread *td, struct shmat_args *uap)
static int shmunload(void)
static int shm_find_segment_by_key(key_t)
static void shmfork_myhook(struct proc *p1, struct proc *p2)