Hi Arnd

I have made the changes suggested, and attached it below. I think it
should be good now.  
Just a couple of questions if I may. 
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. 
Does that also mean that copy_to_user should not be used in ioctl
calls? 

I was wondering if this the compat_sock_get_timestamp function is
needed? If I were to remove the SIOCGSTAMP case from the
compat_x25_ioctl function, then a SIOCGSTAMP ioctl system call would
return -ENOIOCTLCMD which could  then be handled by do_siocgstamp
handler in the ioctl32_hash_table? (fs/compat_ioctl.c)
In which case I could remove this patch from the rest of the series.
 
/Shaun


Index: linux-2.6.15/include/net/compat.h
===================================================================
--- linux-2.6.15.orig/include/net/compat.h
+++ linux-2.6.15/include/net/compat.h
@@ -23,6 +23,8 @@ struct compat_cmsghdr {
        compat_int_t    cmsg_type;
 };
 
+extern int compat_sock_get_timestamp(struct sock *, struct timeval
__user *);
+
 #else /* defined(CONFIG_COMPAT) */
 #define compat_msghdr  msghdr          /* to avoid compiler warnings */
 #endif /* defined(CONFIG_COMPAT) */
Index: linux-2.6.15/net/compat.c
===================================================================
--- linux-2.6.15.orig/net/compat.c
+++ linux-2.6.15/net/compat.c
@@ -503,6 +503,25 @@ static int do_get_sock_timeout(int fd, i
        return err;
 }
 
+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;
+}
+
 asmlinkage long compat_sys_getsockopt(int fd, int level, int optname,
                                char __user *optval, int __user *optlen)
 {
@@ -602,3 +621,5 @@ asmlinkage long compat_sys_socketcall(in
        }
        return ret;
 }
+
+EXPORT_SYMBOL(compat_sock_get_timestamp);


On Fri, 2006-01-13 at 11:46 +0000, Arnd Bergmann wrote:
> On Friday 13 January 2006 03:14, Shaun Pereira wrote:
> > Thank you for reviewing that bit of code.  
> > I had a look at compat_sys_gettimeofday and sys32_gettimeofday codes.
> > They seem to work in a similar way, casting a pointer to the structure
> > from user space to a compat_timeval type.
> 
> The part with the case is ok, except that you don't have to write
> 
> struct compat_timeval __user *ctv;
> ctv = (struct compat_timeval __user*) userstamp;
> 
> Instead,
> 
> struct compat_timeval __user *ctv = userstamp;
> 
> is the more common way to write it. The result is the same, since
> userstamp is a 'void __user *'.
> 
> > But to make sure I have tested the routine by forcing the sk-
> > >sk_stamp.tv_sec value to 0 in the x25_module ( for testing purposes
> > only, as it is initialised to -1). Now when
> > I make a 32 bit userspace SIOCGSTAMP ioctl to the 64 bit kernel I should
> > get the current time back in user space. This seems to work, the ioctl
> > returns the system time (just after TEST6:)
> > 
> > So I have left the patch as is for now. However if necessary to use
> > the element-by-element __put_user routine as in put_tv32, then I can
> > make the change, just let me know.
> 
> You need to to exactly that, yes. I'm not sure what exactly you have
> tested, but the expected result of your code would be that you see
> the sk_stamp.tv_sec value in the output, but not the tv_usec value.
> 
> On little-endian system like x86_64, that is not much of a difference
> (less than a second) that you might miss in a test case, but on
> big-endian, it would be fatal.
> 
> The layout of the structures on most systems is 
> 
>               64 bit LE       64 bit BE       32 bit
> 
> bytes 0-3     tv_sec low      tv_sec high     tv_sec low
> bytes 4-7     tv_sec high     tv_sec low      tv_usec low
> bytes 8-11    tv_usec low     tv_usec high
> bytes 12-15   tv_usec high    tv_usec low
> 
> You code copies the first eight bytes of the 64 bit data structure
> into the 32 bit data structure.
> 
>       Arnd <><

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to