Skip site navigation (1)Skip section navigation (2)

kern/113218: [sysvipc] [patch] Overflow in shmget's memory size check

From: Vasim V <vasim@resume-bank.ru>
Date: Fri, 1 Jun 2007 15:03:24 +0400 (MSD)
Subject: Overflow in shmget's memory size check
Send-pr version: 3.113
Number: 113218
Category: kern
Synopsis: [sysvipc] [patch] Overflow in shmget's memory size check
Severity: non-critical
Priority: low
Responsible: jkim
State: closed
Class: sw-bug
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
Download patch.txt
*** 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
Reply via E-mail [Link]
From: "Vasim Valejev" <vasim@resume-bank.ru> [submitter]
To: <bug-followup@FreeBSD.org>, "Vasim Valejev" <vasim@resume-bank.ru>
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.
Reply via E-mail [Link]
From: "Vasim Valejev" <vasim@resume-bank.ru> [submitter]
To: <bug-followup@FreeBSD.org>
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
By: jkim
When: Fri Sep 21 00:13:44 UTC 2007
Why: Grab.
State Changed
From-To: open->feedback
By: jkim
When: Fri Sep 21 01:04:51 UTC 2007
Why: Patch updated. Waiting for feedback.
Reply via E-mail [Link]
From: Ed Maste <emaste@phaedrus.sandvine.ca>
To: bug-followup@FreeBSD.org, vasim@resume-bank.ru
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?
Reply via E-mail [Link]
From: Jung-uk Kim <jkim@FreeBSD.org>
To: Ed Maste <emaste@phaedrus.sandvine.ca>
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
Reply via E-mail [Link]
From: Ed Maste <emaste@phaedrus.sandvine.ca>
To: Jung-uk Kim <jkim@FreeBSD.org>
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.
Reply via E-mail [Link]
From: Jung-uk Kim <jkim@FreeBSD.org>
To: Ed Maste <emaste@phaedrus.sandvine.ca>
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
Reply via E-mail [Link]
From: Ed Maste <emaste@phaedrus.sandvine.ca>
To: Jung-uk Kim <jkim@FreeBSD.org>
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.
Reply via E-mail [Link]
From: Piotr Rybicki <p.rybicki@cadera.com.pl>
To: bug-followup@FreeBSD.org, vasim@resume-bank.ru
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
By: linimon
When: Mon Mar 3 06:40:26 UTC 2008
Why: Feedback was apparently received some time ago.
State Changed
From-To: analyzed->closed
By: jkim
When: Wed Mar 4 18:28:33 UTC 2009
Why: A different non-intrusive workaround is committed by kib:

http://docs.freebsd.org/cgi/mid.cgi?200903021853.n22IrUdx083424
Reply via E-mail [Link]
From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
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