diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/fs/compat.c b/fs/compat.c index d98c96f4a44d..4d3fbcb2ddb1 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -914,20 +914,24 @@ struct compat_readdir_callback { | |||
914 | }; | 914 | }; |
915 | 915 | ||
916 | static int compat_fillonedir(void *__buf, const char *name, int namlen, | 916 | static int compat_fillonedir(void *__buf, const char *name, int namlen, |
917 | loff_t offset, ino_t ino, unsigned int d_type) | 917 | loff_t offset, u64 ino, unsigned int d_type) |
918 | { | 918 | { |
919 | struct compat_readdir_callback *buf = __buf; | 919 | struct compat_readdir_callback *buf = __buf; |
920 | struct compat_old_linux_dirent __user *dirent; | 920 | struct compat_old_linux_dirent __user *dirent; |
921 | compat_ulong_t d_ino; | ||
921 | 922 | ||
922 | if (buf->result) | 923 | if (buf->result) |
923 | return -EINVAL; | 924 | return -EINVAL; |
925 | d_ino = ino; | ||
926 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
927 | return -EOVERFLOW; | ||
924 | buf->result++; | 928 | buf->result++; |
925 | dirent = buf->dirent; | 929 | dirent = buf->dirent; |
926 | if (!access_ok(VERIFY_WRITE, dirent, | 930 | if (!access_ok(VERIFY_WRITE, dirent, |
927 | (unsigned long)(dirent->d_name + namlen + 1) - | 931 | (unsigned long)(dirent->d_name + namlen + 1) - |
928 | (unsigned long)dirent)) | 932 | (unsigned long)dirent)) |
929 | goto efault; | 933 | goto efault; |
930 | if ( __put_user(ino, &dirent->d_ino) || | 934 | if ( __put_user(d_ino, &dirent->d_ino) || |
931 | __put_user(offset, &dirent->d_offset) || | 935 | __put_user(offset, &dirent->d_offset) || |
932 | __put_user(namlen, &dirent->d_namlen) || | 936 | __put_user(namlen, &dirent->d_namlen) || |
933 | __copy_to_user(dirent->d_name, name, namlen) || | 937 | __copy_to_user(dirent->d_name, name, namlen) || |
@@ -978,22 +982,26 @@ struct compat_getdents_callback { | |||
978 | }; | 982 | }; |
979 | 983 | ||
980 | static int compat_filldir(void *__buf, const char *name, int namlen, | 984 | static int compat_filldir(void *__buf, const char *name, int namlen, |
981 | loff_t offset, ino_t ino, unsigned int d_type) | 985 | loff_t offset, u64 ino, unsigned int d_type) |
982 | { | 986 | { |
983 | struct compat_linux_dirent __user * dirent; | 987 | struct compat_linux_dirent __user * dirent; |
984 | struct compat_getdents_callback *buf = __buf; | 988 | struct compat_getdents_callback *buf = __buf; |
989 | compat_ulong_t d_ino; | ||
985 | int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 990 | int reclen = COMPAT_ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); |
986 | 991 | ||
987 | buf->error = -EINVAL; /* only used if we fail.. */ | 992 | buf->error = -EINVAL; /* only used if we fail.. */ |
988 | if (reclen > buf->count) | 993 | if (reclen > buf->count) |
989 | return -EINVAL; | 994 | return -EINVAL; |
995 | d_ino = ino; | ||
996 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
997 | return -EOVERFLOW; | ||
990 | dirent = buf->previous; | 998 | dirent = buf->previous; |
991 | if (dirent) { | 999 | if (dirent) { |
992 | if (__put_user(offset, &dirent->d_off)) | 1000 | if (__put_user(offset, &dirent->d_off)) |
993 | goto efault; | 1001 | goto efault; |
994 | } | 1002 | } |
995 | dirent = buf->current_dir; | 1003 | dirent = buf->current_dir; |
996 | if (__put_user(ino, &dirent->d_ino)) | 1004 | if (__put_user(d_ino, &dirent->d_ino)) |
997 | goto efault; | 1005 | goto efault; |
998 | if (__put_user(reclen, &dirent->d_reclen)) | 1006 | if (__put_user(reclen, &dirent->d_reclen)) |
999 | goto efault; | 1007 | goto efault; |
@@ -1064,7 +1072,7 @@ struct compat_getdents_callback64 { | |||
1064 | }; | 1072 | }; |
1065 | 1073 | ||
1066 | static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, | 1074 | static int compat_filldir64(void * __buf, const char * name, int namlen, loff_t offset, |
1067 | ino_t ino, unsigned int d_type) | 1075 | u64 ino, unsigned int d_type) |
1068 | { | 1076 | { |
1069 | struct linux_dirent64 __user *dirent; | 1077 | struct linux_dirent64 __user *dirent; |
1070 | struct compat_getdents_callback64 *buf = __buf; | 1078 | struct compat_getdents_callback64 *buf = __buf; |