summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2004-07-14 23:45:12 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2004-07-14 23:45:12 +0000
commit1f938370d0925923855d0aa555c61e0021e813d4 (patch)
treedd1070107bd0640c4efcc4942d08cd1a28e898ea
parent2936cdf8e0c9bb397150cbee125b4456fee40aab (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.c186
-rw-r--r--sys/kern/syscalls.master32
-rw-r--r--sys/sys/ipc.h12
-rw-r--r--sys/sys/msg.h20
-rw-r--r--sys/sys/sem.h15
-rw-r--r--sys/sys/shm.h14
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)