Deleted Added
full compact
sysv_shm.c (198449) sysv_shm.c (205323)
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 198449 2009-10-24 19:00:58Z ru $");
63__FBSDID("$FreeBSD: head/sys/kern/sysv_shm.c 205323 2010-03-19 11:04:42Z kib $");
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>

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

117};
118
119static void shm_deallocate_segment(struct shmid_kernel *);
120static int shm_find_segment_by_key(key_t);
121static struct shmid_kernel *shm_find_segment_by_shmid(int);
122static struct shmid_kernel *shm_find_segment_by_shmidx(int);
123static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
124static void shmrealloc(void);
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>

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

117};
118
119static void shm_deallocate_segment(struct shmid_kernel *);
120static int shm_find_segment_by_key(key_t);
121static struct shmid_kernel *shm_find_segment_by_shmid(int);
122static struct shmid_kernel *shm_find_segment_by_shmidx(int);
123static int shm_delete_mapping(struct vmspace *vm, struct shmmap_state *);
124static void shmrealloc(void);
125static void shminit(void);
125static int shminit(void);
126static int sysvshm_modload(struct module *, int, void *);
127static int shmunload(void);
128static void shmexit_myhook(struct vmspace *vm);
129static void shmfork_myhook(struct proc *p1, struct proc *p2);
130static int sysctl_shmsegs(SYSCTL_HANDLER_ARGS);
131
132/*
133 * Tuneable values.

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

811 mac_sysvshm_init(&shmsegs[i]);
812#endif
813 }
814 free(shmsegs, M_SHM);
815 shmsegs = newsegs;
816 shmalloced = shminfo.shmmni;
817}
818
126static int sysvshm_modload(struct module *, int, void *);
127static int shmunload(void);
128static void shmexit_myhook(struct vmspace *vm);
129static void shmfork_myhook(struct proc *p1, struct proc *p2);
130static int sysctl_shmsegs(SYSCTL_HANDLER_ARGS);
131
132/*
133 * Tuneable values.

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

811 mac_sysvshm_init(&shmsegs[i]);
812#endif
813 }
814 free(shmsegs, M_SHM);
815 shmsegs = newsegs;
816 shmalloced = shminfo.shmmni;
817}
818
819static void
819static struct syscall_helper_data shm_syscalls[] = {
820 SYSCALL_INIT_HELPER(shmat),
821 SYSCALL_INIT_HELPER(shmctl),
822 SYSCALL_INIT_HELPER(shmdt),
823 SYSCALL_INIT_HELPER(shmget),
824#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
825 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
826 SYSCALL_INIT_HELPER(freebsd7_shmctl),
827#endif
828#if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
829 SYSCALL_INIT_HELPER(shmsys),
830#endif
831 SYSCALL_INIT_LAST
832};
833
834#ifdef COMPAT_FREEBSD32
835#include <compat/freebsd32/freebsd32.h>
836#include <compat/freebsd32/freebsd32_ipc.h>
837#include <compat/freebsd32/freebsd32_proto.h>
838#include <compat/freebsd32/freebsd32_signal.h>
839#include <compat/freebsd32/freebsd32_syscall.h>
840#include <compat/freebsd32/freebsd32_util.h>
841
842static struct syscall_helper_data shm32_syscalls[] = {
843 SYSCALL32_INIT_HELPER(shmat),
844 SYSCALL32_INIT_HELPER(shmdt),
845 SYSCALL32_INIT_HELPER(shmget),
846 SYSCALL32_INIT_HELPER(freebsd32_shmsys),
847 SYSCALL32_INIT_HELPER(freebsd32_shmctl),
848#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
849 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
850 SYSCALL32_INIT_HELPER(freebsd7_freebsd32_shmctl),
851#endif
852 SYSCALL_INIT_LAST
853};
854#endif
855
856static int
820shminit()
821{
857shminit()
858{
822 int i;
859 int i, error;
823
824#ifndef BURN_BRIDGES
825 if (TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall) != 0)
826 printf("kern.ipc.shmmaxpgs is now called kern.ipc.shmall!\n");
827#endif
828 TUNABLE_ULONG_FETCH("kern.ipc.shmall", &shminfo.shmall);
829
830 /* Initialize shmmax dealing with possible overflow. */

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

