From: Carsten Langgaard <carstenl@mips.com>
To: Ralf Baechle <ralf@oss.sgi.com>
Cc: "Maciej W. Rozycki" <macro@ds2.pg.gda.pl>, linux-mips@oss.sgi.com
Subject: Re: IPC syscall fixup (o32 conversion layer)
Date: Mon, 19 Aug 2002 15:49:39 +0200 [thread overview]
Message-ID: <3D60F773.3C64C13E@mips.com> (raw)
In-Reply-To: 20020813052324.A22438@linux-mips.org
Ralf Baechle wrote:
> Carsten,
>
> On Wed, Aug 07, 2002 at 04:42:15PM +0200, Carsten Langgaard wrote:
>
> > Here is a patch that fixes the ipc syscalls in the o32
> > wrapper/conversion routines.
> > Needed when running a 64-bit kernel on an o32 userland.
>
> before I finally apply this one, can you do me a favour and check your
> code is still working correctly even after I applied yesterdays fix
> which changes struct msqid64_id to eleminate the mismatch of the kernel
> and libc definitions?
>
It should be fine, I have this change in my local sources already.
>
> Thanks,
>
> Ralf
>
> > Index: arch/mips64/kernel/linux32.c
> > ===================================================================
> > RCS file: /cvs/linux/arch/mips64/kernel/linux32.c,v
> > retrieving revision 1.42.2.9
> > diff -u -r1.42.2.9 linux32.c
> > --- arch/mips64/kernel/linux32.c 2002/07/23 12:26:09 1.42.2.9
> > +++ arch/mips64/kernel/linux32.c 2002/08/07 14:28:03
> > @@ -35,8 +35,16 @@
> > #include <asm/mman.h>
> > #include <asm/ipc.h>
> >
> > -
> > +/* Use this to get at 32-bit user passed pointers. */
> > +/* A() macro should be used for places where you e.g.
> > + have some internal variable u32 and just want to get
> > + rid of a compiler warning. AA() has to be used in
> > + places where you want to convert a function argument
> > + to 32bit pointer or when you e.g. access pt_regs
> > + structure and want to consider 32bit registers only.
> > + */
> > #define A(__x) ((unsigned long)(__x))
> > +#define AA(__x) ((unsigned long)((int)__x))
> >
> > #ifdef __MIPSEB__
> > #define merge_64(r1,r2) ((((r1) & 0xffffffffUL) << 32) + ((r2) & 0xffffffffUL))
> > @@ -1494,6 +1502,19 @@
> > unsigned short seq;
> > };
> >
> > +struct ipc64_perm32 {
> > + key_t key;
> > + __kernel_uid_t32 uid;
> > + __kernel_gid_t32 gid;
> > + __kernel_uid_t32 cuid;
> > + __kernel_gid_t32 cgid;
> > + __kernel_mode_t32 mode;
> > + unsigned short seq;
> > + unsigned short __pad1;
> > + unsigned int __unused1;
> > + unsigned int __unused2;
> > +};
> > +
> > struct semid_ds32 {
> > struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
> > __kernel_time_t32 sem_otime; /* last semop time */
> > @@ -1522,6 +1543,23 @@
> > __kernel_ipc_pid_t32 msg_lrpid;
> > };
> >
> > +struct msqid64_ds32 {
> > + struct ipc64_perm32 msg_perm;
> > + __kernel_time_t32 msg_stime;
> > + unsigned int __unused1;
> > + __kernel_time_t32 msg_rtime;
> > + unsigned int __unused2;
> > + __kernel_time_t32 msg_ctime;
> > + unsigned int __unused3;
> > + unsigned int msg_cbytes;
> > + unsigned int msg_qnum;
> > + unsigned int msg_qbytes;
> > + __kernel_pid_t32 msg_lspid;
> > + __kernel_pid_t32 msg_lrpid;
> > + unsigned int __unused4;
> > + unsigned int __unused5;
> > +};
> > +
> > struct shmid_ds32 {
> > struct ipc_perm32 shm_perm;
> > int shm_segsz;
> > @@ -1533,9 +1571,25 @@
> > unsigned short shm_nattch;
> > };
> >
> > +struct ipc_kludge32 {
> > + u32 msgp;
> > + s32 msgtyp;
> > +};
> > +
> > #define IPCOP_MASK(__x) (1UL << (__x))
> >
> > static int
> > +ipc_parse_version32(int *cmd)
> > +{
> > + if (*cmd & IPC_64) {
> > + *cmd ^= IPC_64;
> > + return IPC_64;
> > + } else {
> > + return IPC_OLD;
> > + }
> > +}
> > +
> > +static int
> > do_sys32_semctl(int first, int second, int third, void *uptr)
> > {
> > union semun fourth;
> > @@ -1603,12 +1657,15 @@
> > static int
> > do_sys32_msgsnd (int first, int second, int third, void *uptr)
> > {
> > - struct msgbuf *p = kmalloc (second + sizeof (struct msgbuf)
> > - + 4, GFP_USER);
> > struct msgbuf32 *up = (struct msgbuf32 *)uptr;
> > + struct msgbuf *p;
> > mm_segment_t old_fs;
> > int err;
> >
> > + if (second < 0)
> > + return -EINVAL;
> > + p = kmalloc (second + sizeof (struct msgbuf)
> > + + 4, GFP_USER);
> > if (!p)
> > return -ENOMEM;
> > err = get_user (p->mtype, &up->mtype);
> > @@ -1636,18 +1693,21 @@
> > int err;
> >
> > if (!version) {
> > - struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;
> > - struct ipc_kludge ipck;
> > + struct ipc_kludge32 *uipck = (struct ipc_kludge32 *)uptr;
> > + struct ipc_kludge32 ipck;
> >
> > err = -EINVAL;
> > if (!uptr)
> > goto out;
> > err = -EFAULT;
> > - if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))
> > + if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
> > goto out;
> > - uptr = (void *)A(ipck.msgp);
> > + uptr = (void *)AA(ipck.msgp);
> > msgtyp = ipck.msgtyp;
> > }
> > +
> > + if (second < 0)
> > + return -EINVAL;
> > err = -ENOMEM;
> > p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
> > if (!p)
> > @@ -1673,9 +1733,10 @@
> > {
> > int err = -EINVAL, err2;
> > struct msqid_ds m;
> > - struct msqid64_ds m64;
> > - struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
> > + struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
> > + struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
> > mm_segment_t old_fs;
> > + int version = ipc_parse_version32(&second);
> >
> > switch (second) {
> >
> > @@ -1686,10 +1747,25 @@
> > break;
> >
> > case IPC_SET:
> > - err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
> > - err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
> > - err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
> > - err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
> > + if (version == IPC_64) {
> > + if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
> > + err = -EFAULT;
> > + break;
> > + }
> > + err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
> > + err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
> > + err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
> > + err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
> > + } else {
> > + if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
> > + err = -EFAULT;
> > + break;
> > + }
> > + err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
> > + err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
> > + err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
> > + err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
> > + }
> > if (err)
> > break;
> > old_fs = get_fs ();
> > @@ -1702,27 +1778,54 @@
> > case MSG_STAT:
> > old_fs = get_fs ();
> > set_fs (KERNEL_DS);
> > - err = sys_msgctl (first, second, (void *) &m64);
> > + err = sys_msgctl (first, second, &m);
> > set_fs (old_fs);
> > - err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);
> > - err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);
> > - err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);
> > - err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);
> > - err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);
> > - err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);
> > - err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);
> > - err2 |= __put_user(m64.msg_stime, &up->msg_stime);
> > - err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);
> > - err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);
> > - err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);
> > - err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);
> > - err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);
> > - err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);
> > - err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);
> > - if (err2)
> > - err = -EFAULT;
> > + if (version == IPC_64) {
> > + if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
> > + err = -EFAULT;
> > + break;
> > + }
> > + err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
> > + err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
> > + err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
> > + err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
> > + err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
> > + err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
> > + err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
> > + err2 |= __put_user(m.msg_stime, &up64->msg_stime);
> > + err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
> > + err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
> > + err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
> > + err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
> > + err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
> > + err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
> > + err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
> > + if (err2)
> > + err = -EFAULT;
> > + } else {
> > + if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
> > + err = -EFAULT;
> > + break;
> > + }
> > + err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
> > + err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
> > + err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
> > + err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
> > + err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
> > + err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
> > + err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
> > + err2 |= __put_user(m.msg_stime, &up32->msg_stime);
> > + err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
> > + err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
> > + err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
> > + err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
> > + err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
> > + err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
> > + err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
> > + if (err2)
> > + err = -EFAULT;
> > + }
> > break;
> > -
> > }
> >
> > return err;
> > @@ -1845,7 +1948,7 @@
> >
> > case SEMOP:
> > /* struct sembuf is the same on 32 and 64bit :)) */
> > - err = sys_semop (first, (struct sembuf *)A(ptr),
> > + err = sys_semop (first, (struct sembuf *)AA(ptr),
> > second);
> > break;
> > case SEMGET:
> > @@ -1853,36 +1956,36 @@
> > break;
> > case SEMCTL:
> > err = do_sys32_semctl (first, second, third,
> > - (void *)A(ptr));
> > + (void *)AA(ptr));
> > break;
> >
> > case MSGSND:
> > err = do_sys32_msgsnd (first, second, third,
> > - (void *)A(ptr));
> > + (void *)AA(ptr));
> > break;
> > case MSGRCV:
> > err = do_sys32_msgrcv (first, second, fifth, third,
> > - version, (void *)A(ptr));
> > + version, (void *)AA(ptr));
> > break;
> > case MSGGET:
> > err = sys_msgget ((key_t) first, second);
> > break;
> > case MSGCTL:
> > - err = do_sys32_msgctl (first, second, (void *)A(ptr));
> > + err = do_sys32_msgctl (first, second, (void *)AA(ptr));
> > break;
> >
> > case SHMAT:
> > err = do_sys32_shmat (first, second, third,
> > - version, (void *)A(ptr));
> > + version, (void *)AA(ptr));
> > break;
> > case SHMDT:
> > - err = sys_shmdt ((char *)A(ptr));
> > + err = sys_shmdt ((char *)AA(ptr));
> > break;
> > case SHMGET:
> > err = sys_shmget (first, second, third);
> > break;
> > case SHMCTL:
> > - err = do_sys32_shmctl (first, second, (void *)A(ptr));
> > + err = do_sys32_shmctl (first, second, (void *)AA(ptr));
> > break;
> > default:
> > err = -EINVAL;
--
_ _ ____ ___ Carsten Langgaard Mailto:carstenl@mips.com
|\ /|||___)(___ MIPS Denmark Direct: +45 4486 5527
| \/ ||| ____) Lautrupvang 4B Switch: +45 4486 5555
TECHNOLOGIES 2750 Ballerup Fax...: +45 4486 5556
Denmark http://www.mips.com
prev parent reply other threads:[~2002-08-19 13:48 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-08-07 14:42 IPC syscall fixup (o32 conversion layer) Carsten Langgaard
2002-08-07 14:58 ` Maciej W. Rozycki
2002-08-07 15:13 ` Ralf Baechle
2002-08-07 15:24 ` Maciej W. Rozycki
2002-08-08 6:57 ` Carsten Langgaard
2002-08-13 3:23 ` Ralf Baechle
2002-08-19 13:49 ` Carsten Langgaard [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3D60F773.3C64C13E@mips.com \
--to=carstenl@mips.com \
--cc=linux-mips@oss.sgi.com \
--cc=macro@ds2.pg.gda.pl \
--cc=ralf@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox