From: Andi Kleen The rtc driver currently checks for sizeof(unsigned long) for reads. This does not work very well when you run an 64bit kernel with 32bit userland, which always passes sizeof(int). Handle both int and long in rtc_read depending on the user read size. drivers/char/rtc.c | 12 ++++++++---- 1 files changed, 8 insertions(+), 4 deletions(-) diff -puN drivers/char/rtc.c~rtc-32-bit-fix drivers/char/rtc.c --- 25/drivers/char/rtc.c~rtc-32-bit-fix 2003-06-08 03:04:40.000000000 -0700 +++ 25-akpm/drivers/char/rtc.c 2003-06-08 03:04:40.000000000 -0700 @@ -279,7 +279,7 @@ static ssize_t rtc_read(struct file *fil if (rtc_has_irq == 0) return -EIO; - if (count < sizeof(unsigned long)) + if (count < sizeof(int)) return -EINVAL; add_wait_queue(&rtc_wait, &wait); @@ -309,9 +309,13 @@ static ssize_t rtc_read(struct file *fil schedule(); } while (1); - retval = put_user(data, (unsigned long *)buf); - if (!retval) - retval = sizeof(unsigned long); + if (count >= sizeof(long)) + retval = put_user(data, (unsigned long *)buf) ?: sizeof(long); + else + retval = put_user(data, (unsigned int *)buf) ?: sizeof(int); + /* RED-PEN: on big endian this still has problems if the + user passes a too big buffer, but expects int */ + out: current->state = TASK_RUNNING; remove_wait_queue(&rtc_wait, &wait); _