850 mac_sysvshm_init(&shmsegs[i]);
851#endif
852 }
853 shm_last_free = 0;
854 shm_nused = 0;
855 shm_committed = 0;
856 shmexit_hook = &shmexit_myhook;
857 shmfork_hook = &shmfork_myhook;
860
861#ifndef BURN_BRIDGES
862 if (TUNABLE_ULONG_FETCH("kern.ipc.shmmaxpgs", &shminfo.shmall) != 0)
863 printf("kern.ipc.shmmaxpgs is now called kern.ipc.shmall!\n");
864#endif
865 TUNABLE_ULONG_FETCH("kern.ipc.shmall", &shminfo.shmall);
866
867 /* Initialize shmmax dealing with possible overflow. */

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

887 mac_sysvshm_init(&shmsegs[i]);
888#endif
889 }
890 shm_last_free = 0;
891 shm_nused = 0;
892 shm_committed = 0;
893 shmexit_hook = &shmexit_myhook;
894 shmfork_hook = &shmfork_myhook;
895
896 error = syscall_helper_register(shm_syscalls);
897 if (error != 0)
898 return (error);
899#ifdef COMPAT_FREEBSD32
900 error = syscall32_helper_register(shm32_syscalls);
901 if (error != 0)
902 return (error);
903#endif
904 return (0);
858}
859
860static int
861shmunload()
862{
863#ifdef MAC
864 int i;
865#endif
866
867 if (shm_nused > 0)
868 return (EBUSY);
869
905}
906
907static int
908shmunload()
909{
910#ifdef MAC
911 int i;
912#endif
913
914 if (shm_nused > 0)
915 return (EBUSY);
916
917#ifdef COMPAT_FREEBSD32
918 syscall32_helper_unregister(shm32_syscalls);
919#endif
920 syscall_helper_unregister(shm_syscalls);
921
870#ifdef MAC
871 for (i = 0; i < shmalloced; i++)
872 mac_sysvshm_destroy(&shmsegs[i]);
873#endif
874 free(shmsegs, M_SHM);
875 shmexit_hook = NULL;
876 shmfork_hook = NULL;
877 return (0);

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

980 uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
981 return (EINVAL);
982 mtx_lock(&Giant);
983 error = (*shmcalls[uap->which])(td, &uap->a2);
984 mtx_unlock(&Giant);
985 return (error);
986}
987
922#ifdef MAC
923 for (i = 0; i < shmalloced; i++)
924 mac_sysvshm_destroy(&shmsegs[i]);
925#endif
926 free(shmsegs, M_SHM);
927 shmexit_hook = NULL;
928 shmfork_hook = NULL;
929 return (0);

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

