Change the ABI of some of the structures used by the SYSV IPC API:

- The uid/cuid members of struct ipc_perm are now uid_t instead of unsigned
  short.
- The gid/cgid members of struct ipc_perm are now gid_t instead of unsigned
  short.
- The mode member of struct ipc_perm is now mode_t instead of unsigned short
  (this is merely a style bug).
- The rather dubious padding fields for ABI compat with SV/I386 have been
  removed from struct msqid_ds and struct semid_ds.
- The shm_segsz member of struct shmid_ds is now a size_t instead of an
  int.  This removes the need for the shm_bsegsz member in struct
  shmid_kernel and should allow for complete support of SYSV SHM regions
  >= 2GB.
- The shm_nattch member of struct shmid_ds is now an int instead of a
  short.
- The shm_internal member of struct shmid_ds is now gone.  The internal
  VM object pointer for SHM regions has been moved into struct
  shmid_kernel.
- The existing __semctl(), msgctl(), and shmctl() system call entries are
  now marked COMPAT7 and new versions of those system calls which support
  the new ABI are now present.
- The new system calls are assigned to the FBSD-1.1 version in libc.  The
  FBSD-1.0 symbols in libc now refer to the old COMPAT7 system calls.
- A simplistic framework for tagging system calls with compatibility
  symbol versions has been added to libc.  Version tags are added to
  system calls by adding an appropriate __sym_compat() entry to
  src/lib/libc/incldue/compat.h. [1]

PR:		kern/16195 kern/113218 bin/129855
Reviewed by:	arch@, rwatson
Discussed with:	kan, kib [1]
This commit is contained in:
John Baldwin 2009-06-24 21:10:52 +00:00
parent 8c5d766cd7
commit b648d4806b
21 changed files with 818 additions and 129 deletions

View File

@ -247,7 +247,6 @@ FBSD_1.0 {
sem_timedwait;
sem_post;
sem_getvalue;
semctl;
setdomainname;
sethostname;
longjmperror;
@ -362,6 +361,7 @@ FBSD_1.1 {
posix_spawnattr_setsigdefault;
posix_spawnattr_setsigmask;
posix_spawnp;
semctl;
tcgetsid;
tcsetsid;
};

View File

@ -29,15 +29,19 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _WANT_SEMUN_OLD
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdarg.h>
#include <stdlib.h>
extern int __semctl(int semid, int semnum, int cmd, union semun *arg);
int __semctl(int semid, int semnum, int cmd, union semun *arg);
int freebsd7___semctl(int semid, int semnum, int cmd, union semun_old *arg);
int semctl(int semid, int semnum, int cmd, ...)
int
semctl(int semid, int semnum, int cmd, ...)
{
va_list ap;
union semun semun;
@ -55,3 +59,25 @@ int semctl(int semid, int semnum, int cmd, ...)
return (__semctl(semid, semnum, cmd, semun_ptr));
}
int
freebsd7_semctl(int semid, int semnum, int cmd, ...)
{
va_list ap;
union semun_old semun;
union semun_old *semun_ptr;
va_start(ap, cmd);
if (cmd == IPC_SET || cmd == IPC_STAT || cmd == GETALL
|| cmd == SETVAL || cmd == SETALL) {
semun = va_arg(ap, union semun_old);
semun_ptr = &semun;
} else {
semun_ptr = NULL;
}
va_end(ap);
return (freebsd7___semctl(semid, semnum, cmd, semun_ptr));
}
__sym_compat(semctl, freebsd7_semctl, FBSD_1.0);

48
lib/libc/include/compat.h Normal file
View File

@ -0,0 +1,48 @@
/*-
* Copyright (c) 2009 Advanced Computing Technologies LLC
* Written by: John H. Baldwin <jhb@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/*
* This file defines compatiblity symbol versions for old system calls. It
* is included in all generated system call files.
*/
#ifndef __LIBC_COMPAT_H__
#define __LIBC_COMPAT_H__
#define __sym_compat(sym,impl,verid) \
.symver impl , sym @ verid
__sym_compat(__semctl, freebsd7___semctl, FBSD_1.0);
__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0);
__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0);
#undef __sym_compat
#endif /* __LIBC_COMPAT_H__ */

View File

@ -53,11 +53,13 @@ SYM_MAPS+= ${.CURDIR}/sys/Symbol.map
CLEANFILES+= ${SASM} ${SPSEUDO}
${SASM}:
printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' > ${.TARGET}
printf '#include "compat.h"\n' > ${.TARGET}
printf '#include "SYS.h"\nRSYSCALL(${.PREFIX})\n' >> ${.TARGET}
${SPSEUDO}:
printf '#include "compat.h"\n' > ${.TARGET}
printf '#include "SYS.h"\nPSEUDO(${.PREFIX:S/_//})\n' \
> ${.TARGET}
>> ${.TARGET}
MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \
aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \

View File

