Sunday, November 14, 2010

Eliminate instructions at compile time trick

Vasiliy Kulikov noted a bug in select code and proposed a fix:
 [..] struct timeval has padding bytes at the end.  This struct is copied to
 userspace with these padding bytes uninitialized.  This leads to leaking
 of contents of kernel stack memory.


 --- a/fs/select.c
 +++ b/fs/select.c
 @@ -306,6 +306,7 @@ static int poll_select_copy_remaining(struct timespec
 *end_time, void __user *p,
               rts.tv_sec = rts.tv_nsec = 0;

       if (timeval) {
 +             memset(&rtv, 0, sizeof(rtv));
               rtv.tv_sec = rts.tv_sec;
               rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;




 Andrew Morton noted that
 | struct timeval has padding bytes at the end.
 On sparc and parisc.  On all other architectures this patch is a waste
 of cycles.

 And came up with this patch:

       if (timeval) {
 -             memset(&rtv, 0, sizeof(rtv));
 +             if (sizeof(rtv) > sizeof(rtv.tv_sec) + sizeof(rtv.tv_usec))
 +                     memset(&rtv, 0, sizeof(rtv));
               rtv.tv_sec = rts.tv_sec;
               rtv.tv_usec = rts.tv_nsec / NSEC_PER_USEC;


 The `if' gets eliminated at compile time.  With this approach we add
 four bytes of text to the sparc64 build and zero bytes of text to the
 x86_64 build.

No comments:

Post a Comment