diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-14 23:45:12 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2004-07-14 23:45:12 +0000 |
commit | 1f938370d0925923855d0aa555c61e0021e813d4 (patch) | |
tree | dd1070107bd0640c4efcc4942d08cd1a28e898ea | |
parent | 2936cdf8e0c9bb397150cbee125b4456fee40aab (diff) |
Because mode_t is used in struct ipc_perm we need new versions of
the msgctl, semctl, and shmctl system calls. This moves the old
versions to COMPAT_35 and adds new ones.
WARNING: While this fixes things like shared memory in the X server
for old (pre-mode_t change) binaries, it will break binaries that
use shared memory built between the time of the mode_t change (Jul
13th) and now. If you rebuild X during that interval you will need
to do it again after updating the rest of userland.
-rw-r--r-- | sys/compat/common/kern_ipc_35.c | 186 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 32 | ||||
-rw-r--r-- | sys/sys/ipc.h | 12 | ||||
-rw-r--r-- | sys/sys/msg.h | 20 | ||||
-rw-r--r-- | sys/sys/sem.h | 15 | ||||
-rw-r--r-- | sys/sys/shm.h | 14 |
6 files changed, 267 insertions, 12 deletions
diff --git a/sys/compat/common/kern_ipc_35.c b/sys/compat/common/kern_ipc_35.c index d3956b24070..b926fd866d5 100644 --- a/sys/compat/common/kern_ipc_35.c +++ b/sys/compat/common/kern_ipc_35.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ipc_35.c,v 1.1 2004/05/03 17:38:48 millert Exp $ */ +/* $OpenBSD: kern_ipc_35.c,v 1.2 2004/07/14 23:45:11 millert Exp $ */ /* * Copyright (c) 2004 Todd C. Miller <Todd.Miller@courtesan.com> @@ -20,6 +20,7 @@ #include <sys/systm.h> #include <sys/kernel.h> #include <sys/proc.h> +#include <sys/msg.h> #include <sys/sem.h> #include <sys/shm.h> @@ -77,3 +78,186 @@ compat_35_sys_semop(struct proc *p, void *v, register_t *retval) return (sys_semop(p, &semop_args, retval)); } #endif + +/* + * Convert between new and old struct {msq,sem,shm}id_ds (both ways) + */ +#if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM) +#define cvt_ds(to, from, type) do { \ + (to)->type##_perm.cuid = (from)->type##_perm.cuid; \ + (to)->type##_perm.cgid = (from)->type##_perm.cgid; \ + (to)->type##_perm.uid = (from)->type##_perm.uid; \ + (to)->type##_perm.gid = (from)->type##_perm.gid; \ + (to)->type##_perm.mode = (from)->type##_perm.mode & 0xffffU; \ + (to)->type##_perm.seq = (from)->type##_perm.seq; \ + (to)->type##_perm.key = (from)->type##_perm.key; \ + bcopy((caddr_t)(from) + sizeof((from)->type##_perm), \ + (caddr_t)(to) + sizeof((to)->type##_perm), \ + sizeof(*(to)) - sizeof((to)->type##_perm)); \ +} while (0) +#endif /* SYSVMSG || SYSVSEM || SYSVSHM */ + +#ifdef SYSVMSG +/* + * Copy a struct msqid_ds35 from userland and convert to struct msqid_ds + */ +static int +msqid_copyin(const void *uaddr, void *kaddr, size_t len) +{ + struct msqid_ds *msqbuf = kaddr; + struct msqid_ds35 omsqbuf; + int error; + + if (len != sizeof(struct msqid_ds)) + return (EFAULT); + if ((error = copyin(uaddr, &omsqbuf, sizeof(omsqbuf))) == 0) + cvt_ds(msqbuf, &omsqbuf, msg); + return (error); +} + +/* + * Convert a struct msqid_ds to struct msqid_ds35 and copy to userland + */ +static int +msqid_copyout(const void *kaddr, void *uaddr, size_t len) +{ + const struct msqid_ds *msqbuf = kaddr; + struct msqid_ds35 omsqbuf; + + if (len != sizeof(struct msqid_ds)) + return (EFAULT); + cvt_ds(&omsqbuf, msqbuf, msg); + return (copyout(&omsqbuf, uaddr, sizeof(omsqbuf))); +} + +/* + * OpenBSD 3.5 msgctl(2) with 16bit mode_t in struct ipcperm. + */ +int +compat_35_sys_msgctl(struct proc *p, void *v, register_t *retval) +{ + struct compat_35_sys_msgctl_args /* { + syscallarg(int) msqid; + syscallarg(int) cmd; + syscallarg(struct msqid_ds35 *) buf; + } */ *uap = v; + + return (msgctl1(p, SCARG(uap, msqid), SCARG(uap, cmd), + (caddr_t)SCARG(uap, buf), msqid_copyin, msqid_copyout)); +} +#endif /* SYSVMSG */ + +#ifdef SYSVSEM +/* + * Copy a struct semid_ds35 from userland and convert to struct semid_ds + */ +static int +semid_copyin(const void *uaddr, void *kaddr, size_t len) +{ + struct semid_ds *sembuf = kaddr; + struct semid_ds35 osembuf; + int error; + + if (len != sizeof(struct semid_ds)) + return (EFAULT); + if ((error = copyin(uaddr, &osembuf, sizeof(osembuf))) == 0) + cvt_ds(sembuf, &osembuf, sem); + return (error); +} + +/* + * Convert a struct semid_ds to struct semid_ds35 and copy to userland + */ +static int +semid_copyout(const void *kaddr, void *uaddr, size_t len) +{ + const struct semid_ds *sembuf = kaddr; + struct semid_ds35 osembuf; + + if (len != sizeof(struct semid_ds)) + return (EFAULT); + cvt_ds(&osembuf, sembuf, sem); + return (copyout(&osembuf, uaddr, sizeof(osembuf))); +} + +/* + * OpenBSD 3.5 semctl(2) with 16bit mode_t in struct ipcperm. + */ +int +compat_35_sys___semctl(struct proc *p, void *v, register_t *retval) +{ + struct compat_35_sys___semctl_args /* { + syscallarg(int) semid; + syscallarg(int) semnum; + syscallarg(int) cmd; + syscallarg(union semun *) arg; + } */ *uap = v; + union semun arg; + int error = 0, cmd = SCARG(uap, cmd); + + switch (cmd) { + case IPC_SET: + case IPC_STAT: + case GETALL: + case SETVAL: + case SETALL: + error = copyin(SCARG(uap, arg), &arg, sizeof(arg)); + break; + } + if (error == 0) { + error = semctl1(p, SCARG(uap, semid), SCARG(uap, semnum), + cmd, &arg, retval, semid_copyin, semid_copyout); + } + return (error); +} +#endif /* SYSVSEM */ + +#ifdef SYSVSHM +/* + * Copy a struct shmid_ds35 from userland and convert to struct shmid_ds + */ +static int +shmid_copyin(const void *uaddr, void *kaddr, size_t len) +{ + struct shmid_ds *shmbuf = kaddr; + struct shmid_ds35 oshmbuf; + int error; + + if (len != sizeof(struct shmid_ds)) + return (EFAULT); + if ((error = copyin(uaddr, &oshmbuf, sizeof(oshmbuf))) == 0) + cvt_ds(shmbuf, &oshmbuf, shm); + return (error); +} + +/* + * Convert a struct shmid_ds to struct shmid_ds35 and copy to userland + */ +static int +shmid_copyout(const void *kaddr, void *uaddr, size_t len) +{ + const struct shmid_ds *shmbuf = kaddr; + struct shmid_ds35 oshmbuf; + + if (len != sizeof(struct shmid_ds)) + return (EFAULT); + cvt_ds(&oshmbuf, shmbuf, shm); + return (copyout(&oshmbuf, uaddr, sizeof(oshmbuf))); +} + +/* + * OpenBSD 3.5 shmctl(2) with 16bit mode_t in struct ipcperm. + */ +int +compat_35_sys_shmctl(struct proc *p, void *v, register_t *retval) +{ + struct compat_35_sys_shmctl_args /* { + syscallarg(int) shmid; + syscallarg(int) cmd; + syscallarg(struct shmid_ds35 *) buf; + } */ *uap = v; + + return (shmctl1(p, SCARG(uap, shmid), SCARG(uap, cmd), + (caddr_t)SCARG(uap, buf), shmid_copyin, shmid_copyout)); +} +#endif /* SYSVSHM */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 4b47fa325b7..2c8052a6b56 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.73 2004/07/14 18:00:48 millert Exp $ +; $OpenBSD: syscalls.master,v 1.74 2004/07/14 23:45:11 millert Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -497,20 +497,20 @@ 255 STD { pid_t sys_getsid(pid_t pid); } 256 STD { int sys_msync(void *addr, size_t len, int flags); } #ifdef SYSVSEM -257 STD { int sys___semctl(int semid, int semnum, int cmd, \ - union semun *arg); } +257 COMPAT_35 { int sys___semctl(int semid, int semnum, int cmd, \ + union semun *arg); } semctl35 #else 257 UNIMPL #endif #ifdef SYSVSHM -258 STD { int sys_shmctl(int shmid, int cmd, \ - struct shmid_ds *buf); } +258 COMPAT_35 { int sys_shmctl(int shmid, int cmd, \ + struct shmid_ds35 *buf); } shmctl35 #else 258 UNIMPL #endif #ifdef SYSVMSG -259 STD { int sys_msgctl(int msqid, int cmd, \ - struct msqid_ds *buf); } +259 COMPAT_35 { int sys_msgctl(int msqid, int cmd, \ + struct msqid_ds35 *buf); } msgctl35 #else 259 UNIMPL #endif @@ -598,3 +598,21 @@ 293 STD { int sys_lstat(const char *path, struct stat *ub); } 294 STD { int sys_fhstat(const fhandle_t *fhp, \ struct stat *sb); } +#ifdef SYSVSEM +295 STD { int sys___semctl(int semid, int semnum, int cmd, \ + union semun *arg); } +#else +295 UNIMPL +#endif +#ifdef SYSVSHM +296 STD { int sys_shmctl(int shmid, int cmd, \ + struct shmid_ds *buf); } +#else +296 UNIMPL +#endif +#ifdef SYSVMSG +297 STD { int sys_msgctl(int msqid, int cmd, \ + struct msqid_ds *buf); } +#else +297 UNIMPL +#endif diff --git a/sys/sys/ipc.h b/sys/sys/ipc.h index 782ba538c1e..948fdfac8ee 100644 --- a/sys/sys/ipc.h +++ b/sys/sys/ipc.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ipc.h,v 1.8 2003/06/02 23:28:21 millert Exp $ */ +/* $OpenBSD: ipc.h,v 1.9 2004/07/14 23:45:11 millert Exp $ */ /* $NetBSD: ipc.h,v 1.15 1996/02/09 18:25:12 christos Exp $ */ /* @@ -68,6 +68,16 @@ struct oipc_perm { unsigned short seq; /* sequence # (to generate unique msg/sem/shm id) */ key_t key; /* user specified msg/sem/shm key */ }; + +struct ipc_perm35 { + uid_t cuid; /* creator user id */ + gid_t cgid; /* creator group id */ + uid_t uid; /* user id */ + gid_t gid; /* group id */ + u_int16_t mode; /* r/w permission */ + unsigned short seq; /* sequence # (to generate unique msg/sem/shm id) */ + key_t key; /* user specified msg/sem/shm key */ +}; #endif /* common mode bits */ diff --git a/sys/sys/msg.h b/sys/sys/msg.h index ade0d67acb4..7a59ad90ee6 100644 --- a/sys/sys/msg.h +++ b/sys/sys/msg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: msg.h,v 1.11 2004/07/14 23:40:27 millert Exp $ */ +/* $OpenBSD: msg.h,v 1.12 2004/07/14 23:45:11 millert Exp $ */ /* $NetBSD: msg.h,v 1.9 1996/02/09 18:25:18 christos Exp $ */ /* @@ -68,6 +68,24 @@ struct omsqid_ds { long msg_pad3; long msg_pad4[4]; }; + +struct msqid_ds35 { + struct ipc_perm35 msg_perm; /* msg queue permission bits */ + struct msg *msg_first; /* first message in the queue */ + struct msg *msg_last; /* last message in the queue */ + unsigned long msg_cbytes; /* number of bytes in use on queue */ + unsigned long msg_qnum; /* number of msgs in the queue */ + unsigned long msg_qbytes; /* max # of bytes on the queue */ + pid_t msg_lspid; /* pid of last msgsnd() */ + pid_t msg_lrpid; /* pid of last msgrcv() */ + time_t msg_stime; /* time of last msgsnd() */ + long msg_pad1; + time_t msg_rtime; /* time of last msgrcv() */ + long msg_pad2; + time_t msg_ctime; /* time of last msgctl() */ + long msg_pad3; + long msg_pad4[4]; +}; #endif struct msg { diff --git a/sys/sys/sem.h b/sys/sys/sem.h index c5cea91e629..1414f7ca149 100644 --- a/sys/sys/sem.h +++ b/sys/sys/sem.h @@ -1,4 +1,4 @@ -/* $OpenBSD: sem.h,v 1.16 2004/07/14 23:40:27 millert Exp $ */ +/* $OpenBSD: sem.h,v 1.17 2004/07/14 23:45:11 millert Exp $ */ /* $NetBSD: sem.h,v 1.8 1996/02/09 18:25:29 christos Exp $ */ /* @@ -77,6 +77,19 @@ struct osemid_ds { long sem_pad2; /* SVABI/386 says I need this here */ long sem_pad3[4]; /* SVABI/386 says I need this here */ }; + +struct semid_ds35 { + struct ipc_perm35 sem_perm; /* operation permission struct */ + struct sem *sem_base; /* pointer to first semaphore in set */ + unsigned short sem_nsems; /* number of sems in set */ + time_t sem_otime; /* last operation time */ + long sem_pad1; /* SVABI/386 says I need this here */ + time_t sem_ctime; /* last change time */ + /* Times measured in secs since */ + /* 00:00:00 GMT, Jan. 1, 1970 */ + long sem_pad2; /* SVABI/386 says I need this here */ + long sem_pad3[4]; /* SVABI/386 says I need this here */ +}; #endif /* diff --git a/sys/sys/shm.h b/sys/sys/shm.h index 43a6c8bc44f..aeb99f385c4 100644 --- a/sys/sys/shm.h +++ b/sys/sys/shm.h @@ -1,4 +1,4 @@ -/* $OpenBSD: shm.h,v 1.17 2004/07/14 23:40:27 millert Exp $ */ +/* $OpenBSD: shm.h,v 1.18 2004/07/14 23:45:11 millert Exp $ */ /* $NetBSD: shm.h,v 1.20 1996/04/09 20:55:35 cgd Exp $ */ /* @@ -120,6 +120,18 @@ struct oshmid_ds { time_t shm_ctime; /* time of last change by shmctl() */ void *shm_internal; /* implementation specific data */ }; + +struct shmid_ds35 { + struct ipc_perm35 shm_perm; /* operation permission structure */ + int shm_segsz; /* size of segment in bytes */ + pid_t shm_lpid; /* process ID of last shm op */ + pid_t shm_cpid; /* process ID of creator */ + shmatt_t shm_nattch; /* number of current attaches */ + time_t shm_atime; /* time of last shmat() */ + time_t shm_dtime; /* time of last shmdt() */ + time_t shm_ctime; /* time of last change by shmctl() */ + void *shm_internal;/* implementation specific data */ +}; #endif #if !defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE) |