Deleted Added
full compact
sysv_shm.c (194894) sysv_shm.c (194910)
1/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */
2/*-
3 * Copyright (c) 1994 Adam Glass and Charles Hannum. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 46 unchanged lines hidden (view full) ---

55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 */
61
62#include <sys/cdefs.h>
1/* $NetBSD: sysv_shm.c,v 1.23 1994/07/04 23:25:12 glass Exp $ */
2/*-
3 * Copyright (c) 1994 Adam Glass and Charles Hannum. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 46 unchanged lines hidden (view full) ---

55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 */
61
62#include <sys/cdefs.h>
63__FBSDID("$FreeBSD: head/sys/kern/sysv_shm.c 194894 2009-06-24 20:01:13Z jhb $");
63__FBSDID("$FreeBSD: head/sys/kern/sysv_shm.c 194910 2009-06-24 21:10:52Z jhb $");
64
65#include "opt_compat.h"
66#include "opt_sysvipc.h"
67
68#include <sys/param.h>
69#include <sys/systm.h>
70#include <sys/kernel.h>
64
65#include "opt_compat.h"
66#include "opt_sysvipc.h"
67
68#include <sys/param.h>
69#include <sys/systm.h>
70#include <sys/kernel.h>
71#include <sys/limits.h>
71#include <sys/lock.h>
72#include <sys/sysctl.h>
73#include <sys/shm.h>
74#include <sys/proc.h>
75#include <sys/malloc.h>
76#include <sys/mman.h>
77#include <sys/module.h>
78#include <sys/mutex.h>

--- 150 unchanged lines hidden (view full) ---

