From vasim@hunter.resume-bank.ru  Fri Jun  1 11:30:08 2007
Return-Path: <vasim@hunter.resume-bank.ru>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 9365E16A468
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  1 Jun 2007 11:30:08 +0000 (UTC)
	(envelope-from vasim@hunter.resume-bank.ru)
Received: from wolf.resume-bank.ru (mail.resume-bank.ru [62.118.250.39])
	by mx1.freebsd.org (Postfix) with SMTP id CDCDC13C44C
	for <FreeBSD-gnats-submit@freebsd.org>; Fri,  1 Jun 2007 11:30:07 +0000 (UTC)
	(envelope-from vasim@hunter.resume-bank.ru)
Received: (qmail 46124 invoked by uid 0); 1 Jun 2007 11:09:16 -0000
Received: from unknown (HELO hunter.resume-bank.ru) (62.118.252.51)
  by mail.resume-bank.ru with SMTP; 1 Jun 2007 11:09:16 -0000
Received: (from vasim@localhost)
	by hunter.resume-bank.ru (8.14.1/8.13.4/Submit) id l51B3OjV018332;
	Fri, 1 Jun 2007 15:03:24 +0400 (MSD)
	(envelope-from vasim)
Message-Id: <200706011103.l51B3OjV018332@hunter.resume-bank.ru>
Date: Fri, 1 Jun 2007 15:03:24 +0400 (MSD)
From: Vasim V <vasim@resume-bank.ru>
Reply-To: Vasim V <vasim@resume-bank.ru>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Overflow in shmget's memory size check
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         113218
>Category:       kern
>Synopsis:       [sysvipc] [patch] Overflow in shmget's memory size check
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jkim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Jun 01 11:40:03 GMT 2007
>Closed-Date:    Wed Mar 04 18:33:09 UTC 2009
>Last-Modified:  Wed Jun 24 21:20:03 UTC 2009
>Originator:     Vasim V
>Release:        FreeBSD 7.0-CURRENT amd64
>Organization:
Resume Bank ltd
>Environment:
System: FreeBSD hunter.resume-bank.ru 7.0-CURRENT FreeBSD 7.0-CURRENT #1: Wed May 30 15:59:46 MSD 2007 vasim@hunter.resume-bank.ru:/usr/src/sys/amd64/compile/NEWHUNTER amd64
>Description:
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
>Fix:

*** sys/kern/sysv_shm.c.orig    Fri Jun  1 14:49:47 2007
--- sys/kern/sysv_shm.c Fri Jun  1 14:50:50 2007
***************
*** 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;



>Release-Note:
>Audit-Trail:

From: "Vasim Valejev" <vasim@resume-bank.ru>
To: <bug-followup@FreeBSD.org>,
	"Vasim Valejev" <vasim@resume-bank.ru>
Cc:  
Subject: Re: kern/113218: [sysvipc] [patch] Overflow in shmget's memory size check
Date: Mon, 4 Jun 2007 16:16:13 +0400

 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.
 

From: "Vasim Valejev" <vasim@resume-bank.ru>
To: <bug-followup@FreeBSD.org>
Cc:  
Subject: Re: kern/113218: [sysvipc] [patch] Overflow in shmget's memory size check
Date: Thu, 2 Aug 2007 13:39:21 +0400

 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.
 
Responsible-Changed-From-To: freebsd-bugs->jkim 
Responsible-Changed-By: jkim 
Responsible-Changed-When: Fri Sep 21 00:13:44 UTC 2007 
Responsible-Changed-Why:  
Grab. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=113218 
State-Changed-From-To: open->feedback 
State-Changed-By: jkim 
State-Changed-When: Fri Sep 21 01:04:51 UTC 2007 
State-Changed-Why:  
Patch updated.  Waiting for feedback. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=113218 

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?

From: Jung-uk Kim <jkim@FreeBSD.org>
To: Ed Maste <emaste@phaedrus.sandvine.ca>
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 12:11:09 -0400

 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

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.

From: Jung-uk Kim <jkim@FreeBSD.org>
To: Ed Maste <emaste@phaedrus.sandvine.ca>
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 14:13:06 -0400

 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

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: Thu, 18 Oct 2007 23:37:44 -0400

 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.
 

From: Piotr Rybicki <p.rybicki@cadera.com.pl>
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, 12 Dec 2007 10:12:04 +0100

 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
State-Changed-From-To: feedback->analyzed 
State-Changed-By: linimon 
State-Changed-When: Mon Mar 3 06:40:26 UTC 2008 
State-Changed-Why:  
Feedback was apparently received some time ago. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=113218 
State-Changed-From-To: analyzed->closed 
State-Changed-By: jkim 
State-Changed-When: Wed Mar 4 18:28:33 UTC 2009 
State-Changed-Why:  
A different non-intrusive workaround is committed by kib: 

http://docs.freebsd.org/cgi/mid.cgi?200903021853.n22IrUdx083424 

http://www.freebsd.org/cgi/query-pr.cgi?pr=113218 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/113218: commit references a PR
Date: Wed, 24 Jun 2009 21:11:11 +0000 (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"
 
>Unformatted:
Can you try the following patch?

http://people.freebsd.org/~jkim/shmmax.diff

Basically it is the same patch but I have cleaned it up a bit.
Unfortunately struct shmid_ds got little bigger on 64-bit
platforms and old ipcs(1) binary does not work with this patch
any more and I am afraid it may break some applications if they
use kern.ipc.shmsegs directly.  In fact, this had to be done
two years ago when we broke the ABI on 64-bit platforms. :-(

Thanks,

Jung-uk Kim