1032 uap->which >= sizeof(shmcalls)/sizeof(shmcalls[0]))
1033 return (EINVAL);
1034 mtx_lock(&Giant);
1035 error = (*shmcalls[uap->which])(td, &uap->a2);
1036 mtx_unlock(&Giant);
1037 return (error);
1038}
1039
988SYSCALL_MODULE_HELPER(shmsys);
989#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
990
1040#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
1041
1042#ifdef COMPAT_FREEBSD32
1043
1044int
1045freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
1046{
1047
991#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
992 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1048#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1049 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1050 switch (uap->which) {
1051 case 0: { /* shmat */
1052 struct shmat_args ap;
993
1053
994#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1054 ap.shmid = uap->a2;
1055 ap.shmaddr = PTRIN(uap->a3);
1056 ap.shmflg = uap->a4;
1057 return (sysent[SYS_shmat].sy_call(td, &ap));
1058 }
1059 case 2: { /* shmdt */
1060 struct shmdt_args ap;
995
1061
1062 ap.shmaddr = PTRIN(uap->a2);
1063 return (sysent[SYS_shmdt].sy_call(td, &ap));
1064 }
1065 case 3: { /* shmget */
1066 struct shmget_args ap;
996
1067
1068 ap.key = uap->a2;
1069 ap.size = uap->a3;
1070 ap.shmflg = uap->a4;
1071 return (sysent[SYS_shmget].sy_call(td, &ap));
1072 }
1073 case 4: { /* shmctl */
1074 struct freebsd7_freebsd32_shmctl_args ap;
1075
1076 ap.shmid = uap->a2;
1077 ap.cmd = uap->a3;
1078 ap.buf = PTRIN(uap->a4);
1079 return (freebsd7_freebsd32_shmctl(td, &ap));
1080 }
1081 case 1: /* oshmctl */
1082 default:
1083 return (EINVAL);
1084 }
1085#else
1086 return (nosys(td, NULL));
1087#endif
1088}
1089
1090#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1091 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1092int
1093freebsd7_freebsd32_shmctl(struct thread *td,
1094 struct freebsd7_freebsd32_shmctl_args *uap)
1095{
1096 int error = 0;
1097 union {
1098 struct shmid_ds shmid_ds;
1099 struct shm_info shm_info;
1100 struct shminfo shminfo;
1101 } u;
1102 union {
1103 struct shmid_ds32_old shmid_ds32;
1104 struct shm_info32 shm_info32;
1105 struct shminfo32 shminfo32;
1106 } u32;
1107 size_t sz;
1108
1109 if (uap->cmd == IPC_SET) {
1110 if ((error = copyin(uap->buf, &u32.shmid_ds32,
1111 sizeof(u32.shmid_ds32))))
1112 goto done;
1113 freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
1114 &u.shmid_ds.shm_perm);
1115 CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1116 CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1117 CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1118 CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1119 CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1120 CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1121 CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1122 }
1123
1124 error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
1125 if (error)
1126 goto done;
1127
1128 /* Cases in which we need to copyout */
1129 switch (uap->cmd) {
1130 case IPC_INFO:
1131 CP(u.shminfo, u32.shminfo32, shmmax);
1132 CP(u.shminfo, u32.shminfo32, shmmin);
1133 CP(u.shminfo, u32.shminfo32, shmmni);
1134 CP(u.shminfo, u32.shminfo32, shmseg);
1135 CP(u.shminfo, u32.shminfo32, shmall);
1136 error = copyout(&u32.shminfo32, uap->buf,
1137 sizeof(u32.shminfo32));
1138 break;
1139 case SHM_INFO:
1140 CP(u.shm_info, u32.shm_info32, used_ids);
1141 CP(u.shm_info, u32.shm_info32, shm_rss);
1142 CP(u.shm_info, u32.shm_info32, shm_tot);
1143 CP(u.shm_info, u32.shm_info32, shm_swp);
1144 CP(u.shm_info, u32.shm_info32, swap_attempts);
1145 CP(u.shm_info, u32.shm_info32, swap_successes);
1146 error = copyout(&u32.shm_info32, uap->buf,
1147 sizeof(u32.shm_info32));
1148 break;
1149 case SHM_STAT:
1150 case IPC_STAT:
1151 freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
1152 &u32.shmid_ds32.shm_perm);
1153 if (u.shmid_ds.shm_segsz > INT32_MAX)
1154 u32.shmid_ds32.shm_segsz = INT32_MAX;
1155 else
1156 CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1157 CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1158 CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1159 CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1160 CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1161 CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1162 CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1163 u32.shmid_ds32.shm_internal = 0;
1164 error = copyout(&u32.shmid_ds32, uap->buf,
1165 sizeof(u32.shmid_ds32));
1166 break;
1167 }
1168
1169done:
1170 if (error) {
1171 /* Invalidate the return value */
1172 td->td_retval[0] = -1;
1173 }
1174 return (error);
1175}
1176#endif
1177
1178int
1179freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
1180{
1181 int error = 0;
1182 union {
1183 struct shmid_ds shmid_ds;
1184 struct shm_info shm_info;
1185 struct shminfo shminfo;
1186 } u;
1187 union {
1188 struct shmid_ds32 shmid_ds32;
1189 struct shm_info32 shm_info32;
1190 struct shminfo32 shminfo32;
1191 } u32;
1192 size_t sz;
1193
1194 if (uap->cmd == IPC_SET) {
1195 if ((error = copyin(uap->buf, &u32.shmid_ds32,
1196 sizeof(u32.shmid_ds32))))
1197 goto done;
1198 freebsd32_ipcperm_in(&u32.shmid_ds32.shm_perm,
1199 &u.shmid_ds.shm_perm);
1200 CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
1201 CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
1202 CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
1203 CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
1204 CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
1205 CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
1206 CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
1207 }
1208
1209 error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
1210 if (error)
1211 goto done;
1212
1213 /* Cases in which we need to copyout */
1214 switch (uap->cmd) {
1215 case IPC_INFO:
1216 CP(u.shminfo, u32.shminfo32, shmmax);
1217 CP(u.shminfo, u32.shminfo32, shmmin);
1218 CP(u.shminfo, u32.shminfo32, shmmni);
1219 CP(u.shminfo, u32.shminfo32, shmseg);
1220 CP(u.shminfo, u32.shminfo32, shmall);
1221 error = copyout(&u32.shminfo32, uap->buf,
1222 sizeof(u32.shminfo32));
1223 break;
1224 case SHM_INFO:
1225 CP(u.shm_info, u32.shm_info32, used_ids);
1226 CP(u.shm_info, u32.shm_info32, shm_rss);
1227 CP(u.shm_info, u32.shm_info32, shm_tot);
1228 CP(u.shm_info, u32.shm_info32, shm_swp);
1229 CP(u.shm_info, u32.shm_info32, swap_attempts);
1230 CP(u.shm_info, u32.shm_info32, swap_successes);
1231 error = copyout(&u32.shm_info32, uap->buf,
1232 sizeof(u32.shm_info32));
1233 break;
1234 case SHM_STAT:
1235 case IPC_STAT:
1236 freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
1237 &u32.shmid_ds32.shm_perm);
1238 if (u.shmid_ds.shm_segsz > INT32_MAX)
1239 u32.shmid_ds32.shm_segsz = INT32_MAX;
1240 else
1241 CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
1242 CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
1243 CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
1244 CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
1245 CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
1246 CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
1247 CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
1248 error = copyout(&u32.shmid_ds32, uap->buf,
1249 sizeof(u32.shmid_ds32));
1250 break;
1251 }
1252
1253done:
1254 if (error) {
1255 /* Invalidate the return value */
1256 td->td_retval[0] = -1;
1257 }
1258 return (error);
1259}
1260#endif
1261
1262#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
1263 defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
1264
1265#ifndef CP
1266#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
1267#endif
1268
997#ifndef _SYS_SYSPROTO_H_
998struct freebsd7_shmctl_args {
999 int shmid;
1000 int cmd;
1001 struct shmid_ds_old *buf;
1002};
1003#endif
1004int

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