229static void
230shm_deallocate_segment(shmseg)
231 struct shmid_kernel *shmseg;
232{
233 vm_size_t size;
234
235 GIANT_REQUIRED;
236
72#include <sys/lock.h>
73#include <sys/sysctl.h>
74#include <sys/shm.h>
75#include <sys/proc.h>
76#include <sys/malloc.h>
77#include <sys/mman.h>
78#include <sys/module.h>
79#include <sys/mutex.h>

--- 150 unchanged lines hidden (view full) ---

230static void
231shm_deallocate_segment(shmseg)
232 struct shmid_kernel *shmseg;
233{
234 vm_size_t size;
235
236 GIANT_REQUIRED;
237
237 vm_object_deallocate(shmseg->u.shm_internal);
238 shmseg->u.shm_internal = NULL;
239 size = round_page(shmseg->shm_bsegsz);
238 vm_object_deallocate(shmseg->object);
239 shmseg->object = NULL;
240 size = round_page(shmseg->u.shm_segsz);
240 shm_committed -= btoc(size);
241 shm_nused--;
242 shmseg->u.shm_perm.mode = SHMSEG_FREE;
243#ifdef MAC
244 mac_sysvshm_cleanup(shmseg);
245#endif
246}
247
248static int
249shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
250{
251 struct shmid_kernel *shmseg;
252 int segnum, result;
253 vm_size_t size;
254
255 GIANT_REQUIRED;
256
257 segnum = IPCID_TO_IX(shmmap_s->shmid);
258 shmseg = &shmsegs[segnum];
241 shm_committed -= btoc(size);
242 shm_nused--;
243 shmseg->u.shm_perm.mode = SHMSEG_FREE;
244#ifdef MAC
245 mac_sysvshm_cleanup(shmseg);
246#endif
247}
248
249static int
250shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
251{
252 struct shmid_kernel *shmseg;
253 int segnum, result;
254 vm_size_t size;
255
256 GIANT_REQUIRED;
257
258 segnum = IPCID_TO_IX(shmmap_s->shmid);
259 shmseg = &shmsegs[segnum];
259 size = round_page(shmseg->shm_bsegsz);
260 size = round_page(shmseg->u.shm_segsz);
260 result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
261 if (result != KERN_SUCCESS)
262 return (EINVAL);
263 shmmap_s->shmid = -1;
264 shmseg->u.shm_dtime = time_second;
265 if ((--shmseg->u.shm_nattch <= 0) &&
266 (shmseg->u.shm_perm.mode & SHMSEG_REMOVED)) {
267 shm_deallocate_segment(shmseg);

--- 103 unchanged lines hidden (view full) ---

371 if (shmmap_s->shmid == -1)
372 break;
373 shmmap_s++;
374 }
375 if (i >= shminfo.shmseg) {
376 error = EMFILE;
377 goto done2;
378 }
261 result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
262 if (result != KERN_SUCCESS)
263 return (EINVAL);
264 shmmap_s->shmid = -1;
265 shmseg->u.shm_dtime = time_second;
266 if ((--shmseg->u.shm_nattch <= 0) &&
267 (shmseg->u.shm_perm.mode & SHMSEG_REMOVED)) {
268 shm_deallocate_segment(shmseg);

--- 103 unchanged lines hidden (view full) ---

372 if (shmmap_s->shmid == -1)
373 break;
374 shmmap_s++;
375 }
376 if (i >= shminfo.shmseg) {
377 error = EMFILE;
378 goto done2;
379 }
379 size = round_page(shmseg->shm_bsegsz);
380 size = round_page(shmseg->u.shm_segsz);
380 prot = VM_PROT_READ;
381 if ((shmflg & SHM_RDONLY) == 0)
382 prot |= VM_PROT_WRITE;
383 flags = MAP_ANON | MAP_SHARED;
384 if (shmaddr) {
385 flags |= MAP_FIXED;
386 if (shmflg & SHM_RND) {
387 attach_va = (vm_offset_t)shmaddr & ~(SHMLBA-1);

--- 9 unchanged lines hidden (view full) ---

397 * put it.
398 */
399 PROC_LOCK(p);
400 attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
401 lim_max(p, RLIMIT_DATA));
402 PROC_UNLOCK(p);
403 }
404
381 prot = VM_PROT_READ;
382 if ((shmflg & SHM_RDONLY) == 0)
383 prot |= VM_PROT_WRITE;
384 flags = MAP_ANON | MAP_SHARED;
385 if (shmaddr) {
386 flags |= MAP_FIXED;
387 if (shmflg & SHM_RND) {
388 attach_va = (vm_offset_t)shmaddr & ~(SHMLBA-1);

--- 9 unchanged lines hidden (view full) ---

398 * put it.
399 */
400 PROC_LOCK(p);
401 attach_va = round_page((vm_offset_t)p->p_vmspace->vm_daddr +
402 lim_max(p, RLIMIT_DATA));
403 PROC_UNLOCK(p);
404 }
405
405 vm_object_reference(shmseg->u.shm_internal);
406 rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->u.shm_internal,
406 vm_object_reference(shmseg->object);
407 rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
407 0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
408 VMFS_ANY_SPACE, prot, prot, 0);
409 if (rv != KERN_SUCCESS) {
408 0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
409 VMFS_ANY_SPACE, prot, prot, 0);
410 if (rv != KERN_SUCCESS) {
410 vm_object_deallocate(shmseg->u.shm_internal);
411 vm_object_deallocate(shmseg->object);
411 error = ENOMEM;
412 goto done2;
413 }
414 vm_map_inherit(&p->p_vmspace->vm_map,
415 attach_va, attach_va + size, VM_INHERIT_SHARE);
416
417 shmmap_s->va = attach_va;
418 shmmap_s->shmid = shmid;

--- 200 unchanged lines hidden (view full) ---

619 }
620 if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
621 return (EEXIST);
622#ifdef MAC
623 error = mac_sysvshm_check_shmget(td->td_ucred, shmseg, uap->shmflg);
624 if (error != 0)
625 return (error);
626#endif
412 error = ENOMEM;
413 goto done2;
414 }
415 vm_map_inherit(&p->p_vmspace->vm_map,
416 attach_va, attach_va + size, VM_INHERIT_SHARE);
417
418 shmmap_s->va = attach_va;
419 shmmap_s->shmid = shmid;

