qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] linux-user: correct semctl() and shmctl()


From: Laurent Vivier
Subject: Re: [Qemu-devel] [PATCH] linux-user: correct semctl() and shmctl()
Date: Wed, 02 Jan 2013 00:10:15 +0100

Ping !

Le jeudi 20 décembre 2012 à 21:58 +0100, Laurent Vivier a écrit :
> 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 <address@hidden>
> ---
>  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:

-- 
"Just play. Have fun. Enjoy the game."
- Michael Jordan
"Just play. Have fun. Enjoy the game."
- Michael Jordan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]