@ -31,7 +31,6 @@ FBSD_1.0 {
__mac_set_file;
__mac_set_link;
__mac_set_proc;
__semctl;
__setugid;
__syscall;
__sysctl;
@ -184,7 +183,6 @@ FBSD_1.0 {
modstat;
mount;
mprotect;
msgctl;
msgget;
msgrcv;
msgsnd;
@ -267,7 +265,6 @@ FBSD_1.0 {
shm_open;
shm_unlink;
shmat;
shmctl;
shmdt;
shmget;
shmsys;
@ -332,6 +329,7 @@ FBSD_1.0 {
};
FBSD_1.1 {
__semctl;
closefrom;
cpuset;
cpuset_getid;
@ -351,10 +349,12 @@ FBSD_1.1 {
mkdirat;
mkfifoat;
mknodat;
msgctl;
openat;
readlinkat;
renameat;
setfib;
shmctl;
symlinkat;
unlinkat;
};

View File

@ -30,11 +30,11 @@
#define _COMPAT_FREEBSD32_FREEBSD32_IPC_H_
struct ipc_perm32 {
uint16_t cuid;
uint16_t cgid;
uint16_t uid;
uint16_t gid;
uint16_t mode;
uid_t cuid;
gid_t cgid;
uid_t uid;
gid_t gid;
mode_t mode;
uint16_t seq;
uint32_t key;
};
@ -44,10 +44,7 @@ struct semid_ds32 {
uint32_t sem_base;
unsigned short sem_nsems;
int32_t sem_otime;
int32_t sem_pad1;
int32_t sem_ctime;
int32_t sem_pad2;
int32_t sem_pad3[4];
};
union semun32 {
@ -66,24 +63,19 @@ struct msqid_ds32 {
pid_t msg_lspid;
pid_t msg_lrpid;
int32_t msg_stime;
int32_t msg_pad1;
int32_t msg_rtime;
int32_t msg_pad2;
int32_t msg_ctime;
int32_t msg_pad3;
int32_t msg_pad4[4];
};
struct shmid_ds32 {
struct ipc_perm32 shm_perm;
int32_t shm_segsz;
int32_t shm_lpid;
int32_t shm_cpid;
int16_t shm_nattch;
pid_t shm_lpid;
pid_t shm_cpid;
int shm_nattch;
int32_t shm_atime;
int32_t shm_dtime;
int32_t shm_ctime;
uint32_t shm_internal;
};
struct shm_info32 {
@ -103,4 +95,58 @@ struct shminfo32 {
uint32_t shmall;
};
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
struct ipc_perm32_old {
uint16_t cuid;
uint16_t cgid;
uint16_t uid;
uint16_t gid;
uint16_t mode;
uint16_t seq;
uint32_t key;
};
struct semid_ds32_old {
struct ipc_perm32_old sem_perm;
uint32_t sem_base;
unsigned short sem_nsems;
int32_t sem_otime;
int32_t sem_pad1;
int32_t sem_ctime;
int32_t sem_pad2;
int32_t sem_pad3[4];
};
struct msqid_ds32_old {
struct ipc_perm32_old msg_perm;
uint32_t msg_first;
uint32_t msg_last;
uint32_t msg_cbytes;
uint32_t msg_qnum;
uint32_t msg_qbytes;
pid_t msg_lspid;
pid_t msg_lrpid;
int32_t msg_stime;
int32_t msg_pad1;
int32_t msg_rtime;
int32_t msg_pad2;
int32_t msg_ctime;
int32_t msg_pad3;
int32_t msg_pad4[4];
};
struct shmid_ds32_old {
struct ipc_perm32_old shm_perm;
int32_t shm_segsz;
pid_t shm_lpid;
pid_t shm_cpid;
int16_t shm_nattch;
int32_t shm_atime;
int32_t shm_dtime;
int32_t shm_ctime;
uint32_t shm_internal;
};
#endif
#endif /* !_COMPAT_FREEBSD32_FREEBSD32_IPC_H_ */

View File

@ -1353,6 +1353,35 @@ freebsd4_freebsd32_fhstatfs(struct thread *td, struct freebsd4_freebsd32_fhstatf
}
#endif
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
static void
freebsd32_ipcperm_old_in(struct ipc_perm32_old *ip32, struct ipc_perm *ip)
{
CP(*ip32, *ip, cuid);
CP(*ip32, *ip, cgid);
CP(*ip32, *ip, uid);
CP(*ip32, *ip, gid);
CP(*ip32, *ip, mode);
CP(*ip32, *ip, seq);
CP(*ip32, *ip, key);
}
static void
freebsd32_ipcperm_old_out(struct ipc_perm *ip, struct ipc_perm32_old *ip32)
{
CP(*ip, *ip32, cuid);
CP(*ip, *ip32, cgid);
CP(*ip, *ip32, uid);
CP(*ip, *ip32, gid);
CP(*ip, *ip32, mode);
CP(*ip, *ip32, seq);
CP(*ip, *ip32, key);
}
#endif
static void
freebsd32_ipcperm_in(struct ipc_perm32 *ip32, struct ipc_perm *ip)
{
@ -1383,6 +1412,8 @@ int
freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
{
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
switch (uap->which) {
case 0:
return (freebsd32_semctl(td,
@ -1390,8 +1421,86 @@ freebsd32_semsys(struct thread *td, struct freebsd32_semsys_args *uap)
default:
return (semsys(td, (struct semsys_args *)uap));
}
#else
return (nosys(td, NULL));
#endif
}
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
int
freebsd7_freebsd32_semctl(struct thread *td,
struct freebsd7_freebsd32_semctl_args *uap)
{
struct semid_ds32_old dsbuf32;
struct semid_ds dsbuf;
union semun semun;
union semun32 arg;
register_t rval;
int error;
switch (uap->cmd) {
case SEM_STAT:
case IPC_SET:
case IPC_STAT:
case GETALL:
case SETVAL:
case SETALL:
error = copyin(uap->arg, &arg, sizeof(arg));
if (error)
return (error);
break;
}
switch (uap->cmd) {
case SEM_STAT:
case IPC_STAT:
semun.buf = &dsbuf;
break;
case IPC_SET:
error = copyin(PTRIN(arg.buf), &dsbuf32, sizeof(dsbuf32));
if (error)
return (error);
freebsd32_ipcperm_old_in(&dsbuf32.sem_perm, &dsbuf.sem_perm);
PTRIN_CP(dsbuf32, dsbuf, sem_base);
CP(dsbuf32, dsbuf, sem_nsems);
CP(dsbuf32, dsbuf, sem_otime);
CP(dsbuf32, dsbuf, sem_ctime);
semun.buf = &dsbuf;
break;
case GETALL:
case SETALL:
semun.array = PTRIN(arg.array);
break;
case SETVAL:
semun.val = arg.val;
break;
}
error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
&rval);
if (error)
return (error);
switch (uap->cmd) {
case SEM_STAT:
case IPC_STAT:
bzero(&dsbuf32, sizeof(dsbuf32));
freebsd32_ipcperm_old_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
PTROUT_CP(dsbuf, dsbuf32, sem_base);
CP(dsbuf, dsbuf32, sem_nsems);
CP(dsbuf, dsbuf32, sem_otime);
CP(dsbuf, dsbuf32, sem_ctime);
error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
break;
}
if (error == 0)
td->td_retval[0] = rval;
return (error);
}
#endif
int
freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
{
@ -1428,13 +1537,7 @@ freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
PTRIN_CP(dsbuf32, dsbuf, sem_base);
CP(dsbuf32, dsbuf, sem_nsems);
CP(dsbuf32, dsbuf, sem_otime);
CP(dsbuf32, dsbuf, sem_pad1);
CP(dsbuf32, dsbuf, sem_ctime);
CP(dsbuf32, dsbuf, sem_pad2);
CP(dsbuf32, dsbuf, sem_pad3[0]);
CP(dsbuf32, dsbuf, sem_pad3[1]);
CP(dsbuf32, dsbuf, sem_pad3[2]);
CP(dsbuf32, dsbuf, sem_pad3[3]);
semun.buf = &dsbuf;
break;
case GETALL:
@ -1454,17 +1557,12 @@ freebsd32_semctl(struct thread *td, struct freebsd32_semctl_args *uap)
switch (uap->cmd) {
case SEM_STAT:
case IPC_STAT:
bzero(&dsbuf32, sizeof(dsbuf32));
freebsd32_ipcperm_out(&dsbuf.sem_perm, &dsbuf32.sem_perm);
PTROUT_CP(dsbuf, dsbuf32, sem_base);
CP(dsbuf, dsbuf32, sem_nsems);
CP(dsbuf, dsbuf32, sem_otime);
CP(dsbuf, dsbuf32, sem_pad1);
CP(dsbuf, dsbuf32, sem_ctime);
CP(dsbuf, dsbuf32, sem_pad2);
CP(dsbuf, dsbuf32, sem_pad3[0]);
CP(dsbuf, dsbuf32, sem_pad3[1]);
CP(dsbuf, dsbuf32, sem_pad3[2]);
CP(dsbuf, dsbuf32, sem_pad3[3]);
error = copyout(&dsbuf32, PTRIN(arg.buf), sizeof(dsbuf32));
break;
}
@ -1478,6 +1576,8 @@ int
freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
{
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
switch (uap->which) {
case 0:
return (freebsd32_msgctl(td,
@ -1491,8 +1591,59 @@ freebsd32_msgsys(struct thread *td, struct freebsd32_msgsys_args *uap)
default:
return (msgsys(td, (struct msgsys_args *)uap));
}
#else
return (nosys(td, NULL));
#endif
}
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
int
freebsd7_freebsd32_msgctl(struct thread *td,
struct freebsd7_freebsd32_msgctl_args *uap)
{
struct msqid_ds msqbuf;
struct msqid_ds32_old msqbuf32;
int error;
if (uap->cmd == IPC_SET) {
error = copyin(uap->buf, &msqbuf32, sizeof(msqbuf32));
if (error)
return (error);
freebsd32_ipcperm_old_in(&msqbuf32.msg_perm, &msqbuf.msg_perm);
PTRIN_CP(msqbuf32, msqbuf, msg_first);
PTRIN_CP(msqbuf32, msqbuf, msg_last);
CP(msqbuf32, msqbuf, msg_cbytes);
CP(msqbuf32, msqbuf, msg_qnum);
CP(msqbuf32, msqbuf, msg_qbytes);
CP(msqbuf32, msqbuf, msg_lspid);
CP(msqbuf32, msqbuf, msg_lrpid);
CP(msqbuf32, msqbuf, msg_stime);
CP(msqbuf32, msqbuf, msg_rtime);
CP(msqbuf32, msqbuf, msg_ctime);
}
error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
if (error)
return (error);
if (uap->cmd == IPC_STAT) {
bzero(&msqbuf32, sizeof(msqbuf32));
freebsd32_ipcperm_old_out(&msqbuf.msg_perm, &msqbuf32.msg_perm);
PTROUT_CP(msqbuf, msqbuf32, msg_first);
PTROUT_CP(msqbuf, msqbuf32, msg_last);
CP(msqbuf, msqbuf32, msg_cbytes);
CP(msqbuf, msqbuf32, msg_qnum);
CP(msqbuf, msqbuf32, msg_qbytes);
CP(msqbuf, msqbuf32, msg_lspid);
CP(msqbuf, msqbuf32, msg_lrpid);
CP(msqbuf, msqbuf32, msg_stime);
CP(msqbuf, msqbuf32, msg_rtime);
CP(msqbuf, msqbuf32, msg_ctime);
error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
}
return (error);
}
#endif
int
freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
{
@ -1513,15 +1664,8 @@ freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
CP(msqbuf32, msqbuf, msg_lspid);
CP(msqbuf32, msqbuf, msg_lrpid);
CP(msqbuf32, msqbuf, msg_stime);
CP(msqbuf32, msqbuf, msg_pad1);
CP(msqbuf32, msqbuf, msg_rtime);
CP(msqbuf32, msqbuf, msg_pad2);
CP(msqbuf32, msqbuf, msg_ctime);
CP(msqbuf32, msqbuf, msg_pad3);
CP(msqbuf32, msqbuf, msg_pad4[0]);
CP(msqbuf32, msqbuf, msg_pad4[1]);
CP(msqbuf32, msqbuf, msg_pad4[2]);
CP(msqbuf32, msqbuf, msg_pad4[3]);
}
error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
if (error)
@ -1536,15 +1680,8 @@ freebsd32_msgctl(struct thread *td, struct freebsd32_msgctl_args *uap)
CP(msqbuf, msqbuf32, msg_lspid);
CP(msqbuf, msqbuf32, msg_lrpid);
CP(msqbuf, msqbuf32, msg_stime);
CP(msqbuf, msqbuf32, msg_pad1);
CP(msqbuf, msqbuf32, msg_rtime);
CP(msqbuf, msqbuf32, msg_pad2);
CP(msqbuf, msqbuf32, msg_ctime);
CP(msqbuf, msqbuf32, msg_pad3);
CP(msqbuf, msqbuf32, msg_pad4[0]);
CP(msqbuf, msqbuf32, msg_pad4[1]);
CP(msqbuf, msqbuf32, msg_pad4[2]);
CP(msqbuf, msqbuf32, msg_pad4[3]);
error = copyout(&msqbuf32, uap->buf, sizeof(struct msqid_ds32));
}
return (error);
@ -1588,6 +1725,8 @@ int
freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
{
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
switch (uap->which) {
case 0: { /* shmat */
struct shmat_args ap;
@ -1623,8 +1762,99 @@ freebsd32_shmsys(struct thread *td, struct freebsd32_shmsys_args *uap)
default:
return (EINVAL);
}
#else
return (nosys(td, NULL));
#endif
}
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
int
freebsd7_freebsd32_shmctl(struct thread *td,
struct freebsd7_freebsd32_shmctl_args *uap)
{
int error = 0;
union {
struct shmid_ds shmid_ds;
struct shm_info shm_info;
struct shminfo shminfo;
} u;
union {
struct shmid_ds32_old shmid_ds32;
struct shm_info32 shm_info32;
struct shminfo32 shminfo32;
} u32;
size_t sz;
if (uap->cmd == IPC_SET) {
if ((error = copyin(uap->buf, &u32.shmid_ds32,
sizeof(u32.shmid_ds32))))
goto done;
freebsd32_ipcperm_old_in(&u32.shmid_ds32.shm_perm,
&u.shmid_ds.shm_perm);
CP(u32.shmid_ds32, u.shmid_ds, shm_segsz);
CP(u32.shmid_ds32, u.shmid_ds, shm_lpid);
CP(u32.shmid_ds32, u.shmid_ds, shm_cpid);
CP(u32.shmid_ds32, u.shmid_ds, shm_nattch);
CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
}
error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
if (error)
goto done;
/* Cases in which we need to copyout */
switch (uap->cmd) {
case IPC_INFO:
CP(u.shminfo, u32.shminfo32, shmmax);
CP(u.shminfo, u32.shminfo32, shmmin);
CP(u.shminfo, u32.shminfo32, shmmni);
CP(u.shminfo, u32.shminfo32, shmseg);
CP(u.shminfo, u32.shminfo32, shmall);
error = copyout(&u32.shminfo32, uap->buf,
sizeof(u32.shminfo32));
break;
case SHM_INFO:
CP(u.shm_info, u32.shm_info32, used_ids);
CP(u.shm_info, u32.shm_info32, shm_rss);
CP(u.shm_info, u32.shm_info32, shm_tot);
CP(u.shm_info, u32.shm_info32, shm_swp);
CP(u.shm_info, u32.shm_info32, swap_attempts);
CP(u.shm_info, u32.shm_info32, swap_successes);
error = copyout(&u32.shm_info32, uap->buf,
sizeof(u32.shm_info32));
break;
case SHM_STAT:
case IPC_STAT:
freebsd32_ipcperm_old_out(&u.shmid_ds.shm_perm,
&u32.shmid_ds32.shm_perm);
if (u.shmid_ds.shm_segsz > INT32_MAX)
u32.shmid_ds32.shm_segsz = INT32_MAX;
else
CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
u32.shmid_ds32.shm_internal = 0;
error = copyout(&u32.shmid_ds32, uap->buf,
sizeof(u32.shmid_ds32));
break;
}
done:
if (error) {
/* Invalidate the return value */
td->td_retval[0] = -1;
}
return (error);
}
#endif
int
freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
{
@ -1654,7 +1884,6 @@ freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
CP(u32.shmid_ds32, u.shmid_ds, shm_atime);
CP(u32.shmid_ds32, u.shmid_ds, shm_dtime);
CP(u32.shmid_ds32, u.shmid_ds, shm_ctime);
PTRIN_CP(u32.shmid_ds32, u.shmid_ds, shm_internal);
}
error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&u, &sz);
@ -1686,14 +1915,16 @@ freebsd32_shmctl(struct thread *td, struct freebsd32_shmctl_args *uap)
case IPC_STAT:
freebsd32_ipcperm_out(&u.shmid_ds.shm_perm,
&u32.shmid_ds32.shm_perm);
CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
if (u.shmid_ds.shm_segsz > INT32_MAX)
u32.shmid_ds32.shm_segsz = INT32_MAX;
else
CP(u.shmid_ds, u32.shmid_ds32, shm_segsz);
CP(u.shmid_ds, u32.shmid_ds32, shm_lpid);
CP(u.shmid_ds, u32.shmid_ds32, shm_cpid);
CP(u.shmid_ds, u32.shmid_ds32, shm_nattch);
CP(u.shmid_ds, u32.shmid_ds32, shm_atime);
CP(u.shmid_ds, u32.shmid_ds32, shm_dtime);
CP(u.shmid_ds, u32.shmid_ds32, shm_ctime);
PTROUT_CP(u.shmid_ds, u32.shmid_ds32, shm_internal);
error = copyout(&u32.shmid_ds32, uap->buf,
sizeof(u32.shmid_ds32));
break;

View File

@ -405,15 +405,15 @@
; The following were introduced with NetBSD/4.4Lite-2
; They are initialized by thier respective modules/sysinits
; XXX PROBLEM!!
220 AUE_SEMCTL STD { int freebsd32_semctl(int semid, int semnum, \
220 AUE_SEMCTL COMPAT7 { int freebsd32_semctl(int semid, int semnum, \
int cmd, union semun32 *arg); }
221 AUE_SEMGET NOPROTO { int semget(key_t key, int nsems, \
int semflg); }
222 AUE_SEMOP NOPROTO { int semop(int semid, struct sembuf *sops, \
u_int nsops); }
223 AUE_NULL UNIMPL semconfig
224 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \
struct msqid_ds32 *buf); }
224 AUE_MSGCTL COMPAT7 { int freebsd32_msgctl(int msqid, int cmd, \
struct msqid_ds32_old *buf); }
225 AUE_MSGGET NOPROTO { int msgget(key_t key, int msgflg); }
226 AUE_MSGSND STD { int freebsd32_msgsnd(int msqid, void *msgp, \
size_t msgsz, int msgflg); }
@ -421,8 +421,8 @@
size_t msgsz, long msgtyp, int msgflg); }
228 AUE_SHMAT NOPROTO { int shmat(int shmid, void *shmaddr, \
int shmflg); }
229 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds *buf); }
229 AUE_SHMCTL COMPAT7 { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32_old *buf); }
230 AUE_SHMDT NOPROTO { int shmdt(void *shmaddr); }
231 AUE_SHMGET NOPROTO { int shmget(key_t key, int size, \
int shmflg); }
@ -894,3 +894,9 @@
unsigned int iovcnt, int flags); }
508 AUE_NULL NOPROTO { int jail_remove(int jid); }
509 AUE_CLOSEFROM NOPROTO { int closefrom(int lowfd); }
510 AUE_SEMCTL STD { int freebsd32_semctl(int semid, int semnum, \
int cmd, union semun32 *arg); }
511 AUE_MSGCTL STD { int freebsd32_msgctl(int msqid, int cmd, \
struct msqid_ds32 *buf); }
512 AUE_SHMCTL STD { int freebsd32_shmctl(int shmid, int cmd, \
struct shmid_ds32 *buf); }

View File

@ -230,23 +230,26 @@ linux_to_bsd_shmid_ds(struct l_shmid_ds *lsp, struct shmid_ds *bsp)
bsp->shm_atime = lsp->shm_atime;
bsp->shm_dtime = lsp->shm_dtime;
bsp->shm_ctime = lsp->shm_ctime;
/* this goes (yet) SOS */
bsp->shm_internal = PTRIN(lsp->private3);
}
static void
bsd_to_linux_shmid_ds(struct shmid_ds *bsp, struct l_shmid_ds *lsp)
{
bsd_to_linux_ipc_perm(&bsp->shm_perm, &lsp->shm_perm);
lsp->shm_segsz = bsp->shm_segsz;
if (bsp->shm_segsz > INT_MAX)
lsp->shm_segsz = INT_MAX;
else
lsp->shm_segsz = bsp->shm_segsz;
lsp->shm_lpid = bsp->shm_lpid;
lsp->shm_cpid = bsp->shm_cpid;
lsp->shm_nattch = bsp->shm_nattch;
if (bsp->shm_nattch > SHRT_MAX)
lsp->shm_nattch = SHRT_MAX;
else
lsp->shm_nattch = bsp->shm_nattch;
lsp->shm_atime = bsp->shm_atime;
lsp->shm_dtime = bsp->shm_dtime;
lsp->shm_ctime = bsp->shm_ctime;
/* this goes (yet) SOS */
lsp->private3 = PTROUT(bsp->shm_internal);
lsp->private3 = 0;
}
static void
@ -424,6 +427,15 @@ linux_shmid_pushdown(l_int ver, struct l_shmid_ds *linux_shmid, caddr_t uaddr)
{
struct l_shmid64_ds linux_shmid64;
/*
* XXX: This is backwards and loses information in shm_nattch
* and shm_segsz. We should probably either expose the BSD
* shmid structure directly and convert it to either the
* non-64 or 64 variant directly or the code should always
* convert to the 64 variant and then truncate values into the
* non-64 variant if needed since the 64 variant has more
* precision.
*/
if (ver == LINUX_IPC_64) {
bzero(&linux_shmid64, sizeof(linux_shmid64));

View File

@ -169,13 +169,12 @@ bsd_to_svr4_semid_ds(bds, sds)
const struct semid_ds *bds;
struct svr4_semid_ds *sds;
{
bzero(sds, sizeof(*sds));
bsd_to_svr4_ipc_perm(&bds->sem_perm, &sds->sem_perm);
sds->sem_base = (struct svr4_sem *) bds->sem_base;
sds->sem_nsems = bds->sem_nsems;
sds->sem_otime = bds->sem_otime;
sds->sem_pad1 = bds->sem_pad1;
sds->sem_ctime = bds->sem_ctime;
sds->sem_pad2 = bds->sem_pad2;
}
static void
@ -187,9 +186,7 @@ svr4_to_bsd_semid_ds(sds, bds)
bds->sem_base = (struct sem *) bds->sem_base;
bds->sem_nsems = sds->sem_nsems;
bds->sem_otime = sds->sem_otime;
bds->sem_pad1 = sds->sem_pad1;
bds->sem_ctime = sds->sem_ctime;
bds->sem_pad2 = sds->sem_pad2;
}
struct svr4_sys_semctl_args {
@ -350,6 +347,7 @@ bsd_to_svr4_msqid_ds(bds, sds)
const struct msqid_ds *bds;
struct svr4_msqid_ds *sds;
{
bzero(sds, sizeof(*sds));
bsd_to_svr4_ipc_perm(&bds->msg_perm, &sds->msg_perm);
sds->msg_first = (struct svr4_msg *) bds->msg_first;
sds->msg_last = (struct svr4_msg *) bds->msg_last;
@ -359,18 +357,8 @@ bsd_to_svr4_msqid_ds(bds, sds)
sds->msg_lspid = bds->msg_lspid;
sds->msg_lrpid = bds->msg_lrpid;
sds->msg_stime = bds->msg_stime;
sds->msg_pad1 = bds->msg_pad1;
sds->msg_rtime = bds->msg_rtime;
sds->msg_pad2 = bds->msg_pad2;
sds->msg_ctime = bds->msg_ctime;
sds->msg_pad3 = bds->msg_pad3;
/* use the padding for the rest of the fields */
{
const short *pad = (const short *) bds->msg_pad4;
sds->msg_cv = pad[0];
sds->msg_qnum_cv = pad[1];
}
}
static void
@ -387,18 +375,8 @@ svr4_to_bsd_msqid_ds(sds, bds)
bds->msg_lspid = sds->msg_lspid;
bds->msg_lrpid = sds->msg_lrpid;
bds->msg_stime = sds->msg_stime;
bds->msg_pad1 = sds->msg_pad1;
bds->msg_rtime = sds->msg_rtime;
bds->msg_pad2 = sds->msg_pad2;
bds->msg_ctime = sds->msg_ctime;
bds->msg_pad3 = sds->msg_pad3;
/* use the padding for the rest of the fields */
{
short *pad = (short *) bds->msg_pad4;
pad[0] = sds->msg_cv;
pad[1] = sds->msg_qnum_cv;
}
}
struct svr4_sys_msgsnd_args {
@ -543,20 +521,18 @@ bsd_to_svr4_shmid_ds(bds, sds)
const struct shmid_ds *bds;
struct svr4_shmid_ds *sds;
{
bzero(sds, sizeof(*sds));
bsd_to_svr4_ipc_perm(&bds->shm_perm, &sds->shm_perm);
sds->shm_segsz = bds->shm_segsz;
sds->shm_lkcnt = 0;
sds->shm_lpid = bds->shm_lpid;
sds->shm_cpid = bds->shm_cpid;
sds->shm_amp = bds->shm_internal;
sds->shm_amp = 0;
sds->shm_nattch = bds->shm_nattch;
sds->shm_cnattch = 0;
sds->shm_atime = bds->shm_atime;
sds->shm_pad1 = 0;
sds->shm_dtime = bds->shm_dtime;
sds->shm_pad2 = 0;
sds->shm_ctime = bds->shm_ctime;
sds->shm_pad3 = 0;
}
static void
@ -568,7 +544,6 @@ svr4_to_bsd_shmid_ds(sds, bds)
bds->shm_segsz = sds->shm_segsz;
bds->shm_lpid = sds->shm_lpid;
bds->shm_cpid = sds->shm_cpid;
bds->shm_internal = sds->shm_amp;
bds->shm_nattch = sds->shm_nattch;
bds->shm_atime = sds->shm_atime;
bds->shm_dtime = sds->shm_dtime;

View File

@ -415,7 +415,10 @@ struct ibcs2_shmid_ds *ibp;
ibp->shm_segsz = bp->shm_segsz;
ibp->shm_lpid = bp->shm_lpid;
ibp->shm_cpid = bp->shm_cpid;
ibp->shm_nattch = bp->shm_nattch;
if (bp->shm_nattch > SHRT_MAX)
ibp->shm_nattch = SHRT_MAX;
else
ibp->shm_nattch = bp->shm_nattch;
ibp->shm_cnattch = 0; /* ignored anyway */
ibp->shm_atime = bp->shm_atime;
ibp->shm_dtime = bp->shm_dtime;
@ -436,7 +439,6 @@ struct shmid_ds *bp;
bp->shm_atime = ibp->shm_atime;
bp->shm_dtime = ibp->shm_dtime;
bp->shm_ctime = ibp->shm_ctime;
bp->shm_internal = (void *)0; /* ignored anyway */
return;
}

View File

@ -417,15 +417,15 @@
;
; The following were introduced with NetBSD/4.4Lite-2
220 AUE_SEMCTL NOSTD { int __semctl(int semid, int semnum, \
int cmd, union semun *arg); }
220 AUE_SEMCTL COMPAT7|NOSTD { int __semctl(int semid, int semnum, \
int cmd, union semun_old *arg); }
221 AUE_SEMGET NOSTD { int semget(key_t key, int nsems, \
int semflg); }
222 AUE_SEMOP NOSTD { int semop(int semid, struct sembuf *sops, \
size_t nsops); }
223 AUE_NULL UNIMPL semconfig
224 AUE_MSGCTL NOSTD { int msgctl(int msqid, int cmd, \
struct msqid_ds *buf); }
224 AUE_MSGCTL COMPAT7|NOSTD { int msgctl(int msqid, int cmd, \
struct msqid_ds_old *buf); }
225 AUE_MSGGET NOSTD { int msgget(key_t key, int msgflg); }
226 AUE_MSGSND NOSTD { int msgsnd(int msqid, const void *msgp, \
size_t msgsz, int msgflg); }
@ -433,8 +433,8 @@
size_t msgsz, long msgtyp, int msgflg); }
228 AUE_SHMAT NOSTD { int shmat(int shmid, const void *shmaddr, \
int shmflg); }
229 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
struct shmid_ds *buf); }
229 AUE_SHMCTL COMPAT7|NOSTD { int shmctl(int shmid, int cmd, \
struct shmid_ds_old *buf); }
230 AUE_SHMDT NOSTD { int shmdt(const void *shmaddr); }
231 AUE_SHMGET NOSTD { int shmget(key_t key, size_t size, \
int shmflg); }
@ -904,5 +904,11 @@
unsigned int iovcnt, int flags); }
508 AUE_NULL STD { int jail_remove(int jid); }
509 AUE_CLOSEFROM STD { int closefrom(int lowfd); }
510 AUE_SEMCTL NOSTD { int __semctl(int semid, int semnum, \
int cmd, union semun *arg); }
511 AUE_MSGCTL NOSTD { int msgctl(int msqid, int cmd, \
struct msqid_ds *buf); }
512 AUE_SHMCTL NOSTD { int shmctl(int shmid, int cmd, \
struct shmid_ds *buf); }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master