--- 200 unchanged lines hidden (view full) ---

620 }
621 if ((uap->shmflg & (IPC_CREAT | IPC_EXCL)) == (IPC_CREAT | IPC_EXCL))
622 return (EEXIST);
623#ifdef MAC
624 error = mac_sysvshm_check_shmget(td->td_ucred, shmseg, uap->shmflg);
625 if (error != 0)
626 return (error);
627#endif
627 if (uap->size != 0 && uap->size > shmseg->shm_bsegsz)
628 if (uap->size != 0 && uap->size > shmseg->u.shm_segsz)
628 return (EINVAL);
629 td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
630 return (0);
631}
632
633static int
634shmget_allocate_segment(td, uap, mode)
635 struct thread *td;

--- 45 unchanged lines hidden (view full) ---

681 0, size, VM_PROT_DEFAULT, 0, cred);
682 if (shm_object == NULL)
683 return (ENOMEM);
684 VM_OBJECT_LOCK(shm_object);
685 vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
686 vm_object_set_flag(shm_object, OBJ_NOSPLIT);
687 VM_OBJECT_UNLOCK(shm_object);
688
629 return (EINVAL);
630 td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
631 return (0);
632}
633
634static int
635shmget_allocate_segment(td, uap, mode)
636 struct thread *td;

--- 45 unchanged lines hidden (view full) ---