1063done:
1064 if (error) {
1065 /* Invalidate the return value */
1066 td->td_retval[0] = -1;
1067 }
1068 return (error);
1069}
1070
1269#ifndef _SYS_SYSPROTO_H_
1270struct freebsd7_shmctl_args {
1271 int shmid;
1272 int cmd;
1273 struct shmid_ds_old *buf;
1274};
1275#endif
1276int

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

1335done:
1336 if (error) {
1337 /* Invalidate the return value */
1338 td->td_retval[0] = -1;
1339 }
1340 return (error);
1341}
1342
1071SYSCALL_MODULE_HELPER(freebsd7_shmctl);
1072
1073#undef CP
1074
1075#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
1076 COMPAT_FREEBSD7 */
1077
1078static int
1079sysvshm_modload(struct module *module, int cmd, void *arg)
1080{
1081 int error = 0;
1082
1083 switch (cmd) {
1084 case MOD_LOAD:
1343#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
1344 COMPAT_FREEBSD7 */
1345
1346static int
1347sysvshm_modload(struct module *module, int cmd, void *arg)
1348{
1349 int error = 0;
1350
1351 switch (cmd) {
1352 case MOD_LOAD:
1085 shminit();
1353 error = shminit();
1354 if (error != 0)
1355 shmunload();
1086 break;
1087 case MOD_UNLOAD:
1088 error = shmunload();
1089 break;
1090 case MOD_SHUTDOWN:
1091 break;
1092 default:
1093 error = EINVAL;
1094 break;
1095 }
1096 return (error);
1097}
1098
1099static moduledata_t sysvshm_mod = {
1100 "sysvshm",
1101 &sysvshm_modload,
1102 NULL
1103};
1104
1356 break;
1357 case MOD_UNLOAD:
1358 error = shmunload();
1359 break;
1360 case MOD_SHUTDOWN:
1361 break;
1362 default:
1363 error = EINVAL;
1364 break;
1365 }
1366 return (error);
1367}
1368
1369static moduledata_t sysvshm_mod = {
1370 "sysvshm",
1371 &sysvshm_modload,
1372 NULL
1373};
1374
1105SYSCALL_MODULE_HELPER(shmat);
1106SYSCALL_MODULE_HELPER(shmctl);
1107SYSCALL_MODULE_HELPER(shmdt);
1108SYSCALL_MODULE_HELPER(shmget);
1109
1110DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST);
1111MODULE_VERSION(sysvshm, 1);
1375DECLARE_MODULE(sysvshm, sysvshm_mod, SI_SUB_SYSV_SHM, SI_ORDER_FIRST);
1376MODULE_VERSION(sysvshm, 1);