View File

@ -36,6 +36,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_compat.h"
#include "opt_sysvipc.h"
#include <sys/param.h>
@ -147,3 +148,33 @@ ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
else
return (EACCES);
}
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
void
ipcperm_old2new(struct ipc_perm_old *old, struct ipc_perm *new)
{
new->cuid = old->cuid;
new->cgid = old->cgid;
new->uid = old->uid;
new->gid = old->gid;
new->mode = old->mode;
new->seq = old->seq;
new->key = old->key;
}
void
ipcperm_new2old(struct ipc_perm *new, struct ipc_perm_old *old)
{
/* XXX: How to handle ID's > USHORT_MAX? */
old->cuid = new->cuid;
old->cgid = new->cgid;
old->uid = new->uid;
old->gid = new->gid;
old->mode = new->mode;
old->seq = new->seq;
old->key = new->key;
}
#endif

View File

@ -1260,10 +1260,11 @@ SYSCTL_PROC(_kern_ipc, OID_AUTO, msqids, CTLFLAG_RD,
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL_MODULE_HELPER(msgsys);
SYSCALL_MODULE_HELPER(freebsd7_msgctl);
/* XXX casting to (sy_call_t *) is bogus, as usual. */
static sy_call_t *msgcalls[] = {
(sy_call_t *)msgctl, (sy_call_t *)msgget,
(sy_call_t *)freebsd7_msgctl, (sy_call_t *)msgget,
(sy_call_t *)msgsnd, (sy_call_t *)msgrcv
};
@ -1293,5 +1294,65 @@ msgsys(td, uap)
error = (*msgcalls[uap->which])(td, &uap->a2);
return (error);
}
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_msgctl_args {
int msqid;
int cmd;
struct msqid_ds_old *buf;
};
#endif
int
freebsd7_msgctl(td, uap)
struct thread *td;
struct freebsd7_msgctl_args *uap;
{
struct msqid_ds_old msqold;
struct msqid_ds msqbuf;
int error;
DPRINTF(("call to freebsd7_msgctl(%d, %d, %p)\n", uap->msqid, uap->cmd,
uap->buf));
if (uap->cmd == IPC_SET) {
error = copyin(uap->buf, &msqold, sizeof(msqold));
if (error)
return (error);
ipcperm_old2new(&msqold.msg_perm, &msqbuf.msg_perm);
CP(msqold, msqbuf, msg_first);
CP(msqold, msqbuf, msg_last);
CP(msqold, msqbuf, msg_cbytes);
CP(msqold, msqbuf, msg_qnum);
CP(msqold, msqbuf, msg_qbytes);
CP(msqold, msqbuf, msg_lspid);
CP(msqold, msqbuf, msg_lrpid);
CP(msqold, msqbuf, msg_stime);
CP(msqold, msqbuf, msg_rtime);
CP(msqold, msqbuf, msg_ctime);
}
error = kern_msgctl(td, uap->msqid, uap->cmd, &msqbuf);
if (error)
return (error);
if (uap->cmd == IPC_STAT) {
bzero(&msqold, sizeof(msqold));
ipcperm_new2old(&msqbuf.msg_perm, &msqold.msg_perm);
CP(msqbuf, msqold, msg_first);
CP(msqbuf, msqold, msg_last);
CP(msqbuf, msqold, msg_cbytes);
CP(msqbuf, msqold, msg_qnum);
CP(msqbuf, msqold, msg_qbytes);
CP(msqbuf, msqold, msg_lspid);
CP(msqbuf, msqold, msg_lrpid);
CP(msqbuf, msqold, msg_stime);
CP(msqbuf, msqold, msg_rtime);
CP(msqbuf, msqold, msg_ctime);
error = copyout(&msqold, uap->buf, sizeof(struct msqid_ds_old));
}
return (error);
}
#undef CP
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */

View File

@ -1317,10 +1317,11 @@ sysctl_sema(SYSCTL_HANDLER_ARGS)
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
SYSCALL_MODULE_HELPER(semsys);
SYSCALL_MODULE_HELPER(freebsd7___semctl);
/* XXX casting to (sy_call_t *) is bogus, as usual. */
static sy_call_t *semcalls[] = {
(sy_call_t *)__semctl, (sy_call_t *)semget,
(sy_call_t *)freebsd7___semctl, (sy_call_t *)semget,
(sy_call_t *)semop
};
@ -1349,5 +1350,89 @@ semsys(td, uap)
error = (*semcalls[uap->which])(td, &uap->a2);
return (error);
}
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#ifndef _SYS_SYSPROTO_H_
struct freebsd7___semctl_args {
int semid;
int semnum;
int cmd;
union semun_old *arg;
};
#endif
int
freebsd7___semctl(struct thread *td, struct freebsd7___semctl_args *uap)
{
struct semid_ds_old dsold;
struct semid_ds dsbuf;
union semun_old arg;
union semun semun;
register_t rval;
int error;
switch (uap->cmd) {
case SEM_STAT:
case IPC_SET:
case IPC_STAT:
case GETALL:
case SETVAL:
case SETALL:
error = copyin(uap->arg, &arg, sizeof(arg));
if (error)
return (error);
break;
}
switch (uap->cmd) {
case SEM_STAT:
case IPC_STAT:
semun.buf = &dsbuf;
break;
case IPC_SET:
error = copyin(arg.buf, &dsold, sizeof(dsold));
if (error)
return (error);
ipcperm_old2new(&dsold.sem_perm, &dsbuf.sem_perm);
CP(dsold, dsbuf, sem_base);
CP(dsold, dsbuf, sem_nsems);
CP(dsold, dsbuf, sem_otime);
CP(dsold, dsbuf, sem_ctime);
semun.buf = &dsbuf;
break;
case GETALL:
case SETALL:
semun.array = arg.array;
break;
case SETVAL:
semun.val = arg.val;
break;
}
error = kern_semctl(td, uap->semid, uap->semnum, uap->cmd, &semun,
&rval);
if (error)
return (error);
switch (uap->cmd) {
case SEM_STAT:
case IPC_STAT:
bzero(&dsold, sizeof(dsold));
ipcperm_new2old(&dsbuf.sem_perm, &dsold.sem_perm);
CP(dsbuf, dsold, sem_base);
CP(dsbuf, dsold, sem_nsems);
CP(dsbuf, dsold, sem_otime);
CP(dsbuf, dsold, sem_ctime);
error = copyout(&dsold, arg.buf, sizeof(dsold));
break;
}
if (error == 0)
td->td_retval[0] = rval;
return (error);
}
#undef CP
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */

