Bug 113218 - [sysvipc] [patch] Overflow in shmget's memory size check
[sysvipc] [patch] Overflow in shmget's memory size check
Status: Closed FIXED
Product: Base System
Classification: Unclassified
Component: kern
7.0-CURRENT
Any Any
: Normal Affects Only Me
Assigned To: Jung-uk Kim
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2007-06-01 12:40 UTC by vasim
Modified: 2009-06-24 22:20 UTC (History)
0 users

See Also:


Attachments
file.diff (576 bytes, patch)
2007-06-01 12:40 UTC, vasim
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description vasim 2007-06-01 12:40:03 UTC
I've got ENOMEM error when tried to allocate SYSV's shared memory buffer
greater than 1G on machine with 16G RAM. Some investigation did show that
there is small error in sys/kern/sysv_shm.c file - variable "size" has
"int" type that may overflow on big values.

How-To-Repeat: 	Just try to allocate big shared memory buffer
Comment 1 vasim 2007-06-04 13:16:13 UTC
Just found that there more modifications needed. Big chunk of shared memory (2GB
or more) won't deallocate properly because "shmid_ds" structure has int type for
"shm_segsz" field. So, will need to change in sys/sys/shm.h (and
/usr/include/sys/shm.h), sysv_shm.c (there is shmid_ds's definition too) and
usr.bin/ipcs/ipcs.c source ("%12d" -> "%12ld" in line that prints segment size
information).

Vasim V.
Comment 2 vasim 2007-08-02 10:39:21 UTC
Hi !

Full patch (including ipcs fix):

*** sys/kern/sysv_shm.c.orig    Mon Mar  5 16:10:57 2007
--- sys/kern/sysv_shm.c Wed Jul 25 15:00:14 2007
***************
*** 149,155 ****
  #define       SHMMAXPGS       8192    /* Note: sysv shared memory is swap
backed. */
  #endif
  #ifndef SHMMAX
! #define       SHMMAX  (SHMMAXPGS*PAGE_SIZE)
  #endif
  #ifndef SHMMIN
  #define       SHMMIN  1
--- 149,155 ----
  #define       SHMMAXPGS       8192    /* Note: sysv shared memory is swap
backed. */
  #endif
  #ifndef SHMMAX
! #define       SHMMAX  (1L*SHMMAXPGS*PAGE_SIZE)
  #endif
  #ifndef SHMMIN
  #define       SHMMIN  1
***************
*** 453,459 ****
  #if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
  struct oshmid_ds {
        struct  ipc_perm shm_perm;      /* operation perms */
!       int     shm_segsz;              /* size of segment (bytes) */
        u_short shm_cpid;               /* pid, creator */
        u_short shm_lpid;               /* pid, last operation */
        short   shm_nattch;             /* no. of current attaches */
--- 453,459 ----
  #if defined(__i386__) && (defined(COMPAT_FREEBSD4) || defined(COMPAT_43))
  struct oshmid_ds {
        struct  ipc_perm shm_perm;      /* operation perms */
!       size_t  shm_segsz;              /* size of segment (bytes) */
        u_short shm_cpid;               /* pid, creator */
        u_short shm_lpid;               /* pid, last operation */
        short   shm_nattch;             /* no. of current attaches */
***************
*** 717,723 ****
        struct shmget_args *uap;
        int mode;
  {
!       int i, segnum, shmid, size;
        struct ucred *cred = td->td_ucred;
        struct shmid_kernel *shmseg;
        vm_object_t shm_object;
--- 717,724 ----
        struct shmget_args *uap;
        int mode;
  {
!       int i, segnum, shmid;
!       size_t size;
        struct ucred *cred = td->td_ucred;
        struct shmid_kernel *shmseg;
        vm_object_t shm_object;
*** sys/sys/shm.h.orig  Sat Aug  6 11:20:17 2005
--- sys/sys/shm.h       Wed Jul 25 14:47:47 2007
***************
*** 77,83 ****

  struct shmid_ds {
        struct ipc_perm 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 */
        short           shm_nattch;     /* number of current attaches */
--- 77,83 ----

  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 */
        short           shm_nattch;     /* number of current attaches */
*** usr.bin/ipcs/ipcs.c.orig    Mon May 15 12:20:38 2006
--- usr.bin/ipcs/ipcs.c Wed Jul 25 14:48:23 2007
***************
*** 439,445 ****
                                                    kshmptr->u.shm_nattch);

                                        if (option & BIGGEST)
!                                               printf(" %12d",
                                                    kshmptr->u.shm_segsz);

                                        if (option & PID)
--- 439,445 ----
                                                    kshmptr->u.shm_nattch);

                                        if (option & BIGGEST)
!                                               printf(" %12ld",
                                                    kshmptr->u.shm_segsz);

                                        if (option & PID)


Vasim V.
Comment 3 Jung-uk Kim freebsd_committer 2007-09-21 01:13:44 UTC
Responsible Changed
From-To: freebsd-bugs->jkim

Grab.
Comment 4 Jung-uk Kim freebsd_committer 2007-09-21 02:04:51 UTC
State Changed
From-To: open->feedback

Patch updated.  Waiting for feedback.
Comment 5 emaste 2007-10-17 16:10:11 UTC
Presumably changing shm_segsz from int to size_t means we'll need to add
a 32-bit compat shmctl as well as a backwards-compatibility one for
older FreeBSD 6/7 64-bit apps?
Comment 6 Jung-uk Kim freebsd_committer 2007-10-17 17:11:09 UTC
On Wednesday 17 October 2007 11:40 am, Ed Maste wrote:
> The following reply was made to PR kern/113218; it has been noted
> by GNATS.
>
> From: Ed Maste <emaste@phaedrus.sandvine.ca>
> To: bug-followup@FreeBSD.org, vasim@resume-bank.ru
> Cc:
> Subject: Re: kern/113218: [sysvipc] [patch] Overflow in shmget's
> memory size check Date: Wed, 17 Oct 2007 11:10:11 -0400
>
>  Presumably changing shm_segsz from int to size_t means we'll need
> to add a 32-bit compat shmctl as well as a backwards-compatibility
> one for older FreeBSD 6/7 64-bit apps?

Yes, correct.  But struct oshmid_ds is already taken.  Do you think I 
have to add OMG_we_broke_shmid_ds? ;-)  Seriously, I think we should 
do it for 7.0 before it gets too late.  Maybe 6.3 can live without it 
because shminfo was not increased on the branch.  Or maybe we can add 
the feature with compat shim later only on the branch.  What do you 
think?

Jung-uk Kim
Comment 7 emaste 2007-10-17 18:35:44 UTC
On Wed, Oct 17, 2007 at 12:11:09PM -0400, Jung-uk Kim wrote:

> >  Presumably changing shm_segsz from int to size_t means we'll need
> > to add a 32-bit compat shmctl as well as a backwards-compatibility
> > one for older FreeBSD 6/7 64-bit apps?
> 
> Yes, correct.  But struct oshmid_ds is already taken.  Do you think I 
> have to add OMG_we_broke_shmid_ds? ;-)

Yeah, it's a shame, and we already have an oshmctl syscall.  I don't
know what naming convention we'd use, but we probably end up with
the existing oshmctl, shmctl_5x in 32- and 64-bit versions, and then
the modified shmctl in 32- and 64-bit versions.  Maybe the following?

shmctl
shmctl_5x
freebsd32_shmctl_5x
shmctl
freebsd32_shmctl

> Seriously, I think we should 
> do it for 7.0 before it gets too late.  Maybe 6.3 can live without it 
> because shminfo was not increased on the branch.  Or maybe we can add 
> the feature with compat shim later only on the branch.  What do you 
> think?

Yeah, getting this into 7.0 would be very very good.  I'll need to get
it in 6.x as well at work, although I can probably break the ABI there
so that part is less of a concern for me.  Probably the issue causes
the most grief with big Postgres installations which will most likely
want to use 7.x anyhow in short order for the better scalability.
Comment 8 Jung-uk Kim freebsd_committer 2007-10-17 19:13:06 UTC
On Wednesday 17 October 2007 01:40 pm, Ed Maste wrote:
> The following reply was made to PR kern/113218; it has been noted
> by GNATS.
>
> From: Ed Maste <emaste@phaedrus.sandvine.ca>
> To: Jung-uk Kim <jkim@FreeBSD.org>
> Cc: bug-followup@FreeBSD.org, vasim@resume-bank.ru
> Subject: Re: kern/113218: [sysvipc] [patch] Overflow in shmget's
> memory size check Date: Wed, 17 Oct 2007 13:35:44 -0400
>
>  On Wed, Oct 17, 2007 at 12:11:09PM -0400, Jung-uk Kim wrote:
>  > >  Presumably changing shm_segsz from int to size_t means we'll
>  > > need to add a 32-bit compat shmctl as well as a
>  > > backwards-compatibility one for older FreeBSD 6/7 64-bit apps?
>  >
>  > Yes, correct.  But struct oshmid_ds is already taken.  Do you
>  > think I have to add OMG_we_broke_shmid_ds? ;-)
>
>  Yeah, it's a shame, and we already have an oshmctl syscall.  I
> don't know what naming convention we'd use, but we probably end up
> with the existing oshmctl, shmctl_5x in 32- and 64-bit versions,
> and then the modified shmctl in 32- and 64-bit versions.  Maybe the
> following?
>
>  shmctl
>  shmctl_5x
>  freebsd32_shmctl_5x
>  shmctl
>  freebsd32_shmctl
>
>  > Seriously, I think we should
>  > do it for 7.0 before it gets too late.  Maybe 6.3 can live
>  > without it because shminfo was not increased on the branch.  Or
>  > maybe we can add the feature with compat shim later only on the
>  > branch.  What do you think?
>
>  Yeah, getting this into 7.0 would be very very good.  I'll need to
> get it in 6.x as well at work, although I can probably break the
> ABI there so that part is less of a concern for me.  Probably the
> issue causes the most grief with big Postgres installations which
> will most likely want to use 7.x anyhow in short order for the
> better scalability.

Actually there is another way.  We can add a upper half in struct 
shmid_kernel.  Then we can aggregate the lower half 
(shmid_ds.shm_segsz) and the upper half to get real shm_segsz.  But 
it is ugly and userland will not see the upper half, e.g., ipcs -b.

Jung-uk Kim
Comment 9 emaste 2007-10-19 04:37:44 UTC
It turns out this has been discussed a number of times already, and
there's another issue that Robert Watson brought up that needs to be
dealt with at the same time.  That is, ipc_perm needs to get fixed:

[ipc.h]
/*
 * XXX almost all members have wrong types.
 */
struct ipc_perm {
        unsigned short  cuid;   /* creator user id */
        unsigned short  cgid;   /* creator group id */
        unsigned short  uid;    /* user id */
        unsigned short  gid;    /* group id */
        unsigned short  mode;   /* r/w permission */
        unsigned short  seq;    /* sequence # (to generate unique ipcid) */
        key_t           key;    /* user specified msg/sem/shm key */
};

These should be:

uid_t	cuid
gid_t	cgid
uid_t	uid
gid_t	gid
mode_t	mode
?	seq
key_t	key

(I'm not sure what type seq should have.)  Anyhow, we'll have to deal
with the ABI issue for sem and msg in addition to shm then.
Comment 10 p.rybicki 2007-12-12 09:12:04 UTC
Hi there.

Is there any chance to have this functionality (ability to allocate more 
than 2G of SHM) in 7.0-R ?

I have a huge postgresql installation and now i'm suffering from this 
limitation. It's nice to know that new release is very fast (according 
to Kris's presentation on MeetBSD), but this limit is a real pain.

Perhaps 7-Branch is good moment for ABI brekage (IMHO better break when 
updating 6.X -> 7.0 than 7.0 -> 7.X).

Personally i'd rather wait longer for 7.0 without this limtation.

Best regards
Piotr Rybicki
Comment 11 Mark Linimon freebsd_committer 2008-03-03 06:40:26 UTC
State Changed
From-To: feedback->analyzed

Feedback was apparently received some time ago.
Comment 12 Jung-uk Kim freebsd_committer 2009-03-04 18:28:33 UTC
State Changed
From-To: analyzed->closed

A different non-intrusive workaround is committed by kib: 

http://docs.freebsd.org/cgi/mid.cgi?200903021853.n22IrUdx083424
Comment 13 dfilter freebsd_committer 2009-06-24 22:11:11 UTC
Author: jhb
Date: Wed Jun 24 21:10:52 2009
New Revision: 194910
URL: http://svn.freebsd.org/changeset/base/194910

Log:
  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]

Added:
  head/lib/libc/include/compat.h   (contents, props changed)
Modified:
  head/lib/libc/gen/Symbol.map
  head/lib/libc/gen/semctl.c
  head/lib/libc/sys/Makefile.inc
  head/lib/libc/sys/Symbol.map
  head/sys/compat/freebsd32/freebsd32_ipc.h
  head/sys/compat/freebsd32/freebsd32_misc.c
  head/sys/compat/freebsd32/syscalls.master
  head/sys/compat/linux/linux_ipc.c
  head/sys/compat/svr4/svr4_ipc.c
  head/sys/i386/ibcs2/ibcs2_ipc.c
  head/sys/kern/syscalls.master
  head/sys/kern/sysv_ipc.c
  head/sys/kern/sysv_msg.c
  head/sys/kern/sysv_sem.c
  head/sys/kern/sysv_shm.c
  head/sys/sys/ipc.h
  head/sys/sys/msg.h
  head/sys/sys/sem.h
  head/sys/sys/shm.h
  head/usr.bin/ipcs/ipcs.c

Modified: head/lib/libc/gen/Symbol.map
==============================================================================
--- head/lib/libc/gen/Symbol.map	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/lib/libc/gen/Symbol.map	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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;
 };

