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 --- |