From: Laurent Vivier <laurent@vivier.eu>
To: qemu-devel@nongnu.org
Cc: Riku Voipio <riku.voipio@iki.fi>, Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH] linux-user: correct semctl() and shmctl()
Date: Thu, 20 Dec 2012 21:58:56 +0100 [thread overview]
Message-ID: <1356037136-19479-1-git-send-email-laurent@vivier.eu> (raw)
The parameter "union semun" of semctl() is not a value
but a pointer to the value.
Moreover, all fields of target_su must be swapped (if needed).
The third argument of shmctl is a pointer.
WITHOUT this patch:
$ ipcs
kernel not configured for shared memory
qemu: uncaught target signal 11 (Segmentation fault) - core dumped
WITH this patch:
$ ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
0x4e545030 0 root 600 96 1
0x4e545031 32769 root 600 96 1
0x4e545032 65538 root 666 96 1
0x4e545033 98307 root 666 96 1
0x47505344 131076 root 666 8240 1
0x3c81b7f5 163845 laurent 666 4096 0
0x00000000 729513990 laurent 600 393216 2 dest
0x00000000 729546759 laurent 600 393216 2 dest
0x00000000 1879179273 laurent 600 393216 2 dest
------ Semaphore Arrays --------
key semid owner perms nsems
0x3c81b7f6 32768 laurent 666 1
0x1c44ac47 6586369 laurent 600 1
------ Message Queues --------
key msqid owner perms used-bytes messages
0x1c44ac45 458752 laurent 600 0 0
0x1c44ac46 491521 laurent 600 0 0
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
---
linux-user/syscall.c | 37 ++++++++++++++++++++++++++-----------
1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index c2a2343..7bab006 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -2656,24 +2656,26 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd,
break;
case GETALL:
case SETALL:
- err = target_to_host_semarray(semid, &array, target_su.array);
+ err = target_to_host_semarray(semid, &array,
+ tswapal(target_su.array));
if (err)
return err;
arg.array = array;
ret = get_errno(semctl(semid, semnum, cmd, arg));
- err = host_to_target_semarray(semid, target_su.array, &array);
+ err = host_to_target_semarray(semid, tswapal(target_su.array),
+ &array);
if (err)
return err;
break;
case IPC_STAT:
case IPC_SET:
case SEM_STAT:
- err = target_to_host_semid_ds(&dsarg, target_su.buf);
+ err = target_to_host_semid_ds(&dsarg, tswapal(target_su.buf));
if (err)
return err;
arg.buf = &dsarg;
ret = get_errno(semctl(semid, semnum, cmd, arg));
- err = host_to_target_semid_ds(target_su.buf, &dsarg);
+ err = host_to_target_semid_ds(tswapal(target_su.buf), &dsarg);
if (err)
return err;
break;
@@ -2681,7 +2683,7 @@ static inline abi_long do_semctl(int semid, int semnum, int cmd,
case SEM_INFO:
arg.__buf = &seminfo;
ret = get_errno(semctl(semid, semnum, cmd, arg));
- err = host_to_target_seminfo(target_su.__buf, &seminfo);
+ err = host_to_target_seminfo(tswapal(target_su.__buf), &seminfo);
if (err)
return err;
break;
@@ -3161,10 +3163,16 @@ static abi_long do_ipc(unsigned int call, int first,
ret = get_errno(semget(first, second, third));
break;
- case IPCOP_semctl:
- ret = do_semctl(first, second, third, (union target_semun)(abi_ulong) ptr);
+ case IPCOP_semctl: {
+ union target_semun *target_su;
+ if (!lock_user_struct(VERIFY_READ, target_su, ptr, 1)) {
+ ret = -TARGET_EFAULT;
+ break;
+ }
+ ret = do_semctl(first, second, third, *target_su);
+ unlock_user_struct(target_su, ptr, 0);
break;
-
+ }
case IPCOP_msgget:
ret = get_errno(msgget(first, second));
break;
@@ -3229,7 +3237,7 @@ static abi_long do_ipc(unsigned int call, int first,
/* IPC_* and SHM_* command values are the same on all linux platforms */
case IPCOP_shmctl:
- ret = do_shmctl(first, second, third);
+ ret = do_shmctl(first, second, ptr);
break;
default:
gemu_log("Unsupported ipc call: %d (version %d)\n", call, version);
@@ -6996,9 +7004,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
break;
#endif
#ifdef TARGET_NR_semctl
- case TARGET_NR_semctl:
- ret = do_semctl(arg1, arg2, arg3, (union target_semun)(abi_ulong)arg4);
+ case TARGET_NR_semctl: {
+ union target_semun *target_su;
+ if (!lock_user_struct(VERIFY_READ, target_su, arg4, 1)) {
+ ret = -TARGET_EFAULT;
+ break;
+ }
+ ret = do_semctl(arg1, arg2, arg3, *target_su);
+ unlock_user_struct(target_su, ptr, 0);
break;
+ }
#endif
#ifdef TARGET_NR_msgctl
case TARGET_NR_msgctl:
--
1.7.10.4
next reply other threads:[~2012-12-20 20:59 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-12-20 20:58 Laurent Vivier [this message]
2013-01-01 23:10 ` [Qemu-devel] [PATCH] linux-user: correct semctl() and shmctl() Laurent Vivier
2013-01-02 0:00 ` Peter Maydell
2013-01-02 20:38 ` [Qemu-devel] [PATCH][v2] " Laurent Vivier
2013-01-19 23:28 ` Laurent Vivier
2013-01-20 11:24 ` Peter Maydell
2013-01-20 21:12 ` [Qemu-devel] [PATCH] " Laurent Vivier
2013-01-20 21:45 ` Peter Maydell
2013-01-21 6:25 ` [Qemu-devel] [PATCH][v3] " Laurent Vivier
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=1356037136-19479-1-git-send-email-laurent@vivier.eu \
--to=laurent@vivier.eu \
--cc=qemu-devel@nongnu.org \
--cc=riku.voipio@iki.fi \
/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;
as well as URLs for NNTP newsgroup(s).