View File

@ -68,6 +68,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/sysctl.h>
#include <sys/shm.h>
@ -234,9 +235,9 @@ shm_deallocate_segment(shmseg)
GIANT_REQUIRED;
vm_object_deallocate(shmseg->u.shm_internal);
shmseg->u.shm_internal = NULL;
size = round_page(shmseg->shm_bsegsz);
vm_object_deallocate(shmseg->object);
shmseg->object = NULL;
size = round_page(shmseg->u.shm_segsz);
shm_committed -= btoc(size);
shm_nused--;
shmseg->u.shm_perm.mode = SHMSEG_FREE;
@ -256,7 +257,7 @@ shm_delete_mapping(struct vmspace *vm, struct shmmap_state *shmmap_s)
segnum = IPCID_TO_IX(shmmap_s->shmid);
shmseg = &shmsegs[segnum];
size = round_page(shmseg->shm_bsegsz);
size = round_page(shmseg->u.shm_segsz);
result = vm_map_remove(&vm->vm_map, shmmap_s->va, shmmap_s->va + size);
if (result != KERN_SUCCESS)
return (EINVAL);
@ -376,7 +377,7 @@ kern_shmat(td, shmid, shmaddr, shmflg)
error = EMFILE;
goto done2;
}
size = round_page(shmseg->shm_bsegsz);
size = round_page(shmseg->u.shm_segsz);
prot = VM_PROT_READ;
if ((shmflg & SHM_RDONLY) == 0)
prot |= VM_PROT_WRITE;
@ -402,12 +403,12 @@ kern_shmat(td, shmid, shmaddr, shmflg)
PROC_UNLOCK(p);
}
vm_object_reference(shmseg->u.shm_internal);
rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->u.shm_internal,
vm_object_reference(shmseg->object);
rv = vm_map_find(&p->p_vmspace->vm_map, shmseg->object,
0, &attach_va, size, (flags & MAP_FIXED) ? VMFS_NO_SPACE :
VMFS_ANY_SPACE, prot, prot, 0);
if (rv != KERN_SUCCESS) {
vm_object_deallocate(shmseg->u.shm_internal);
vm_object_deallocate(shmseg->object);
error = ENOMEM;
goto done2;
}
@ -624,7 +625,7 @@ shmget_existing(td, uap, mode, segnum)
if (error != 0)
return (error);
#endif
if (uap->size != 0 && uap->size > shmseg->shm_bsegsz)
if (uap->size != 0 && uap->size > shmseg->u.shm_segsz)
return (EINVAL);
td->td_retval[0] = IXSEQ_TO_IPCID(segnum, shmseg->u.shm_perm);
return (0);
@ -686,13 +687,12 @@ shmget_allocate_segment(td, uap, mode)
vm_object_set_flag(shm_object, OBJ_NOSPLIT);
VM_OBJECT_UNLOCK(shm_object);
shmseg->u.shm_internal = shm_object;
shmseg->object = shm_object;
shmseg->u.shm_perm.cuid = shmseg->u.shm_perm.uid = cred->cr_uid;
shmseg->u.shm_perm.cgid = shmseg->u.shm_perm.gid = cred->cr_gid;
shmseg->u.shm_perm.mode = (shmseg->u.shm_perm.mode & SHMSEG_WANTED) |
(mode & ACCESSPERMS) | SHMSEG_ALLOCATED;
shmseg->u.shm_segsz = uap->size;
shmseg->shm_bsegsz = uap->size;
shmseg->u.shm_cpid = td->td_proc->p_pid;
shmseg->u.shm_lpid = shmseg->u.shm_nattch = 0;
shmseg->u.shm_atime = shmseg->u.shm_dtime = 0;
@ -953,7 +953,7 @@ oshmctl(td, uap)
static sy_call_t *shmcalls[] = {
(sy_call_t *)shmat, (sy_call_t *)oshmctl,
(sy_call_t *)shmdt, (sy_call_t *)shmget,
(sy_call_t *)shmctl
(sy_call_t *)freebsd7_shmctl
};
int
@ -983,6 +983,93 @@ shmsys(td, uap)
SYSCALL_MODULE_HELPER(shmsys);
#endif /* i386 && (COMPAT_FREEBSD4 || COMPAT_43) */
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
#define CP(src, dst, fld) do { (dst).fld = (src).fld; } while (0)
#ifndef _SYS_SYSPROTO_H_
struct freebsd7_shmctl_args {
int shmid;
int cmd;
struct shmid_ds_old *buf;
};
#endif
int
freebsd7_shmctl(td, uap)
struct thread *td;
struct freebsd7_shmctl_args *uap;
{
int error = 0;
struct shmid_ds_old old;
struct shmid_ds buf;
size_t bufsz;
/*
* The only reason IPC_INFO, SHM_INFO, SHM_STAT exists is to support
* Linux binaries. If we see the call come through the FreeBSD ABI,
* return an error back to the user since we do not to support this.
*/
if (uap->cmd == IPC_INFO || uap->cmd == SHM_INFO ||
uap->cmd == SHM_STAT)
return (EINVAL);
/* IPC_SET needs to copyin the buffer before calling kern_shmctl */
if (uap->cmd == IPC_SET) {
if ((error = copyin(uap->buf, &old, sizeof(old))))
goto done;
ipcperm_old2new(&old.shm_perm, &buf.shm_perm);
CP(old, buf, shm_segsz);
CP(old, buf, shm_lpid);
CP(old, buf, shm_cpid);
CP(old, buf, shm_nattch);
CP(old, buf, shm_atime);
CP(old, buf, shm_dtime);
CP(old, buf, shm_ctime);
}
error = kern_shmctl(td, uap->shmid, uap->cmd, (void *)&buf, &bufsz);
if (error)
goto done;
/* Cases in which we need to copyout */
switch (uap->cmd) {
case IPC_STAT:
ipcperm_new2old(&buf.shm_perm, &old.shm_perm);
if (buf.shm_segsz > INT_MAX)
old.shm_segsz = INT_MAX;
else
CP(buf, old, shm_segsz);
CP(buf, old, shm_lpid);
CP(buf, old, shm_cpid);
if (buf.shm_nattch > SHRT_MAX)
old.shm_nattch = SHRT_MAX;
else
CP(buf, old, shm_nattch);
CP(buf, old, shm_atime);
CP(buf, old, shm_dtime);
CP(buf, old, shm_ctime);
old.shm_internal = NULL;
error = copyout(&old, uap->buf, sizeof(old));
break;
}
done:
if (error) {
/* Invalidate the return value */
td->td_retval[0] = -1;
}
return (error);
}
SYSCALL_MODULE_HELPER(freebsd7_shmctl);
#undef CP
#endif /* COMPAT_FREEBSD4 || COMPAT_FREEBSD5 || COMPAT_FREEBSD6 ||
COMPAT_FREEBSD7 */
static int
sysvshm_modload(struct module *module, int cmd, void *arg)
{

View File

@ -69,10 +69,9 @@ typedef __uid_t uid_t;
#define _UID_T_DECLARED
#endif
/*
* XXX almost all members have wrong types.
*/
struct ipc_perm {
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
struct ipc_perm_old {
unsigned short cuid; /* creator user id */
unsigned short cgid; /* creator group id */
unsigned short uid; /* user id */
@ -81,6 +80,17 @@ struct ipc_perm {
unsigned short seq; /* sequence # (to generate unique ipcid) */
key_t key; /* user specified msg/sem/shm key */
};
#endif
struct ipc_perm {
uid_t cuid; /* creator user id */
gid_t cgid; /* creator group id */
uid_t uid; /* user id */
gid_t gid; /* group id */
mode_t mode; /* r/w permission */
unsigned short seq; /* sequence # (to generate unique ipcid) */
key_t key; /* user specified msg/sem/shm key */
};
#if __BSD_VISIBLE
/* common mode bits */
@ -116,6 +126,12 @@ struct thread;
struct proc;
struct vmspace;
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
void ipcperm_old2new(struct ipc_perm_old *, struct ipc_perm *);
void ipcperm_new2old(struct ipc_perm *, struct ipc_perm_old *);
#endif
int ipcperm(struct thread *, struct ipc_perm *, int);
extern void (*shmfork_hook)(struct proc *, struct proc *);
extern void (*shmexit_hook)(struct vmspace *);

View File

@ -57,6 +57,27 @@ typedef __time_t time_t;
#define _TIME_T_DECLARED
#endif
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
struct msqid_ds_old {
struct ipc_perm_old msg_perm; /* msg queue permission bits */
struct msg *msg_first; /* first message in the queue */
struct msg *msg_last; /* last message in the queue */
msglen_t msg_cbytes; /* number of bytes in use on the queue */
msgqnum_t msg_qnum; /* number of msgs in the queue */
msglen_t 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
/*
* XXX there seems to be no prefix reserved for this header, so the name
* "msg" in "struct msg" and the names of all of the nonstandard members
@ -73,12 +94,8 @@ struct msqid_ds {
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];
};
#if __BSD_VISIBLE

View File

@ -27,8 +27,10 @@ typedef __time_t time_t;
#define _TIME_T_DECLARED
#endif
struct semid_ds {
struct ipc_perm sem_perm; /* operation permission struct */
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
struct semid_ds_old {
struct ipc_perm_old 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 */
@ -39,6 +41,17 @@ struct semid_ds {
long sem_pad2; /* SVABI/386 says I need this here */
long sem_pad3[4]; /* SVABI/386 says I need this here */
};
#endif
struct semid_ds {
struct ipc_perm 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 */
time_t sem_ctime; /* last change time */
/* Times measured in secs since */
/* 00:00:00 GMT, Jan. 1, 1970 */
};
/*
* semop's sops parameter structure
@ -50,6 +63,16 @@ struct sembuf {
};
#define SEM_UNDO 010000
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7) || \
defined(_WANT_SEMUN_OLD)
union semun_old {
int val; /* value for SETVAL */
struct semid_ds_old *buf; /* buffer for IPC_STAT & IPC_SET */
unsigned short *array; /* array for GETALL & SETALL */
};
#endif
/*
* semctl's arg parameter structure
*/

View File

@ -75,8 +75,10 @@ typedef __size_t size_t;
#define _SIZE_T_DECLARED
#endif
struct shmid_ds {
struct ipc_perm shm_perm; /* operation permission structure */
#if defined(COMPAT_FREEBSD4) || defined(COMPAT_FREEBSD5) || \
defined(COMPAT_FREEBSD6) || defined(COMPAT_FREEBSD7)
struct shmid_ds_old {
struct ipc_perm_old shm_perm; /* operation permission structure */
int shm_segsz; /* size of segment in bytes */
pid_t shm_lpid; /* process ID of last shared memory op */
pid_t shm_cpid; /* process ID of creator */
@ -86,8 +88,21 @@ struct shmid_ds {
time_t shm_ctime; /* time of last change by shmctl() */
void *shm_internal; /* sysv stupidity */
};
#endif
struct shmid_ds {
struct ipc_perm shm_perm; /* operation permission structure */
size_t shm_segsz; /* size of segment in bytes */
pid_t shm_lpid; /* process ID of last shared memory op */
pid_t shm_cpid; /* process ID of creator */
int 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() */
};
#ifdef _KERNEL
#include <vm/vm.h>
/*
* System 5 style catch-all structure for shared memory constants that
@ -107,8 +122,8 @@ struct shminfo {
*/
struct shmid_kernel {
struct shmid_ds u;
vm_object_t object;
struct label *label; /* MAC label */
size_t shm_bsegsz;
};
extern struct shminfo shminfo;

View File

@ -453,7 +453,7 @@ print_kshmptr(int i, int option, struct shmid_kernel *kshmptr)
if (option & BIGGEST)
printf(" %12zu",
kshmptr->shm_bsegsz);
kshmptr->u.shm_segsz);
if (option & PID)
printf(" %12d %12d",