From: Arun Sharma <arun.sharma@intel.com>
To: Arnd Bergmann <arnd@arndb.de>
Cc: Andrew Morton <akpm@osdl.org>,
"David S. Miller" <davem@redhat.com>,
linux-arch@vger.kernel.org
Subject: Re: sys getdents64 needs compat wrapper ?
Date: Tue, 22 Jun 2004 11:21:13 -0700 [thread overview]
Message-ID: <40D87899.6070209@intel.com> (raw)
In-Reply-To: <200406202350.24106.arnd@arndb.de>
[-- Attachment #1: Type: text/plain, Size: 1041 bytes --]
On 6/20/2004 2:50 PM, Arnd Bergmann wrote:
> I now noticed one more bug:
>
>> + * values at locations that are unknown to be aligned.
>> + */
>> +#define __get_user_unaligned(x, ptr) \
>> +({ \
>> + __typeof__ (*(ptr)) __x = (x); \
>> + __copy_from_user(&__x, (ptr), sizeof(*(ptr))) ? -EFAULT : 0; \
>> +})
>
> The assignment is done in the wrong direction, this needs to become
> something like:
>
> #define __get_user_unaligned(x, ptr) \
> ({ \
> __typeof__ (*(ptr)) __x; \
> __copy_from_user(&__x, (ptr), sizeof(*(ptr))) ? -EFAULT : 0; \
> (x) = __x; \
> })
>
> Hopefully that'll be the last change for this, the rest looks good to
> me.
Hope so! Take 3.
-Arun
[-- Attachment #2: __get_put_user_unaligned.3.patch --]
[-- Type: text/plain, Size: 7893 bytes --]
(1) Fix compat_filldir64() which is broken on big-endian machines.
(2) Introduce new APIs __{get,put}_user_unaligned.
(3) Optimize __{get,put}_user_unaligned for ia64, x86-64, ppc64 and s390.
Signed-off-by: Gordon Jin <gordon.jin@intel.com>
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
diff -purN linux-2.6.7-rc3-getdents/fs/compat.c linux-2.6.7-rc3-getdents-user_unaligned/fs/compat.c
--- linux-2.6.7-rc3-getdents/fs/compat.c 2004-06-18 18:41:36.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/fs/compat.c 2004-06-17 14:51:42.000000000 +0800
@@ -979,19 +979,14 @@ static int compat_filldir64(void * __buf
dirent = buf->previous;
if (dirent) {
- if (__put_user(offset, (u32 __user *)&dirent->d_off))
- goto efault;
- if (__put_user(offset >> 32,
- ((u32 __user *)&dirent->d_off) + 1))
+ if (__put_user_unaligned(offset, &dirent->d_off))
goto efault;
}
dirent = buf->current_dir;
- if ((__put_user(ino, (u32 __user *)&dirent->d_ino))
- || (__put_user(ino >> 32, ((u32 __user *)&dirent->d_ino) + 1)))
+ if (__put_user_unaligned(ino, &dirent->d_ino))
goto efault;
off = 0;
- if ((__put_user(off, (u32 __user *)&dirent->d_off))
- || (__put_user(off >> 32, ((u32 __user *)&dirent->d_off) + 1)))
+ if (__put_user_unaligned(off, &dirent->d_off))
goto efault;
if (__put_user(reclen, &dirent->d_reclen))
goto efault;
@@ -1040,8 +1035,7 @@ asmlinkage long compat_sys_getdents64(un
lastdirent = buf.previous;
if (lastdirent) {
typeof(lastdirent->d_off) d_off = file->f_pos;
- __put_user(d_off, (u32 __user *)&lastdirent->d_off);
- __put_user(d_off >> 32, ((u32 __user *)&lastdirent->d_off) + 1);
+ __put_user_unaligned(d_off, &lastdirent->d_off);
error = count - buf.count;
}
diff -purN linux-2.6.7-rc3-getdents/include/asm-generic/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-generic/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-generic/uaccess.h 1970-01-01 08:00:00.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-generic/uaccess.h 2004-06-22 09:40:05.861305422 +0800
@@ -0,0 +1,26 @@
+#ifndef _ASM_GENERIC_UACCESS_H_
+#define _ASM_GENERIC_UACCESS_H_
+
+/*
+ * This macro should be used instead of __get_user() when accessing
+ * values at locations that are unknown to be aligned.
+ */
+#define __get_user_unaligned(x, ptr) \
+({ \
+ __typeof__ (*(ptr)) __x; \
+ __copy_from_user(&__x, (ptr), sizeof(*(ptr))) ? -EFAULT : 0; \
+ (x) = __x; \
+})
+
+
+/*
+ * This macro should be used instead of __put_user() when accessing
+ * values at locations that are unknown to be aligned.
+ */
+#define __put_user_unaligned(x, ptr) \
+({ \
+ __typeof__ (*(ptr)) __x = (x); \
+ __copy_to_user((ptr), &__x, sizeof(*(ptr))) ? -EFAULT : 0; \
+})
+
+#endif /* _ASM_GENERIC_UACCESS_H */
diff -purN linux-2.6.7-rc3-getdents/include/asm-ia64/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-ia64/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-ia64/uaccess.h 2004-06-18 18:41:09.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-ia64/uaccess.h 2004-06-18 18:24:27.000000000 +0800
@@ -91,6 +91,42 @@ verify_area (int type, const void *addr,
#define __put_user(x, ptr) __put_user_nocheck((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)))
#define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+extern long __put_user_unaligned_unknown (void);
+
+#define __put_user_unaligned(x, ptr) \
+({ \
+ long __ret; \
+ switch (sizeof(*(ptr))) { \
+ case 1: __ret = __put_user((x), (ptr)); break; \
+ case 2: __ret = (__put_user((x), (u8 __user *)(ptr))) \
+ | (__put_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
+ case 4: __ret = (__put_user((x), (u16 __user *)(ptr))) \
+ | (__put_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
+ case 8: __ret = (__put_user((x), (u32 __user *)(ptr))) \
+ | (__put_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
+ default: __ret = __put_user_unaligned_unknown(); \
+ } \
+ __ret; \
+})
+
+extern long __get_user_unaligned_unknown (void);
+
+#define __get_user_unaligned(x, ptr) \
+({ \
+ long __ret; \
+ switch (sizeof(*(ptr))) { \
+ case 1: __ret = __get_user((x), (ptr)); break; \
+ case 2: __ret = (__get_user((x), (u8 __user *)(ptr))) \
+ | (__get_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
+ case 4: __ret = (__get_user((x), (u16 __user *)(ptr))) \
+ | (__get_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
+ case 8: __ret = (__get_user((x), (u32 __user *)(ptr))) \
+ | (__get_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
+ default: __ret = __get_user_unaligned_unknown(); \
+ } \
+ __ret; \
+})
+
#ifdef ASM_SUPPORTED
struct __large_struct { unsigned long buf[100]; };
# define __m(x) (*(struct __large_struct *)(x))
diff -purN linux-2.6.7-rc3-getdents/include/asm-mips/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-mips/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-mips/uaccess.h 2004-06-18 18:41:06.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-mips/uaccess.h 2004-06-17 14:51:42.000000000 +0800
@@ -13,6 +13,7 @@
#include <linux/compiler.h>
#include <linux/errno.h>
#include <linux/thread_info.h>
+#include <asm-generic/uaccess.h>
/*
* The fs value determines whether argument validity checking should be
diff -purN linux-2.6.7-rc3-getdents/include/asm-ppc64/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-ppc64/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-ppc64/uaccess.h 2004-06-18 18:41:04.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-ppc64/uaccess.h 2004-06-18 18:27:57.000000000 +0800
@@ -111,6 +111,9 @@ extern unsigned long search_exception_ta
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
extern long __put_user_bad(void);
#define __put_user_nocheck(x,ptr,size) \
diff -purN linux-2.6.7-rc3-getdents/include/asm-s390/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-s390/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-s390/uaccess.h 2004-06-18 18:41:20.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-s390/uaccess.h 2004-06-18 18:31:37.000000000 +0800
@@ -230,6 +230,9 @@ extern int __put_user_bad(void);
extern int __get_user_bad(void);
+#define __put_user_unaligned __put_user
+#define __get_user_unaligned __get_user
+
extern long __copy_to_user_asm(const void *from, long n, void *to);
/**
diff -purN linux-2.6.7-rc3-getdents/include/asm-sparc64/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-sparc64/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-sparc64/uaccess.h 2004-06-18 18:41:21.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-sparc64/uaccess.h 2004-06-17 14:51:42.000000000 +0800
@@ -14,6 +14,7 @@
#include <asm/asi.h>
#include <asm/system.h>
#include <asm/spitfire.h>
+#include <asm-generic/uaccess.h>
#endif
#ifndef __ASSEMBLY__
diff -purN linux-2.6.7-rc3-getdents/include/asm-x86_64/uaccess.h linux-2.6.7-rc3-getdents-user_unaligned/include/asm-x86_64/uaccess.h
--- linux-2.6.7-rc3-getdents/include/asm-x86_64/uaccess.h 2004-06-18 18:41:04.000000000 +0800
+++ linux-2.6.7-rc3-getdents-user_unaligned/include/asm-x86_64/uaccess.h 2004-06-18 18:32:15.000000000 +0800
@@ -147,6 +147,9 @@ extern void __put_user_bad(void);
#define __put_user(x,ptr) \
__put_user_nocheck((__typeof__(*(ptr)))(x),(ptr),sizeof(*(ptr)))
+#define __get_user_unaligned __get_user
+#define __put_user_unaligned __put_user
+
#define __put_user_nocheck(x,ptr,size) \
({ \
int __pu_err; \
next prev parent reply other threads:[~2004-06-22 18:21 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-05-20 21:06 =?iso-8859-1?Q?Re:_sys_getdents64_needs_compat_wrapper_??= Arnd Bergmann
2004-06-05 0:16 ` =?iso-8859-1?Q?Re:_sys_getdents64_needs_compat_wrapper_??= Arun Sharma
2004-06-05 0:28 ` sys getdents64 needs compat wrapper ? David S. Miller
2004-06-07 21:13 ` Arun Sharma
2004-06-07 21:58 ` David S. Miller
2004-06-11 15:09 ` Arnd Bergmann
2004-06-14 18:15 ` Arun Sharma
2004-06-17 22:28 ` Arun Sharma
2004-06-17 23:36 ` Arnd Bergmann
2004-06-18 0:56 ` Arun Sharma
2004-06-18 17:05 ` Arun Sharma
2004-06-20 21:50 ` Arnd Bergmann
2004-06-22 18:21 ` Arun Sharma [this message]
-- strict thread matches above, loose matches on Subject: below --
2004-06-05 14:52 =?iso-8859-1?Q?Re:_Re:_Re:_sys_getdents64_needs_compat_wrapper_??= Arnd Bergmann
2004-06-05 18:41 ` sys getdents64 needs compat wrapper ? Andrew Morton
2004-06-05 19:31 ` David S. Miller
2004-05-20 18:32 sys_getdents64 " Arun Sharma
2004-05-20 20:58 ` David S. Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=40D87899.6070209@intel.com \
--to=arun.sharma@intel.com \
--cc=akpm@osdl.org \
--cc=arnd@arndb.de \
--cc=davem@redhat.com \
--cc=linux-arch@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.