From: Andi Kleen <ak@suse.de>

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);

_