Modified: head/lib/libc/gen/semctl.c
==============================================================================
--- head/lib/libc/gen/semctl.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/lib/libc/gen/semctl.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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 cm
 
 	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);

Added: head/lib/libc/include/compat.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libc/include/compat.h	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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__ */
+

Modified: head/lib/libc/sys/Makefile.inc
==============================================================================
--- head/lib/libc/sys/Makefile.inc	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/lib/libc/sys/Makefile.inc	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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 \

Modified: head/lib/libc/sys/Symbol.map
==============================================================================
--- head/lib/libc/sys/Symbol.map	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/lib/libc/sys/Symbol.map	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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;
 };

Modified: head/sys/compat/freebsd32/freebsd32_ipc.h
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_ipc.h	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/compat/freebsd32/freebsd32_ipc.h	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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_ */

Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/compat/freebsd32/freebsd32_misc.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -1353,6 +1353,35 @@ freebsd4_freebsd32_fhstatfs(struct threa
 }
 #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,7 +1421,85 @@ freebsd32_semsys(struct thread *td, stru
 	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, stru
 		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, stru
 	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, stru
 	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, stru
 		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, stru
 		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, stru
 	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, stru
 		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, stru
 	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;

Modified: head/sys/compat/freebsd32/syscalls.master
==============================================================================
--- head/sys/compat/freebsd32/syscalls.master	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/compat/freebsd32/syscalls.master	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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); }

Modified: head/sys/compat/linux/linux_ipc.c
==============================================================================
--- head/sys/compat/linux/linux_ipc.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/compat/linux/linux_ipc.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -230,23 +230,26 @@ linux_to_bsd_shmid_ds(struct l_shmid_ds 
     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
 {
 	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));
 

Modified: head/sys/compat/svr4/svr4_ipc.c
==============================================================================
--- head/sys/compat/svr4/svr4_ipc.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/compat/svr4/svr4_ipc.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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;

Modified: head/sys/i386/ibcs2/ibcs2_ipc.c
==============================================================================
--- head/sys/i386/ibcs2/ibcs2_ipc.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/i386/ibcs2/ibcs2_ipc.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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;
 }
 

Modified: head/sys/kern/syscalls.master
==============================================================================
--- head/sys/kern/syscalls.master	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/kern/syscalls.master	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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

Modified: head/sys/kern/sysv_ipc.c
==============================================================================
--- head/sys/kern/sysv_ipc.c	Wed Jun 24 21:09:56 2009	(r194909)
+++ head/sys/kern/sysv_ipc.c	Wed Jun 24 21:10:52 2009	(r194910)
@@ -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_pe
 	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)

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"