682 0, size, VM_PROT_DEFAULT, 0, cred);
683 if (shm_object == NULL)
684 return (ENOMEM);
685 VM_OBJECT_LOCK(shm_object);
686 vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
687 vm_object_set_flag(shm_object, OBJ_NOSPLIT);
688 VM_OBJECT_UNLOCK(shm_object);
689
689 shmseg->u.shm_internal = shm_object;
690 shmseg->object = shm_object;
690 shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid;
691 shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
692 shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
693 (mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
694 shmseg->u.shm_segsz = uap->size;
691 shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid;
692 shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
693 shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
694 (mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
695 shmseg->u.shm_segsz = uap->size;
695 shmseg->shm_bsegsz = uap->size;
696 shmseg->u.shm_cpid = td->td_proc->p_pid;
697 shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
698 shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
699#ifdef MAC
700 mac_sysvshm_create(cred, shmseg);
701#endif
702 shmseg->u.shm_ctime = time_second;
703 shm_committed += btoc(size);

--- 244 unchanged lines hidden (view full) ---

948 return (EINVAL);
949#endif
950}
951
952/* XXX casting to (sy_call_t *) is bogus, as usual. */
953static sy_call_t *shmcalls[] = {
954 (sy_call_t *)shmat, (sy_call_t *)oshmctl,
955 (sy_call_t *)shmdt, (sy_call_t *)shmget,
696 shmseg->u.shm_cpid = td->td_proc->p_pid;
697 shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
698 shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
699#ifdef MAC
700 mac_sysvshm_create(cred, shmseg);
701#endif
702 shmseg->u.shm_ctime = time_second;
703 shm_committed += btoc(size);

--- 244 unchanged lines hidden (view full) ---

948 return (EINVAL);
949#endif
950}
951
952/* XXX casting to (sy_call_t *) is bogus, as usual. */
953static sy_call_t *shmcalls[] = {
954 (sy_call_t *)shmat, (sy_call_t *)oshmctl,
955 (sy_call_t *)shmdt, (sy_call_t *)shmget,
956 (sy_call_t *)shmctl
956 (sy_call_t *)freebsd7_shmctl
957};
958
959int
960shmsys(td, uap)
961 struct thread *td;
962 /* XXX actually varargs. */
963 struct shmsys_args /* {
964 int which;

--- 13 unchanged lines hidden (view full) ---

978 error = (*shmcalls[uap->which])(td, &uap->a2);
979 mtx_unlock(&Giant);
980 return (error);
981}
982
983SYSCALL_MODULE_HELPER(shmsys);
984#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
985
957};
958
959int
960shmsys(td, uap)
961 struct thread *td;
962 /* XXX actually varargs. */
963 struct shmsys_args /* {
964 int which;

--- 13 unchanged lines hidden (view full) ---

978 error = (*shmcalls[uap->which])(td, &uap->a2);
979 mtx_unlock(&Giant);
980 return (error);
981}
982
983SYSCALL_MODULE_HELPER(shmsys);
984#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
985
986#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
987 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
988
989#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
990
991
992#ifndef _SYS_SYSPROTO_H_
993struct freebsd7_shmctl_args {
994 int shmid;
995 int cmd;
996 struct shmid_ds_old *buf;
997};
998#endif
999int
1000freebsd7_shmctl(td, uap)
1001 struct thread *td;
1002 struct freebsd7_shmctl_args *uap;
1003{
1004 int error = 0;
1005 struct shmid_ds_old old;
1006 struct shmid_ds buf;
1007 size_t bufsz;
1008
1009 /*
1010 * The only reason IPC_INFO, SHM_INFO, SHM_STAT exists is to support
1011 * Linux binaries. If we see the call come through the FreeBSD ABI,
1012 * return an error back to the user since we do not to support this.
1013 */
1014 if (uap->cmd == IPC_INFO || uap->cmd == SHM_INFO ||
1015 uap->cmd == SHM_STAT)
1016 return (EINVAL);
1017
1018 /* IPC_SET needs to copyin the buffer before calling kern_shmctl */
1019 if (uap->cmd == IPC_SET) {
1020 if ((error = copyin(uap->buf, &old, sizeof(old))))
1021 goto done;
1022 ipcperm_old2new(&old.shm_perm, &buf.shm_perm);
1023 CP(old, buf, shm_segsz);
1024 CP(old, buf, shm_lpid);
1025 CP(old, buf, shm_cpid);
1026 CP(old, buf, shm_nattch);
1027 CP(old, buf, shm_atime);
1028 CP(old, buf, shm_dtime);
1029 CP(old, buf, shm_ctime);
1030 }
1031
1032 error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&buf, &bufsz);
1033 if (error)
1034 goto done;
1035
1036 /* Cases in which we need to copyout */
1037 switch (uap->cmd) {
1038 case IPC_STAT:
1039 ipcperm_new2old(&buf.shm_perm, &old.shm_perm);
1040 if (buf.shm_segsz > INT_MAX)
1041 old.shm_segsz = INT_MAX;
1042 else
1043 CP(buf, old, shm_segsz);
1044 CP(buf, old, shm_lpid);
1045 CP(buf, old, shm_cpid);
1046 if (buf.shm_nattch > SHRT_MAX)
1047 old.shm_nattch = SHRT_MAX;
1048 else
1049 CP(buf, old, shm_nattch);
1050 CP(buf, old, shm_atime);
1051 CP(buf, old, shm_dtime);
1052 CP(buf, old, shm_ctime);
1053 old.shm_internal = NULL;
1054 error = copyout(&old, uap->buf, sizeof(old));
1055 break;
1056 }
1057
1058done:
1059 if (error) {
1060 /* Invalidate the return value */
1061 td->td_retval[0] = -1;
1062 }
1063 return (error);
1064}
1065
1066SYSCALL_MODULE_HELPER(freebsd7_shmctl);
1067
1068#undef CP
1069
1070#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
1071 COMPAT_FREEBSD7 */
1072
986static int
987sysvshm_modload(struct module *module, int cmd, void *arg)
988{
989 int error = 0;
990
991 switch (cmd) {
992 case MOD_LOAD:
993 shminit();

--- 26 unchanged lines hidden ---
1073static int
1074sysvshm_modload(struct module *module, int cmd, void *arg)
1075{
1076 int error = 0;
1077
1078 switch (cmd) {
1079 case MOD_LOAD:
1080 shminit();

--- 26 unchanged lines hidden ---