From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LuSUj-0003Dw-07 for qemu-devel@nongnu.org; Thu, 16 Apr 2009 10:23:13 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LuSUi-0003Dg-6a for qemu-devel@nongnu.org; Thu, 16 Apr 2009 10:23:12 -0400 Received: from [199.232.76.173] (port=50248 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LuSUi-0003Dd-17 for qemu-devel@nongnu.org; Thu, 16 Apr 2009 10:23:12 -0400 Received: from naru.obs2.net ([84.20.150.76]:45790) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LuSUg-0004OF-VZ for qemu-devel@nongnu.org; Thu, 16 Apr 2009 10:23:11 -0400 Date: Thu, 16 Apr 2009 17:23:09 +0300 From: Riku Voipio Subject: Re: [Qemu-devel] [PATCH 04/10] fix IPCOP_sem* and implement sem* Message-ID: <20090416142309.GH28127@kos.to> References: <20090415152823.GA9642@volta.aurel32.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20090415152823.GA9642@volta.aurel32.net> Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Aurelien Jarno Cc: qemu-devel@nongnu.org On Wed, Apr 15, 2009 at 05:28:23PM +0200, Aurelien Jarno wrote: > > +struct target_sembuf { > > + unsigned short sem_num; > > + short sem_op; > > + short sem_flg; > > +}; > > + > > +static inline abi_long target_to_host_sembuf(struct sembuf *host_sembuf, > > + abi_ulong target_addr, > > + unsigned nsops) > > +{ > > + struct target_sembuf *target_sembuf; > > + int i; > > + > > + target_sembuf = lock_user(VERIFY_READ, target_addr, > > + nsops*sizeof(struct target_sembuf), 1); > > + if (!target_sembuf) > > + return -TARGET_EFAULT; > > + > > + for(i=0; i > + __put_user(target_sembuf[i].sem_num, &host_sembuf[i].sem_num); > > + __put_user(target_sembuf[i].sem_op, &host_sembuf[i].sem_op); > > + __put_user(target_sembuf[i].sem_flg, &host_sembuf[i].sem_flg); > > + } > I don't follow fully the subtle difference between __put_user() and > __get_user,() but given lock_user is called with VERIFY_READ, I think > __get_user() should be used instead. Yes.. since the target and host args are swapped, it still works like __get_user. Corrected version attached. (This error appears also once in the shm* patch too) >>From 32b512d9b521d2b146658f932b9c3553cd3ec1cd Mon Sep 17 00:00:00 2001 From: Riku Voipio Date: Fri, 3 Apr 2009 00:28:14 +0300 Subject: [PATCH] [v2] fix IPCOP_sem* and implement sem* From: Kirill A. Shutemov Fix and cleanup IPCOP_sem* ipc calls handling and implement sem* syscalls. Riku: 1) Uglify whitespace so that diff gets smaller and easier to review 2) use __get_user in target_to_host_sembuf Signed-off-by: Riku Voipio --- linux-user/syscall.c | 286 +++++++++++++++++++++++++++++++++----------------- 1 files changed, 188 insertions(+), 98 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 74b41a8..92e5159 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -2005,7 +2005,8 @@ static inline abi_long target_to_host_semid_ds(struct semid_ds *host_sd, if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) return -TARGET_EFAULT; - target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr); + if (target_to_host_ipc_perm(&(host_sd->sem_perm),target_addr)) + return -TARGET_EFAULT; host_sd->sem_nsems = tswapl(target_sd->sem_nsems); host_sd->sem_otime = tswapl(target_sd->sem_otime); host_sd->sem_ctime = tswapl(target_sd->sem_ctime); @@ -2020,7 +2021,8 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr, if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) return -TARGET_EFAULT; - host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm)); + if (host_to_target_ipc_perm(target_addr,&(host_sd->sem_perm))) + return -TARGET_EFAULT;; target_sd->sem_nsems = tswapl(host_sd->sem_nsems); target_sd->sem_otime = tswapl(host_sd->sem_otime); target_sd->sem_ctime = tswapl(host_sd->sem_ctime); @@ -2028,135 +2030,214 @@ static inline abi_long host_to_target_semid_ds(abi_ulong target_addr, return 0; } +struct target_seminfo { + int semmap; + int semmni; + int semmns; + int semmnu; + int semmsl; + int semopm; + int semume; + int semusz; + int semvmx; + int semaem; +}; + +static inline abi_long host_to_target_seminfo(abi_ulong target_addr, + struct seminfo *host_seminfo) +{ + struct target_seminfo *target_seminfo; + if (!lock_user_struct(VERIFY_WRITE, target_seminfo, target_addr, 0)) + return -TARGET_EFAULT; + __put_user(host_seminfo->semmap, &target_seminfo->semmap); + __put_user(host_seminfo->semmni, &target_seminfo->semmni); + __put_user(host_seminfo->semmns, &target_seminfo->semmns); + __put_user(host_seminfo->semmnu, &target_seminfo->semmnu); + __put_user(host_seminfo->semmsl, &target_seminfo->semmsl); + __put_user(host_seminfo->semopm, &target_seminfo->semopm); + __put_user(host_seminfo->semume, &target_seminfo->semume); + __put_user(host_seminfo->semusz, &target_seminfo->semusz); + __put_user(host_seminfo->semvmx, &target_seminfo->semvmx); + __put_user(host_seminfo->semaem, &target_seminfo->semaem); + unlock_user_struct(target_seminfo, target_addr, 1); + return 0; +} + union semun { int val; struct semid_ds *buf; unsigned short *array; + struct seminfo *__buf; }; union target_semun { int val; - abi_long buf; - unsigned short int *array; + abi_ulong buf; + abi_ulong array; + abi_ulong __buf; }; -static inline abi_long target_to_host_semun(int cmd, - union semun *host_su, - abi_ulong target_addr, - struct semid_ds *ds) +static inline abi_long target_to_host_semarray(int semid, unsigned short **host_array, + abi_ulong target_addr) { - union target_semun *target_su; + int nsems; + unsigned short *array; + union semun semun; + struct semid_ds semid_ds; + int i, ret; - switch( cmd ) { - case IPC_STAT: - case IPC_SET: - if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) - return -TARGET_EFAULT; - target_to_host_semid_ds(ds,target_su->buf); - host_su->buf = ds; - unlock_user_struct(target_su, target_addr, 0); - break; - case GETVAL: - case SETVAL: - if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) - return -TARGET_EFAULT; - host_su->val = tswapl(target_su->val); - unlock_user_struct(target_su, target_addr, 0); - break; - case GETALL: - case SETALL: - if (!lock_user_struct(VERIFY_READ, target_su, target_addr, 1)) - return -TARGET_EFAULT; - *host_su->array = tswap16(*target_su->array); - unlock_user_struct(target_su, target_addr, 0); - break; - default: - gemu_log("semun operation not fully supported: %d\n", (int)cmd); + semun.buf = &semid_ds; + + ret = semctl(semid, 0, IPC_STAT, semun); + if (ret == -1) + return get_errno(ret); + + nsems = semid_ds.sem_nsems; + + *host_array = malloc(nsems*sizeof(unsigned short)); + array = lock_user(VERIFY_READ, target_addr, + nsems*sizeof(unsigned short), 1); + if (!array) + return -TARGET_EFAULT; + + for(i=0; ibuf,ds); - unlock_user_struct(target_su, target_addr, 1); - break; - case GETVAL: - case SETVAL: - if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0)) - return -TARGET_EFAULT; - target_su->val = tswapl(host_su->val); - unlock_user_struct(target_su, target_addr, 1); - break; - case GETALL: - case SETALL: - if (lock_user_struct(VERIFY_WRITE, target_su, target_addr, 0)) - return -TARGET_EFAULT; - *target_su->array = tswap16(*host_su->array); - unlock_user_struct(target_su, target_addr, 1); - break; - default: - gemu_log("semun operation not fully supported: %d\n", (int)cmd); + semun.buf = &semid_ds; + + ret = semctl(semid, 0, IPC_STAT, semun); + if (ret == -1) + return get_errno(ret); + + nsems = semid_ds.sem_nsems; + + array = lock_user(VERIFY_WRITE, target_addr, + nsems*sizeof(unsigned short), 0); + if (!array) + return -TARGET_EFAULT; + + for(i=0; i