diff options
author | alfred <alfred@FreeBSD.org> | 2000-12-01 08:57:47 +0000 |
---|---|---|
committer | alfred <alfred@FreeBSD.org> | 2000-12-01 08:57:47 +0000 |
commit | e6bf60ac99dad1e2f847cb7f1557c06a651f4c9d (patch) | |
tree | 9e9a1edac03b7e0a202fb92d35ad8aba89087754 | |
parent | e1caf64702400ce84de06e726003bca5f0121595 (diff) | |
download | FreeBSD-src-e6bf60ac99dad1e2f847cb7f1557c06a651f4c9d.zip FreeBSD-src-e6bf60ac99dad1e2f847cb7f1557c06a651f4c9d.tar.gz |
sysvipc loadable.
new syscall entry lkmressys - "reserved loadable syscall"
Make syscall_register allow overwriting of such entries (lkmressys).
-rw-r--r-- | sys/kern/init_sysent.c | 29 | ||||
-rw-r--r-- | sys/kern/kern_syscalls.c | 9 | ||||
-rw-r--r-- | sys/kern/syscalls.c | 1 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 40 | ||||
-rw-r--r-- | sys/kern/sysv_ipc.c | 242 | ||||
-rw-r--r-- | sys/kern/sysv_msg.c | 73 | ||||
-rw-r--r-- | sys/kern/sysv_sem.c | 64 | ||||
-rw-r--r-- | sys/kern/sysv_shm.c | 70 | ||||
-rw-r--r-- | sys/modules/Makefile | 2 | ||||
-rw-r--r-- | sys/modules/sysvipc/sysvmsg/Makefile | 10 | ||||
-rw-r--r-- | sys/modules/sysvipc/sysvsem/Makefile | 10 | ||||
-rw-r--r-- | sys/modules/sysvipc/sysvshm/Makefile | 11 | ||||
-rw-r--r-- | sys/sys/ipc.h | 4 | ||||
-rw-r--r-- | sys/sys/syscall.h | 2 | ||||
-rw-r--r-- | sys/sys/sysent.h | 9 | ||||
-rw-r--r-- | sys/sys/sysproto.h | 1 |
16 files changed, 321 insertions, 256 deletions
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index c2d3cae..ba9728e 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -191,9 +191,9 @@ struct sysent sysent[] = { { AS(rtprio_args), (sy_call_t *)rtprio }, /* 166 = rtprio */ { 0, (sy_call_t *)nosys }, /* 167 = nosys */ { 0, (sy_call_t *)nosys }, /* 168 = nosys */ - { AS(semsys_args), (sy_call_t *)semsys }, /* 169 = semsys */ - { AS(msgsys_args), (sy_call_t *)msgsys }, /* 170 = msgsys */ - { AS(shmsys_args), (sy_call_t *)shmsys }, /* 171 = shmsys */ + { AS(semsys_args), (sy_call_t *)lkmressys }, /* 169 = semsys */ + { AS(msgsys_args), (sy_call_t *)lkmressys }, /* 170 = msgsys */ + { AS(shmsys_args), (sy_call_t *)lkmressys }, /* 171 = shmsys */ { 0, (sy_call_t *)nosys }, /* 172 = nosys */ { AS(pread_args), (sy_call_t *)pread }, /* 173 = pread */ { AS(pwrite_args), (sy_call_t *)pwrite }, /* 174 = pwrite */ @@ -242,18 +242,18 @@ struct sysent sysent[] = { { 0, (sy_call_t *)lkmnosys }, /* 217 = lkmnosys */ { 0, (sy_call_t *)lkmnosys }, /* 218 = lkmnosys */ { 0, (sy_call_t *)lkmnosys }, /* 219 = lkmnosys */ - { AS(__semctl_args), (sy_call_t *)__semctl }, /* 220 = __semctl */ - { AS(semget_args), (sy_call_t *)semget }, /* 221 = semget */ - { AS(semop_args), (sy_call_t *)semop }, /* 222 = semop */ + { AS(__semctl_args), (sy_call_t *)lkmressys }, /* 220 = __semctl */ + { AS(semget_args), (sy_call_t *)lkmressys }, /* 221 = semget */ + { AS(semop_args), (sy_call_t *)lkmressys }, /* 222 = semop */ { 0, (sy_call_t *)nosys }, /* 223 = semconfig */ - { AS(msgctl_args), (sy_call_t *)msgctl }, /* 224 = msgctl */ - { AS(msgget_args), (sy_call_t *)msgget }, /* 225 = msgget */ - { AS(msgsnd_args), (sy_call_t *)msgsnd }, /* 226 = msgsnd */ - { AS(msgrcv_args), (sy_call_t *)msgrcv }, /* 227 = msgrcv */ - { AS(shmat_args), (sy_call_t *)shmat }, /* 228 = shmat */ - { AS(shmctl_args), (sy_call_t *)shmctl }, /* 229 = shmctl */ - { AS(shmdt_args), (sy_call_t *)shmdt }, /* 230 = shmdt */ - { AS(shmget_args), (sy_call_t *)shmget }, /* 231 = shmget */ + { AS(msgctl_args), (sy_call_t *)lkmressys }, /* 224 = msgctl */ + { AS(msgget_args), (sy_call_t *)lkmressys }, /* 225 = msgget */ + { AS(msgsnd_args), (sy_call_t *)lkmressys }, /* 226 = msgsnd */ + { AS(msgrcv_args), (sy_call_t *)lkmressys }, /* 227 = msgrcv */ + { AS(shmat_args), (sy_call_t *)lkmressys }, /* 228 = shmat */ + { AS(shmctl_args), (sy_call_t *)lkmressys }, /* 229 = shmctl */ + { AS(shmdt_args), (sy_call_t *)lkmressys }, /* 230 = shmdt */ + { AS(shmget_args), (sy_call_t *)lkmressys }, /* 231 = shmget */ { AS(clock_gettime_args), (sy_call_t *)clock_gettime }, /* 232 = clock_gettime */ { AS(clock_settime_args), (sy_call_t *)clock_settime }, /* 233 = clock_settime */ { AS(clock_getres_args), (sy_call_t *)clock_getres }, /* 234 = clock_getres */ @@ -392,4 +392,5 @@ struct sysent sysent[] = { { AS(__cap_get_file_args), (sy_call_t *)__cap_get_file }, /* 367 = __cap_get_file */ { AS(__cap_set_fd_args), (sy_call_t *)__cap_set_fd }, /* 368 = __cap_set_fd */ { AS(__cap_set_file_args), (sy_call_t *)__cap_set_file }, /* 369 = __cap_set_file */ + { 0, (sy_call_t *)lkmressys }, /* 370 = lkmressys */ }; diff --git a/sys/kern/kern_syscalls.c b/sys/kern/kern_syscalls.c index 72b01c8..633406a 100644 --- a/sys/kern/kern_syscalls.c +++ b/sys/kern/kern_syscalls.c @@ -45,6 +45,12 @@ lkmnosys(struct proc *p, struct nosys_args *args) } int +lkmressys(struct proc *p, struct nosys_args *args) +{ + return(nosys(p, args)); +} + +int syscall_register(int *offset, struct sysent *new_sysent, struct sysent *old_sysent) { @@ -59,7 +65,8 @@ syscall_register(int *offset, struct sysent *new_sysent, *offset = i; } else if (*offset < 0 || *offset >= SYS_MAXSYSCALL) return EINVAL; - else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys) + else if (sysent[*offset].sy_call != (sy_call_t *)lkmnosys && + sysent[*offset].sy_call != (sy_call_t *)lkmressys) return EEXIST; *old_sysent = sysent[*offset]; diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 85e638a..834580a 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -377,4 +377,5 @@ char *syscallnames[] = { "__cap_get_file", /* 367 = __cap_get_file */ "__cap_set_fd", /* 368 = __cap_set_fd */ "__cap_set_file", /* 369 = __cap_set_file */ + "lkmressys", /* 370 = lkmressys */ }; diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 1ec9908..9a33b8a 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -9,7 +9,7 @@ ; MPSAFE optional field, specifies that syscall does not want the ; BGL grabbed automatically (it is SMP safe). ; type one of STD, OBSOL, UNIMPL, COMPAT, CPT_NOA, LIBCOMPAT, -; NODEF, NOARGS, NOPROTO, NOIMPL +; NODEF, NOARGS, NOPROTO, NOIMPL, NOSTD ; namespc one of POSIX, BSD, NOHIDE ; name psuedo-prototype of syscall routine ; If one of the following alts is different, then all appear: @@ -24,6 +24,9 @@ ; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h ; OBSOL obsolete, not included in system, only specifies name ; UNIMPL not implemented, placeholder only +; NOSTD implemented but as a lkm that can be statically +; compiled in sysent entry will be filled with lkmsys +; so the SYSCALL_MODULE macro works ; #ifdef's, etc. may be included, and are copied to the output files. @@ -249,7 +252,6 @@ 158 STD BSD { int fstatfs(int fd, struct statfs *buf); } 159 UNIMPL NOHIDE nosys 160 UNIMPL NOHIDE nosys -; 161 is initialized by the NFS code, if present. 161 STD BSD { int getfh(char *fname, struct fhandle *fhp); } 162 STD BSD { int getdomainname(char *domainname, int len); } 163 STD BSD { int setdomainname(char *domainname, int len); } @@ -259,13 +261,16 @@ struct rtprio *rtp); } 167 UNIMPL NOHIDE nosys 168 UNIMPL NOHIDE nosys -169 STD BSD { int semsys(int which, int a2, int a3, int a4, \ +; 169 is initialized by the SYSVSEM code if present or loaded +169 NOSTD BSD { int semsys(int which, int a2, int a3, int a4, \ int a5); } +; 169 is initialized by the SYSVMSG code if present or loaded ; XXX should be { int semsys(int which, ...); } -170 STD BSD { int msgsys(int which, int a2, int a3, int a4, \ +170 NOSTD BSD { int msgsys(int which, int a2, int a3, int a4, \ int a5, int a6); } +; 169 is initialized by the SYSVSHM code if present or loaded ; XXX should be { int msgsys(int which, ...); } -171 STD BSD { int shmsys(int which, int a2, int a3, int a4); } +171 NOSTD BSD { int shmsys(int which, int a2, int a3, int a4); } ; XXX should be { int shmsys(int which, ...); } 172 UNIMPL NOHIDE nosys 173 STD POSIX { ssize_t pread(int fd, void *buf, size_t nbyte, \ @@ -338,25 +343,25 @@ ; ; The following were introduced with NetBSD/4.4Lite-2 -; -220 STD BSD { int __semctl(int semid, int semnum, int cmd, \ +; They are initialized by thier respective modules/sysinits +220 NOSTD BSD { int __semctl(int semid, int semnum, int cmd, \ union semun *arg); } -221 STD BSD { int semget(key_t key, int nsems, int semflg); } -222 STD BSD { int semop(int semid, struct sembuf *sops, \ +221 NOSTD BSD { int semget(key_t key, int nsems, int semflg); } +222 NOSTD BSD { int semop(int semid, struct sembuf *sops, \ u_int nsops); } 223 UNIMPL NOHIDE semconfig -224 STD BSD { int msgctl(int msqid, int cmd, \ +224 NOSTD BSD { int msgctl(int msqid, int cmd, \ struct msqid_ds *buf); } -225 STD BSD { int msgget(key_t key, int msgflg); } -226 STD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \ +225 NOSTD BSD { int msgget(key_t key, int msgflg); } +226 NOSTD BSD { int msgsnd(int msqid, void *msgp, size_t msgsz, \ int msgflg); } -227 STD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \ +227 NOSTD BSD { int msgrcv(int msqid, void *msgp, size_t msgsz, \ long msgtyp, int msgflg); } -228 STD BSD { int shmat(int shmid, void *shmaddr, int shmflg); } -229 STD BSD { int shmctl(int shmid, int cmd, \ +228 NOSTD BSD { int shmat(int shmid, void *shmaddr, int shmflg); } +229 NOSTD BSD { int shmctl(int shmid, int cmd, \ struct shmid_ds *buf); } -230 STD BSD { int shmdt(void *shmaddr); } -231 STD BSD { int shmget(key_t key, int size, int shmflg); } +230 NOSTD BSD { int shmdt(void *shmaddr); } +231 NOSTD BSD { int shmget(key_t key, int size, int shmflg); } ; 232 STD POSIX { int clock_gettime(clockid_t clock_id, \ struct timespec *tp); } @@ -526,3 +531,4 @@ 367 STD BSD { int __cap_get_file(const char *path_p, struct cap *cap_p); } 368 STD BSD { int __cap_set_fd(int fd, struct cap *cap_p); } 369 STD BSD { int __cap_set_file(const char *path_p, struct cap *cap_p); } +370 NODEF NOHIDE lkmressys lkmressys nosys_args int diff --git a/sys/kern/sysv_ipc.c b/sys/kern/sysv_ipc.c index eddd9ed..f28d660 100644 --- a/sys/kern/sysv_ipc.c +++ b/sys/kern/sysv_ipc.c @@ -35,11 +35,48 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/sem.h> +#include <sys/shm.h> #include <sys/ipc.h> #include <sys/proc.h> #include <sys/ucred.h> -#if defined(SYSVSEM) || defined(SYSVSHM) || defined(SYSVMSG) +void (*semexit_hook)(struct proc *) = NULL; +void (*shmfork_hook)(struct proc *, struct proc *) = NULL; +void (*shmexit_hook)(struct proc *) = NULL; + +/* called from kern_exit.c */ +void +semexit(p) + struct proc *p; +{ + + if (semexit_hook != NULL) + semexit_hook(p); + return; +} + +/* called from kern_fork.c */ +void +shmfork(p1, p2) + struct proc *p1, *p2; +{ + + if (shmfork_hook != NULL) + shmfork_hook(p1, p2); + return; +} + +/* called from kern_exit.c */ +void +shmexit(p) + struct proc *p; +{ + + if (shmexit_hook != NULL) + shmexit_hook(p); + return; +} /* * Check for ipc permission @@ -69,206 +106,3 @@ ipcperm(p, perm, mode) return (0); return ((mode & perm->mode) == mode || suser(p) == 0 ? 0 : EACCES); } - -#endif /* defined(SYSVSEM) || defined(SYSVSHM) || defined(SYSVMSG) */ - - -#if !defined(SYSVSEM) || !defined(SYSVSHM) || !defined(SYSVMSG) - -#include <sys/proc.h> -#include <sys/sem.h> -#include <sys/shm.h> -#include <sys/syslog.h> -#include <sys/sysproto.h> -#include <sys/systm.h> - -static void sysv_nosys __P((struct proc *p, char *s)); - -static void -sysv_nosys(p, s) - struct proc *p; - char *s; -{ - log(LOG_ERR, "cmd %s pid %d tried to use non-present %s\n", - p->p_comm, p->p_pid, s); -} - -#if !defined(SYSVSEM) - -/* - * SYSVSEM stubs - */ - -int -semsys(p, uap) - struct proc *p; - struct semsys_args *uap; -{ - sysv_nosys(p, "SYSVSEM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -__semctl(p, uap) - struct proc *p; - register struct __semctl_args *uap; -{ - sysv_nosys(p, "SYSVSEM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -semget(p, uap) - struct proc *p; - register struct semget_args *uap; -{ - sysv_nosys(p, "SYSVSEM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -semop(p, uap) - struct proc *p; - register struct semop_args *uap; -{ - sysv_nosys(p, "SYSVSEM"); - return nosys(p, (struct nosys_args *)uap); -}; - -/* called from kern_exit.c */ -void -semexit(p) - struct proc *p; -{ - return; -} - -#endif /* !defined(SYSVSEM) */ - - -#if !defined(SYSVMSG) - -/* - * SYSVMSG stubs - */ - -int -msgsys(p, uap) - struct proc *p; - /* XXX actually varargs. */ - struct msgsys_args *uap; -{ - sysv_nosys(p, "SYSVMSG"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -msgctl(p, uap) - struct proc *p; - register struct msgctl_args *uap; -{ - sysv_nosys(p, "SYSVMSG"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -msgget(p, uap) - struct proc *p; - register struct msgget_args *uap; -{ - sysv_nosys(p, "SYSVMSG"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -msgsnd(p, uap) - struct proc *p; - register struct msgsnd_args *uap; -{ - sysv_nosys(p, "SYSVMSG"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -msgrcv(p, uap) - struct proc *p; - register struct msgrcv_args *uap; -{ - sysv_nosys(p, "SYSVMSG"); - return nosys(p, (struct nosys_args *)uap); -}; - -#endif /* !defined(SYSVMSG) */ - - -#if !defined(SYSVSHM) - -/* - * SYSVSHM stubs - */ - -int -shmdt(p, uap) - struct proc *p; - struct shmdt_args *uap; -{ - sysv_nosys(p, "SYSVSHM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -shmat(p, uap) - struct proc *p; - struct shmat_args *uap; -{ - sysv_nosys(p, "SYSVSHM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -shmctl(p, uap) - struct proc *p; - struct shmctl_args *uap; -{ - sysv_nosys(p, "SYSVSHM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -shmget(p, uap) - struct proc *p; - struct shmget_args *uap; -{ - sysv_nosys(p, "SYSVSHM"); - return nosys(p, (struct nosys_args *)uap); -}; - -int -shmsys(p, uap) - struct proc *p; - /* XXX actually varargs. */ - struct shmsys_args *uap; -{ - sysv_nosys(p, "SYSVSHM"); - return nosys(p, (struct nosys_args *)uap); -}; - -/* called from kern_fork.c */ -void -shmfork(p1, p2) - struct proc *p1, *p2; -{ - return; -} - -/* called from kern_exit.c */ -void -shmexit(p) - struct proc *p; -{ - return; -} - -#endif /* !defined(SYSVSHM) */ - -#endif /* !defined(SYSVSEM) || !defined(SYSVSHM) || !defined(SYSVMSG) */ diff --git a/sys/kern/sysv_msg.c b/sys/kern/sysv_msg.c index 6b8ab1e..cbc6535 100644 --- a/sys/kern/sysv_msg.c +++ b/sys/kern/sysv_msg.c @@ -27,6 +27,7 @@ #include <sys/kernel.h> #include <sys/proc.h> #include <sys/msg.h> +#include <sys/syscall.h> #include <sys/sysent.h> #include <sys/sysctl.h> #include <sys/malloc.h> @@ -34,7 +35,9 @@ static MALLOC_DEFINE(M_MSG, "msg", "SVID compatible message queues"); -static void msginit __P((void *)); +static void msginit __P((void)); +static int msgunload __P((void)); +static int sysvmsg_modload __P((struct module *, int, void *)); #define MSG_DEBUG #undef MSG_DEBUG_OK @@ -123,8 +126,7 @@ static struct msg *msghdrs; /* MSGTQL msg headers */ static struct msqid_ds *msqids; /* MSGMNI msqid_ds struct's */ static void -msginit(dummy) - void *dummy; +msginit() { register int i; @@ -192,7 +194,70 @@ msginit(dummy) msqids[i].msg_perm.mode = 0; } } -SYSINIT(sysv_msg, SI_SUB_SYSV_MSG, SI_ORDER_FIRST, msginit, NULL) + +static int +msgunload() +{ + struct msqid_ds *msqptr; + int msqid; + + for (msqid = 0; msqid < msginfo.msgmni; msqid++) { + /* + * Look for an unallocated and unlocked msqid_ds. + * msqid_ds's can be locked by msgsnd or msgrcv while + * they are copying the message in/out. We can't + * re-use the entry until they release it. + */ + msqptr = &msqids[msqid]; + if (msqptr->msg_qbytes != 0 || + (msqptr->msg_perm.mode & MSG_LOCKED) != 0) + break; + } + if (msqid != msginfo.msgmni) + return (EBUSY); + + free(msgpool, M_MSG); + free(msgmaps, M_MSG); + free(msghdrs, M_MSG); + free(msqids, M_MSG); + return (0); +} + + +static int +sysvmsg_modload(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD: + msginit(); + break; + case MOD_UNLOAD: + error = msgunload(); + break; + case MOD_SHUTDOWN: + break; + default: + error = EINVAL; + break; + } + return (error); +} + +static moduledata_t sysvmsg_moduledata = { + "sysvmsg_mod", + &sysvmsg_modload, + NULL +}; + +SYSCALL_MODULE_HELPER(msgctl, 3); +SYSCALL_MODULE_HELPER(msgget, 2); +SYSCALL_MODULE_HELPER(msgsnd, 4); +SYSCALL_MODULE_HELPER(msgrcv, 5); + +DECLARE_MODULE(sysvmsg_mod, sysvmsg_moduledata, + SI_SUB_SYSV_MSG, SI_ORDER_FIRST); /* * Entry point for all MSG calls diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c index f616f6e..e817a18 100644 --- a/sys/kern/sysv_sem.c +++ b/sys/kern/sysv_sem.c @@ -16,6 +16,7 @@ #include <sys/kernel.h> #include <sys/proc.h> #include <sys/sem.h> +#include <sys/syscall.h> #include <sys/sysent.h> #include <sys/sysctl.h> #include <sys/malloc.h> @@ -23,7 +24,10 @@ static MALLOC_DEFINE(M_SEM, "sem", "SVID compatible semaphores"); -static void seminit __P((void *)); +static void seminit __P((void)); +static int sysvsem_modload __P((struct module *, int, void *)); +static int semunload __P((void)); +static void semexit_myhook __P((struct proc *p)); #ifndef _SYS_SYSPROTO_H_ struct __semctl_args; @@ -159,8 +163,7 @@ RO seminfo.semaem /* SEMAEM unused - user param */ #endif static void -seminit(dummy) - void *dummy; +seminit(void) { register int i; @@ -183,8 +186,57 @@ seminit(dummy) suptr->un_proc = NULL; } semu_list = NULL; + semexit_hook = &semexit_myhook; } -SYSINIT(sysv_sem, SI_SUB_SYSV_SEM, SI_ORDER_FIRST, seminit, NULL) + +static int +semunload(void) +{ + + if (semtot != 0) + return (EBUSY); + + free(sem, M_SEM); + free(sema, M_SEM); + free(semu, M_SEM); + semexit_hook = NULL; + return (0); +} + +static int +sysvsem_modload(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD: + seminit(); + break; + case MOD_UNLOAD: + error = semunload(); + break; + case MOD_SHUTDOWN: + break; + default: + error = EINVAL; + break; + } + return (error); +} + +static moduledata_t sysvsem_moduledata = { + "sysvsem_mod", + &sysvsem_modload, + NULL +}; + +SYSCALL_MODULE_HELPER(semsys, 5); +SYSCALL_MODULE_HELPER(__semctl, 4); +SYSCALL_MODULE_HELPER(semget, 3); +SYSCALL_MODULE_HELPER(semop, 3); + +DECLARE_MODULE(sysvsem_mod, sysvsem_moduledata, + SI_SUB_SYSV_SEM, SI_ORDER_FIRST); /* * Entry point for all SEM calls @@ -933,8 +985,8 @@ done: * Go through the undo structures for this process and apply the adjustments to * semaphores. */ -void -semexit(p) +static void +semexit_myhook(p) struct proc *p; { register struct sem_undo *suptr; diff --git a/sys/kern/sysv_shm.c b/sys/kern/sysv_shm.c index 9ad55099..97608f4 100644 --- a/sys/kern/sysv_shm.c +++ b/sys/kern/sysv_shm.c @@ -45,6 +45,7 @@ #include <sys/malloc.h> #include <sys/mman.h> #include <sys/stat.h> +#include <sys/syscall.h> #include <sys/sysent.h> #include <sys/jail.h> @@ -95,7 +96,11 @@ static int shm_find_segment_by_key __P((key_t)); static struct shmid_ds *shm_find_segment_by_shmid __P((int)); static int shm_delete_mapping __P((struct proc *, struct shmmap_state *)); static void shmrealloc __P((void)); -static void shminit __P((void *)); +static void shminit __P((void)); +static int sysvshm_modload __P((struct module *, int, void *)); +static int shmunload __P((void)); +static void shmexit_myhook __P((struct proc *p)); +static void shmfork_myhook __P((struct proc *p1, struct proc *p2)); /* * Tuneable values @@ -624,8 +629,8 @@ shmsys(p, uap) return ((*shmcalls[uap->which])(p, &uap->a2)); } -void -shmfork(p1, p2) +static void +shmfork_myhook(p1, p2) struct proc *p1, *p2; { struct shmmap_state *shmmap_s; @@ -641,8 +646,8 @@ shmfork(p1, p2) shmsegs[IPCID_TO_IX(shmmap_s->shmid)].shm_nattch++; } -void -shmexit(p) +static void +shmexit_myhook(p) struct proc *p; { struct shmmap_state *shmmap_s; @@ -680,8 +685,7 @@ shmrealloc(void) } static void -shminit(dummy) - void *dummy; +shminit() { int i; @@ -696,5 +700,55 @@ shminit(dummy) shm_last_free = 0; shm_nused = 0; shm_committed = 0; + shmexit_hook = &shmexit_myhook; + shmfork_hook = &shmfork_myhook; +} + +static int +shmunload() +{ + + if (shm_nused > 0) + return (EBUSY); + + free(shmsegs, M_SHM); + shmexit_hook = NULL; + shmfork_hook = NULL; + return (0); +} + +static int +sysvshm_modload(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD: + shminit(); + break; + case MOD_UNLOAD: + error = shmunload(); + break; + case MOD_SHUTDOWN: + break; + default: + error = EINVAL; + break; + } + return (error); } -SYSINIT(sysv_shm, SI_SUB_SYSV_SHM, SI_ORDER_FIRST, shminit, NULL); + +static moduledata_t sysvshm_moduledata = { + "sysvshm_mod", + &sysvshm_modload, + NULL +}; + +SYSCALL_MODULE_HELPER(shmsys, 4); +SYSCALL_MODULE_HELPER(shmat, 3); +SYSCALL_MODULE_HELPER(shmctl, 3); +SYSCALL_MODULE_HELPER(shmdt, 1); +SYSCALL_MODULE_HELPER(shmget, 3); + +DECLARE_MODULE(sysvshm_mod, sysvshm_moduledata, + SI_SUB_SYSV_SHM, SI_ORDER_FIRST); diff --git a/sys/modules/Makefile b/sys/modules/Makefile index 52c41d2..5c7b5c0 100644 --- a/sys/modules/Makefile +++ b/sys/modules/Makefile @@ -11,7 +11,7 @@ SUBDIR= 3dfx accf_data accf_http agp aha amr an aue \ if_ppp if_sl if_tap if_tun ip6fw ipfilter ipfw ispfw joy kernfs kue \ linux md mfs mii mlx msdos ncp netgraph nfs ntfs nullfs \ nwfs pcn portal procfs ${_random} \ - rl rp sf sis sk sn sound ste syscons ti tl twe tx \ + rl rp sf sis sk sn sound ste syscons sysvipc ti tl twe tx \ udbp ugen uhid ukbd ulpt umapfs umass umodem ums union urio usb \ uscanner \ vinum vn vpo vr vx wb wx xl diff --git a/sys/modules/sysvipc/sysvmsg/Makefile b/sys/modules/sysvipc/sysvmsg/Makefile new file mode 100644 index 0000000..9392b4b --- /dev/null +++ b/sys/modules/sysvipc/sysvmsg/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../kern +KMOD = sysvmsg +SRCS = sysv_msg.c opt_sysvipc.h + +opt_sysvipc.h: + touch $@ + +.include <bsd.kmod.mk> diff --git a/sys/modules/sysvipc/sysvsem/Makefile b/sys/modules/sysvipc/sysvsem/Makefile new file mode 100644 index 0000000..f799802 --- /dev/null +++ b/sys/modules/sysvipc/sysvsem/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../kern +KMOD = sysvsem +SRCS = sysv_sem.c opt_sysvipc.h + +opt_sysvipc.h: + touch $@ + +.include <bsd.kmod.mk> diff --git a/sys/modules/sysvipc/sysvshm/Makefile b/sys/modules/sysvipc/sysvshm/Makefile new file mode 100644 index 0000000..d63280e --- /dev/null +++ b/sys/modules/sysvipc/sysvshm/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../kern +KMOD = sysvshm +OPTS = opt_sysvipc.h opt_compat.h opt_rlimit.h +SRCS = sysv_shm.c $(OPTS) + +$(OPTS): + touch $@ + +.include <bsd.kmod.mk> diff --git a/sys/sys/ipc.h b/sys/sys/ipc.h index 38892e9..1a153c5 100644 --- a/sys/sys/ipc.h +++ b/sys/sys/ipc.h @@ -85,6 +85,10 @@ struct ipc_perm { struct proc; int ipcperm __P((struct proc *, struct ipc_perm *, int)); +extern void (*semexit_hook)(struct proc *); +extern void (*shmfork_hook)(struct proc *, struct proc *); +extern void (*shmexit_hook)(struct proc *); + #else /* ! _KERNEL */ /* XXX doesn't really belong here, but has been historical practice in SysV. */ diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 8966354..011669b 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -291,4 +291,4 @@ #define SYS___cap_get_file 367 #define SYS___cap_set_fd 368 #define SYS___cap_set_file 369 -#define SYS_MAXSYSCALL 370 +#define SYS_MAXSYSCALL 371 diff --git a/sys/sys/sysent.h b/sys/sys/sysent.h index 93d356b..fca23e0 100644 --- a/sys/sys/sysent.h +++ b/sys/sys/sysent.h @@ -112,6 +112,15 @@ static moduledata_t name##_mod = { \ }; \ DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) +#define SYSCALL_MODULE_HELPER(syscallname, argcount) \ +static int syscallname##_syscall = SYS_##syscallname; \ +static struct sysent syscallname##_sysent = { \ + argcount, (sy_call_t *)& syscallname \ +}; \ +SYSCALL_MODULE(syscallname, \ + & syscallname##_syscall, & syscallname##_sysent, \ + NULL, NULL); + int syscall_register __P((int *offset, struct sysent *new_sysent, struct sysent *old_sysent)); int syscall_deregister __P((int *offset, struct sysent *old_sysent)); diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index dee4147..7e8abde 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -1280,6 +1280,7 @@ int __cap_get_fd __P((struct proc *, struct __cap_get_fd_args *)); int __cap_get_file __P((struct proc *, struct __cap_get_file_args *)); int __cap_set_fd __P((struct proc *, struct __cap_set_fd_args *)); int __cap_set_file __P((struct proc *, struct __cap_set_file_args *)); +int lkmressys __P((struct proc *, struct nosys_args *)); #ifdef COMPAT_43 |