From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IXzP7-0001qY-4M for qemu-devel@nongnu.org; Wed, 19 Sep 2007 09:15:45 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IXzP6-0001q0-70 for qemu-devel@nongnu.org; Wed, 19 Sep 2007 09:15:44 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IXzP5-0001pk-Tv for qemu-devel@nongnu.org; Wed, 19 Sep 2007 09:15:44 -0400 Received: from owa.c2.net ([207.235.78.2] helo=email.c2.net) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IXzP5-0002LP-IQ for qemu-devel@nongnu.org; Wed, 19 Sep 2007 09:15:43 -0400 From: Thayne Harbaugh In-Reply-To: <1190207177.9564.115.camel@phantasm.home.enterpriseandprosperity.com> References: <1190205992.9564.88.camel@phantasm.home.enterpriseandprosperity.com> <1190206302.9564.91.camel@phantasm.home.enterpriseandprosperity.com> <1190206395.9564.94.camel@phantasm.home.enterpriseandprosperity.com> <1190206457.9564.95.camel@phantasm.home.enterpriseandprosperity.com> <1190206659.9564.97.camel@phantasm.home.enterpriseandprosperity.com> <1190206714.9564.99.camel@phantasm.home.enterpriseandprosperity.com> <1190206770.9564.101.camel@phantasm.home.enterpriseandprosperity.com> <1190206856.9564.104.camel@phantasm.home.enterpriseandprosperity.com> <1190206906.9564.105.camel@phantasm.home.enterpriseandprosperity.com> <1190206961.9564.107.camel@phantasm.home.enterpriseandprosperity.com> <1190207013.9564.109.camel@phantasm.home.enterpriseandprosperity.com> <1190207059.9564.111.camel@phantasm.home.enterpriseandprosperity.com> <1190207107.9564.113.camel@phantasm.home.enterpriseandprosperity.com> <1190207177.9564.115.camel@phantasm.home.enterpriseandprosperity.com> Content-Type: multipart/mixed; boundary="=-DzQHNmSbrRECWEuyDGvi" Date: Wed, 19 Sep 2007 07:09:08 -0600 Message-Id: <1190207348.9564.119.camel@phantasm.home.enterpriseandprosperity.com> Mime-Version: 1.0 Subject: [Qemu-devel] Re: [PATCH] linux-user stat64_put_user function Reply-To: thayne@c2.net, qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --=-DzQHNmSbrRECWEuyDGvi Content-Type: text/plain Content-Transfer-Encoding: 7bit This patch puts stat64 functionality into a function rather than using gotos for all the locations that copy stat64 buffers to user space. This patch is necessary for following fstatat64 syscall patch. --=-DzQHNmSbrRECWEuyDGvi Content-Disposition: attachment; filename=35_stat64_put_user.patch Content-Type: text/x-patch; name=35_stat64_put_user.patch; charset=UTF-8 Content-Transfer-Encoding: 7bit Index: qemu/linux-user/syscall.c =================================================================== --- qemu.orig/linux-user/syscall.c 2007-09-19 06:28:30.000000000 -0600 +++ qemu/linux-user/syscall.c 2007-09-19 06:28:34.000000000 -0600 @@ -526,6 +526,77 @@ return 0; } +#ifdef TARGET_ARM +#define copy_to_user_statbuf64_wrapper(tsb,hsb) \ + ((((CPUARMState *)cpu_env)->eabi) \ + ? copy_to_user_statbuf64_eabi((tsb),(hsb)) \ + : copy_to_user_statbuf64((tsb),(hsb))) +#else +#define copy_to_user_statbuf64_wrapper(tsb,hsb) \ + copy_to_user_eabi_statbuf64((tsb),(hsb)) +#endif + +#ifdef TARGET_ARM +static inline long copy_to_user_statbuf64_eabi(void *gen_target_stbuf, + const struct stat *host_stbuf) +{ + struct target_eabi_stat64 *target_stbuf = (struct target_eabi_stat64 *)gen_target_stbuf; + int i; + + if( !access_ok(VERIFY_WRITE,target_stbuf,sizeof(struct target_eabi_stat64)) ) return -EFAULT; + memset(target_stbuf, 0, sizeof(struct target_eabi_stat64)); + /* use __put_user() since we just checked that the buffer is valid */ + __put_user(host_stbuf->st_dev, &target_stbuf->st_dev); + __put_user(host_stbuf->st_ino, &target_stbuf->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_stbuf->st_ino, &target_stbuf->__st_ino); +#endif + __put_user(host_stbuf->st_mode, &target_stbuf->st_mode); + __put_user(host_stbuf->st_nlink, &target_stbuf->st_nlink); + __put_user(host_stbuf->st_uid, &target_stbuf->st_uid); + __put_user(host_stbuf->st_gid, &target_stbuf->st_gid); + __put_user(host_stbuf->st_rdev, &target_stbuf->st_rdev); + /* XXX: better use of kernel struct */ + __put_user(host_stbuf->st_size, &target_stbuf->st_size); + __put_user(host_stbuf->st_blksize, &target_stbuf->st_blksize); + __put_user(host_stbuf->st_blocks, &target_stbuf->st_blocks); + __put_user(host_stbuf->st_atime, &target_stbuf->target_st_atime); + __put_user(host_stbuf->st_mtime, &target_stbuf->target_st_mtime); + __put_user(host_stbuf->st_ctime, &target_stbuf->target_st_ctime); + + return 0; +} +#endif + +static inline long copy_to_user_statbuf64(void *gen_target_stbuf, + const struct stat *host_stbuf) +{ + struct target_stat64 *target_stbuf = (struct target_stat64 *)gen_target_stbuf; + gemu_log("%s()\n", __func__); + if( !access_ok(VERIFY_WRITE,target_stbuf,sizeof(struct target_stat64)) ) return -EFAULT; + memset(target_stbuf, 0, sizeof(struct target_stat64)); + /* use __put_user() since we just checked that the buffer is valid */ + __put_user(host_stbuf->st_dev, &target_stbuf->st_dev); + __put_user(host_stbuf->st_ino, &target_stbuf->st_ino); +#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO + __put_user(host_stbuf->st_ino, &target_stbuf->__st_ino); +#endif + __put_user(host_stbuf->st_mode, &target_stbuf->st_mode); + __put_user(host_stbuf->st_nlink, &target_stbuf->st_nlink); + __put_user(host_stbuf->st_uid, &target_stbuf->st_uid); + __put_user(host_stbuf->st_gid, &target_stbuf->st_gid); + __put_user(host_stbuf->st_rdev, &target_stbuf->st_rdev); + /* XXX: better use of kernel struct */ + __put_user(host_stbuf->st_size, &target_stbuf->st_size); + __put_user(host_stbuf->st_blksize, &target_stbuf->st_blksize); + __put_user(host_stbuf->st_blocks, &target_stbuf->st_blocks); + __put_user(host_stbuf->st_atime, &target_stbuf->target_st_atime); + __put_user(host_stbuf->st_mtime, &target_stbuf->target_st_mtime); + __put_user(host_stbuf->st_ctime, &target_stbuf->target_st_ctime); + return 0; +} + + static inline long copy_from_user_timeval(struct timeval *tv, struct target_timeval *target_tv) { @@ -4562,7 +4633,10 @@ if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT; ret = get_errno(stat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret) + && copy_to_user_statbuf64_wrapper(arg2,&st)) + return -EFAULT; + break; #endif #ifdef TARGET_NR_lstat64 case TARGET_NR_lstat64: @@ -4570,65 +4644,18 @@ if( !access_ok(VERIFY_READ,p,1) ) return -EFAULT; ret = get_errno(lstat(path(p), &st)); unlock_user(p, arg1, 0); - goto do_stat64; + if (!is_error(ret) + && copy_to_user_statbuf64_wrapper(arg2,&st)) + return -EFAULT; + break; #endif #ifdef TARGET_NR_fstat64 case TARGET_NR_fstat64: - { - ret = get_errno(fstat(arg1, &st)); - do_stat64: - if (!is_error(ret)) { -#ifdef TARGET_ARM - if (((CPUARMState *)cpu_env)->eabi) { - struct target_eabi_stat64 *target_st = (struct target_eabi_stat64 *)arg2; - if( !access_ok(VERIFY_WRITE,target_st,sizeof(struct target_eabi_stat64)) ) return -EFAULT; - memset(target_st, 0, sizeof(struct target_eabi_stat64)); - /* use __put_user() since we just checked that the buffer is valid */ - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - /* XXX: better use of kernel struct */ - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - } else -#endif - { - struct target_stat64 *target_st = (struct target_stat64 *)arg2; - if( !access_ok(VERIFY_WRITE,target_st,sizeof(struct target_stat64)) ) return -EFAULT; - memset(target_st, 0, sizeof(struct target_stat64)); - /* use __put_user() since we just checked that the buffer is valid */ - __put_user(st.st_dev, &target_st->st_dev); - __put_user(st.st_ino, &target_st->st_ino); -#ifdef TARGET_STAT64_HAS_BROKEN_ST_INO - __put_user(st.st_ino, &target_st->__st_ino); -#endif - __put_user(st.st_mode, &target_st->st_mode); - __put_user(st.st_nlink, &target_st->st_nlink); - __put_user(st.st_uid, &target_st->st_uid); - __put_user(st.st_gid, &target_st->st_gid); - __put_user(st.st_rdev, &target_st->st_rdev); - /* XXX: better use of kernel struct */ - __put_user(st.st_size, &target_st->st_size); - __put_user(st.st_blksize, &target_st->st_blksize); - __put_user(st.st_blocks, &target_st->st_blocks); - __put_user(st.st_atime, &target_st->target_st_atime); - __put_user(st.st_mtime, &target_st->target_st_mtime); - __put_user(st.st_ctime, &target_st->target_st_ctime); - } - } - } - break; + ret = get_errno(fstat(arg1, &st)); + if (!is_error(ret) + && copy_to_user_statbuf64_wrapper(arg2,&st)) + return -EFAULT; + break; #endif #ifdef USE_UID16 case TARGET_NR_lchown: --=-DzQHNmSbrRECWEuyDGvi--