Re: 32 bit (socket layer) ioctl emulation for 64 bit kernels
From: YOSHIFUJI Hideaki / 吉藤英明 <hidden>
Date: 2006-01-16 06:40:19
Also in:
lkml
In article [ref] (at Mon, 16 Jan 2006 16:59:20 +1100), Shaun Pereira [off-list ref] says:
If I understand correctly from your comments (thanks for that, they are helpful) copy_to_user acts like a memcopy for an 'array' of bytes and should not be used to copy the timeval struct to userspace. Rather put_user / __put_user macros should be used which allows transfer of single element values of the structure.
+int compat_sock_get_timestamp(struct sock *sk, struct timeval __user
*userstamp)
+{
+ struct compat_timeval __user *ctv
+ = (struct compat_timeval __user*) userstamp;
+ int err = -ENOENT;
+ if(!sock_flag(sk, SOCK_TIMESTAMP))
+ sock_enable_timestamp(sk);
+ if(sk->sk_stamp.tv_sec == -1)
+ return err;
+ if(sk->sk_stamp.tv_sec == 0)
+ do_gettimeofday(&sk->sk_stamp);
+ err = -EFAULT;
+ if(access_ok(VERIFTY_WRITE, ctv, sizeof(*ctv))) {
+ err = __put_user(sk->sk_stamp.tv_sec, &ctv->tv_sec);
+ err != __put_user(sk->sk_stamp.tv_usec, &ctv->tv_usec);
+ }
+ return err;
+}
+
Hmm, you will copy 32bit of MSB in big-endian.
You should do something like this:
strtuct compat_timeval tvtmp;
:
tvtmp.tv_sec = sk->sk_stamp.tv_sec;
tvtmp.tv_usec = sk->sk_stemp.tv_usec;
return copy_to_user(ctv, &tvtmp, sizeof(tvtmp));
Or, am I miss something?
--yoshfuji