diff options
-rw-r--r-- | arch/alpha/kernel/osf_sys.c | 8 | ||||
-rw-r--r-- | arch/ia64/ia32/sys_ia32.c | 23 | ||||
-rw-r--r-- | arch/mips/kernel/linux32.c | 2 | ||||
-rw-r--r-- | arch/mips/kernel/sysirix.c | 10 | ||||
-rw-r--r-- | arch/parisc/hpux/fs.c | 6 | ||||
-rw-r--r-- | arch/parisc/kernel/sys_parisc32.c | 19 | ||||
-rw-r--r-- | arch/powerpc/kernel/sys_ppc32.c | 15 | ||||
-rw-r--r-- | arch/s390/kernel/compat_linux.c | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sunos.c | 16 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sparc32.c | 5 | ||||
-rw-r--r-- | arch/sparc64/kernel/sys_sunos32.c | 12 | ||||
-rw-r--r-- | arch/sparc64/solaris/fs.c | 7 | ||||
-rw-r--r-- | arch/x86_64/ia32/sys_ia32.c | 7 | ||||
-rw-r--r-- | fs/afs/dir.c | 4 | ||||
-rw-r--r-- | fs/compat.c | 18 | ||||
-rw-r--r-- | fs/exportfs/expfs.c | 2 | ||||
-rw-r--r-- | fs/fat/dir.c | 2 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 2 | ||||
-rw-r--r-- | fs/readdir.c | 18 | ||||
-rw-r--r-- | fs/reiserfs/xattr.c | 6 | ||||
-rw-r--r-- | fs/stat.c | 6 | ||||
-rw-r--r-- | include/linux/fs.h | 2 | ||||
-rw-r--r-- | include/linux/stat.h | 2 |
23 files changed, 152 insertions, 45 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 8a31fc1bfb15..ad6173651995 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -111,22 +111,26 @@ struct osf_dirent_callback { | |||
111 | 111 | ||
112 | static int | 112 | static int |
113 | osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, | 113 | osf_filldir(void *__buf, const char *name, int namlen, loff_t offset, |
114 | ino_t ino, unsigned int d_type) | 114 | u64 ino, unsigned int d_type) |
115 | { | 115 | { |
116 | struct osf_dirent __user *dirent; | 116 | struct osf_dirent __user *dirent; |
117 | struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; | 117 | struct osf_dirent_callback *buf = (struct osf_dirent_callback *) __buf; |
118 | unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); | 118 | unsigned int reclen = ROUND_UP(NAME_OFFSET + namlen + 1); |
119 | unsigned int d_ino; | ||
119 | 120 | ||
120 | buf->error = -EINVAL; /* only used if we fail */ | 121 | buf->error = -EINVAL; /* only used if we fail */ |
121 | if (reclen > buf->count) | 122 | if (reclen > buf->count) |
122 | return -EINVAL; | 123 | return -EINVAL; |
124 | d_ino = ino; | ||
125 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
126 | return -EOVERFLOW; | ||
123 | if (buf->basep) { | 127 | if (buf->basep) { |
124 | if (put_user(offset, buf->basep)) | 128 | if (put_user(offset, buf->basep)) |
125 | return -EFAULT; | 129 | return -EFAULT; |
126 | buf->basep = NULL; | 130 | buf->basep = NULL; |
127 | } | 131 | } |
128 | dirent = buf->dirent; | 132 | dirent = buf->dirent; |
129 | put_user(ino, &dirent->d_ino); | 133 | put_user(d_ino, &dirent->d_ino); |
130 | put_user(namlen, &dirent->d_namlen); | 134 | put_user(namlen, &dirent->d_namlen); |
131 | put_user(reclen, &dirent->d_reclen); | 135 | put_user(reclen, &dirent->d_reclen); |
132 | if (copy_to_user(dirent->d_name, name, namlen) || | 136 | if (copy_to_user(dirent->d_name, name, namlen) || |
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c index bddbd22706ed..9d6a3f210148 100644 --- a/arch/ia64/ia32/sys_ia32.c +++ b/arch/ia64/ia32/sys_ia32.c | |||
@@ -125,6 +125,7 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use | |||
125 | 125 | ||
126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | 126 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) |
127 | { | 127 | { |
128 | compat_ino_t ino; | ||
128 | int err; | 129 | int err; |
129 | 130 | ||
130 | if ((u64) stat->size > MAX_NON_LFS || | 131 | if ((u64) stat->size > MAX_NON_LFS || |
@@ -132,11 +133,15 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf) | |||
132 | !old_valid_dev(stat->rdev)) | 133 | !old_valid_dev(stat->rdev)) |
133 | return -EOVERFLOW; | 134 | return -EOVERFLOW; |
134 | 135 | ||
136 | ino = stat->ino; | ||
137 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
138 | return -EOVERFLOW; | ||
139 | |||
135 | if (clear_user(ubuf, sizeof(*ubuf))) | 140 | if (clear_user(ubuf, sizeof(*ubuf))) |
136 | return -EFAULT; | 141 | return -EFAULT; |
137 | 142 | ||
138 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); | 143 | err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev); |
139 | err |= __put_user(stat->ino, &ubuf->st_ino); | 144 | err |= __put_user(ino, &ubuf->st_ino); |
140 | err |= __put_user(stat->mode, &ubuf->st_mode); | 145 | err |= __put_user(stat->mode, &ubuf->st_mode); |
141 | err |= __put_user(stat->nlink, &ubuf->st_nlink); | 146 | err |= __put_user(stat->nlink, &ubuf->st_nlink); |
142 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); | 147 | err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid); |
@@ -1222,16 +1227,20 @@ struct readdir32_callback { | |||
1222 | }; | 1227 | }; |
1223 | 1228 | ||
1224 | static int | 1229 | static int |
1225 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | 1230 | filldir32 (void *__buf, const char *name, int namlen, loff_t offset, u64 ino, |
1226 | unsigned int d_type) | 1231 | unsigned int d_type) |
1227 | { | 1232 | { |
1228 | struct compat_dirent __user * dirent; | 1233 | struct compat_dirent __user * dirent; |
1229 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 1234 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
1230 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); | 1235 | int reclen = ROUND_UP(offsetof(struct compat_dirent, d_name) + namlen + 1, 4); |
1236 | u32 d_ino; | ||
1231 | 1237 | ||
1232 | buf->error = -EINVAL; /* only used if we fail.. */ | 1238 | buf->error = -EINVAL; /* only used if we fail.. */ |
1233 | if (reclen > buf->count) | 1239 | if (reclen > buf->count) |
1234 | return -EINVAL; | 1240 | return -EINVAL; |
1241 | d_ino = ino; | ||
1242 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1243 | return -EOVERFLOW; | ||
1235 | buf->error = -EFAULT; /* only used if we fail.. */ | 1244 | buf->error = -EFAULT; /* only used if we fail.. */ |
1236 | dirent = buf->previous; | 1245 | dirent = buf->previous; |
1237 | if (dirent) | 1246 | if (dirent) |
@@ -1239,7 +1248,7 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
1239 | return -EFAULT; | 1248 | return -EFAULT; |
1240 | dirent = buf->current_dir; | 1249 | dirent = buf->current_dir; |
1241 | buf->previous = dirent; | 1250 | buf->previous = dirent; |
1242 | if (put_user(ino, &dirent->d_ino) | 1251 | if (put_user(d_ino, &dirent->d_ino) |
1243 | || put_user(reclen, &dirent->d_reclen) | 1252 | || put_user(reclen, &dirent->d_reclen) |
1244 | || copy_to_user(dirent->d_name, name, namlen) | 1253 | || copy_to_user(dirent->d_name, name, namlen) |
1245 | || put_user(0, dirent->d_name + namlen)) | 1254 | || put_user(0, dirent->d_name + namlen)) |
@@ -1287,17 +1296,21 @@ out: | |||
1287 | } | 1296 | } |
1288 | 1297 | ||
1289 | static int | 1298 | static int |
1290 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, | 1299 | fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, u64 ino, |
1291 | unsigned int d_type) | 1300 | unsigned int d_type) |
1292 | { | 1301 | { |
1293 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 1302 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
1294 | struct old_linux32_dirent __user * dirent; | 1303 | struct old_linux32_dirent __user * dirent; |
1304 | u32 d_ino; | ||
1295 | 1305 | ||
1296 | if (buf->count) | 1306 | if (buf->count) |
1297 | return -EINVAL; | 1307 | return -EINVAL; |
1308 | d_ino = ino; | ||
1309 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1310 | return -EOVERFLOW; | ||
1298 | buf->count++; | 1311 | buf->count++; |
1299 | dirent = buf->dirent; | 1312 | dirent = buf->dirent; |
1300 | if (put_user(ino, &dirent->d_ino) | 1313 | if (put_user(d_ino, &dirent->d_ino) |
1301 | || put_user(offset, &dirent->d_offset) | 1314 | || put_user(offset, &dirent->d_offset) |
1302 | || put_user(namlen, &dirent->d_namlen) | 1315 | || put_user(namlen, &dirent->d_namlen) |
1303 | || copy_to_user(dirent->d_name, name, namlen) | 1316 | || copy_to_user(dirent->d_name, name, namlen) |
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 52cada45b353..53f4171fc188 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -77,6 +77,8 @@ int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | |||
77 | memset(&tmp, 0, sizeof(tmp)); | 77 | memset(&tmp, 0, sizeof(tmp)); |
78 | tmp.st_dev = new_encode_dev(stat->dev); | 78 | tmp.st_dev = new_encode_dev(stat->dev); |
79 | tmp.st_ino = stat->ino; | 79 | tmp.st_ino = stat->ino; |
80 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
81 | return -EOVERFLOW; | ||
80 | tmp.st_mode = stat->mode; | 82 | tmp.st_mode = stat->mode; |
81 | tmp.st_nlink = stat->nlink; | 83 | tmp.st_nlink = stat->nlink; |
82 | SET_UID(tmp.st_uid, stat->uid); | 84 | SET_UID(tmp.st_uid, stat->uid); |
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 11bb97174972..93c74fefff76 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c | |||
@@ -1739,12 +1739,13 @@ struct irix_dirent32_callback { | |||
1739 | #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) | 1739 | #define ROUND_UP32(x) (((x)+sizeof(u32)-1) & ~(sizeof(u32)-1)) |
1740 | 1740 | ||
1741 | static int irix_filldir32(void *__buf, const char *name, | 1741 | static int irix_filldir32(void *__buf, const char *name, |
1742 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 1742 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
1743 | { | 1743 | { |
1744 | struct irix_dirent32 __user *dirent; | 1744 | struct irix_dirent32 __user *dirent; |
1745 | struct irix_dirent32_callback *buf = __buf; | 1745 | struct irix_dirent32_callback *buf = __buf; |
1746 | unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); | 1746 | unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1); |
1747 | int err = 0; | 1747 | int err = 0; |
1748 | u32 d_ino; | ||
1748 | 1749 | ||
1749 | #ifdef DEBUG_GETDENTS | 1750 | #ifdef DEBUG_GETDENTS |
1750 | printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", | 1751 | printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]", |
@@ -1753,12 +1754,15 @@ static int irix_filldir32(void *__buf, const char *name, | |||
1753 | buf->error = -EINVAL; /* only used if we fail.. */ | 1754 | buf->error = -EINVAL; /* only used if we fail.. */ |
1754 | if (reclen > buf->count) | 1755 | if (reclen > buf->count) |
1755 | return -EINVAL; | 1756 | return -EINVAL; |
1757 | d_ino = ino; | ||
1758 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
1759 | return -EOVERFLOW; | ||
1756 | dirent = buf->previous; | 1760 | dirent = buf->previous; |
1757 | if (dirent) | 1761 | if (dirent) |
1758 | err = __put_user(offset, &dirent->d_off); | 1762 | err = __put_user(offset, &dirent->d_off); |
1759 | dirent = buf->current_dir; | 1763 | dirent = buf->current_dir; |
1760 | err |= __put_user(dirent, &buf->previous); | 1764 | err |= __put_user(dirent, &buf->previous); |
1761 | err |= __put_user(ino, &dirent->d_ino); | 1765 | err |= __put_user(d_ino, &dirent->d_ino); |
1762 | err |= __put_user(reclen, &dirent->d_reclen); | 1766 | err |= __put_user(reclen, &dirent->d_reclen); |
1763 | err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; | 1767 | err |= copy_to_user((char __user *)dirent->d_name, name, namlen) ? -EFAULT : 0; |
1764 | err |= __put_user(0, &dirent->d_name[namlen]); | 1768 | err |= __put_user(0, &dirent->d_name[namlen]); |
@@ -1837,7 +1841,7 @@ struct irix_dirent64_callback { | |||
1837 | #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) | 1841 | #define ROUND_UP64(x) (((x)+sizeof(u64)-1) & ~(sizeof(u64)-1)) |
1838 | 1842 | ||
1839 | static int irix_filldir64(void *__buf, const char *name, | 1843 | static int irix_filldir64(void *__buf, const char *name, |
1840 | int namlen, loff_t offset, ino_t ino, unsigned int d_type) | 1844 | int namlen, loff_t offset, u64 ino, unsigned int d_type) |
1841 | { | 1845 | { |
1842 | struct irix_dirent64 __user *dirent; | 1846 | struct irix_dirent64 __user *dirent; |
1843 | struct irix_dirent64_callback * buf = __buf; | 1847 | struct irix_dirent64_callback * buf = __buf; |
diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index d7c80edf4489..6e79dbf3f6bd 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c | |||
@@ -77,17 +77,21 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | |||
77 | { | 77 | { |
78 | struct hpux_dirent * dirent; | 78 | struct hpux_dirent * dirent; |
79 | struct getdents_callback * buf = (struct getdents_callback *) __buf; | 79 | struct getdents_callback * buf = (struct getdents_callback *) __buf; |
80 | ino_t d_ino; | ||
80 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 81 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
81 | 82 | ||
82 | buf->error = -EINVAL; /* only used if we fail.. */ | 83 | buf->error = -EINVAL; /* only used if we fail.. */ |
83 | if (reclen > buf->count) | 84 | if (reclen > buf->count) |
84 | return -EINVAL; | 85 | return -EINVAL; |
86 | d_ino = ino; | ||
87 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
88 | return -EOVERFLOW; | ||
85 | dirent = buf->previous; | 89 | dirent = buf->previous; |
86 | if (dirent) | 90 | if (dirent) |
87 | put_user(offset, &dirent->d_off); | 91 | put_user(offset, &dirent->d_off); |
88 | dirent = buf->current_dir; | 92 | dirent = buf->current_dir; |
89 | buf->previous = dirent; | 93 | buf->previous = dirent; |
90 | put_user(ino, &dirent->d_ino); | 94 | put_user(d_ino, &dirent->d_ino); |
91 | put_user(reclen, &dirent->d_reclen); | 95 | put_user(reclen, &dirent->d_reclen); |
92 | put_user(namlen, &dirent->d_namlen); | 96 | put_user(namlen, &dirent->d_namlen); |
93 | copy_to_user(dirent->d_name, name, namlen); | 97 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index b74869803081..e3b30bc36453 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c | |||
@@ -237,14 +237,19 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user | |||
237 | 237 | ||
238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 238 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
239 | { | 239 | { |
240 | compat_ino_t ino; | ||
240 | int err; | 241 | int err; |
241 | 242 | ||
242 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | 243 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || |
243 | !new_valid_dev(stat->rdev)) | 244 | !new_valid_dev(stat->rdev)) |
244 | return -EOVERFLOW; | 245 | return -EOVERFLOW; |
245 | 246 | ||
247 | ino = stat->ino; | ||
248 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
249 | return -EOVERFLOW; | ||
250 | |||
246 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | 251 | err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); |
247 | err |= put_user(stat->ino, &statbuf->st_ino); | 252 | err |= put_user(ino, &statbuf->st_ino); |
248 | err |= put_user(stat->mode, &statbuf->st_mode); | 253 | err |= put_user(stat->mode, &statbuf->st_mode); |
249 | err |= put_user(stat->nlink, &statbuf->st_nlink); | 254 | err |= put_user(stat->nlink, &statbuf->st_nlink); |
250 | err |= put_user(0, &statbuf->st_reserved1); | 255 | err |= put_user(0, &statbuf->st_reserved1); |
@@ -312,16 +317,20 @@ filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, | |||
312 | struct linux32_dirent __user * dirent; | 317 | struct linux32_dirent __user * dirent; |
313 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; | 318 | struct getdents32_callback * buf = (struct getdents32_callback *) __buf; |
314 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); | 319 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); |
320 | u32 d_ino; | ||
315 | 321 | ||
316 | buf->error = -EINVAL; /* only used if we fail.. */ | 322 | buf->error = -EINVAL; /* only used if we fail.. */ |
317 | if (reclen > buf->count) | 323 | if (reclen > buf->count) |
318 | return -EINVAL; | 324 | return -EINVAL; |
325 | d_ino = ino; | ||
326 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
327 | return -EOVERFLOW; | ||
319 | dirent = buf->previous; | 328 | dirent = buf->previous; |
320 | if (dirent) | 329 | if (dirent) |
321 | put_user(offset, &dirent->d_off); | 330 | put_user(offset, &dirent->d_off); |
322 | dirent = buf->current_dir; | 331 | dirent = buf->current_dir; |
323 | buf->previous = dirent; | 332 | buf->previous = dirent; |
324 | put_user(ino, &dirent->d_ino); | 333 | put_user(d_ino, &dirent->d_ino); |
325 | put_user(reclen, &dirent->d_reclen); | 334 | put_user(reclen, &dirent->d_reclen); |
326 | copy_to_user(dirent->d_name, name, namlen); | 335 | copy_to_user(dirent->d_name, name, namlen); |
327 | put_user(0, dirent->d_name + namlen); | 336 | put_user(0, dirent->d_name + namlen); |
@@ -371,12 +380,16 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t | |||
371 | { | 380 | { |
372 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; | 381 | struct readdir32_callback * buf = (struct readdir32_callback *) __buf; |
373 | struct old_linux32_dirent __user * dirent; | 382 | struct old_linux32_dirent __user * dirent; |
383 | u32 d_ino; | ||
374 | 384 | ||
375 | if (buf->count) | 385 | if (buf->count) |
376 | return -EINVAL; | 386 | return -EINVAL; |
387 | d_ino = ino; | ||
388 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
389 | return -EOVERFLOW; | ||
377 | buf->count++; | 390 | buf->count++; |
378 | dirent = buf->dirent; | 391 | dirent = buf->dirent; |
379 | put_user(ino, &dirent->d_ino); | 392 | put_user(d_ino, &dirent->d_ino); |
380 | put_user(offset, &dirent->d_offset); | 393 | put_user(offset, &dirent->d_offset); |
381 | put_user(namlen, &dirent->d_namlen); | 394 | put_user(namlen, &dirent->d_namlen); |
382 | copy_to_user(dirent->d_name, name, namlen); | 395 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c index 5e391fc25340..d15c33e95959 100644 --- a/arch/powerpc/kernel/sys_ppc32.c +++ b/arch/powerpc/kernel/sys_ppc32.c | |||
@@ -69,16 +69,20 @@ struct readdir_callback32 { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int fillonedir(void * __buf, const char * name, int namlen, | 71 | static int fillonedir(void * __buf, const char * name, int namlen, |
72 | off_t offset, ino_t ino, unsigned int d_type) | 72 | off_t offset, u64 ino, unsigned int d_type) |
73 | { | 73 | { |
74 | struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; | 74 | struct readdir_callback32 * buf = (struct readdir_callback32 *) __buf; |
75 | struct old_linux_dirent32 __user * dirent; | 75 | struct old_linux_dirent32 __user * dirent; |
76 | ino_t d_ino; | ||
76 | 77 | ||
77 | if (buf->count) | 78 | if (buf->count) |
78 | return -EINVAL; | 79 | return -EINVAL; |
80 | d_ino = ino; | ||
81 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
82 | return -EOVERFLOW; | ||
79 | buf->count++; | 83 | buf->count++; |
80 | dirent = buf->dirent; | 84 | dirent = buf->dirent; |
81 | put_user(ino, &dirent->d_ino); | 85 | put_user(d_ino, &dirent->d_ino); |
82 | put_user(offset, &dirent->d_offset); | 86 | put_user(offset, &dirent->d_offset); |
83 | put_user(namlen, &dirent->d_namlen); | 87 | put_user(namlen, &dirent->d_namlen); |
84 | copy_to_user(dirent->d_name, name, namlen); | 88 | copy_to_user(dirent->d_name, name, namlen); |
@@ -120,15 +124,20 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp, | |||
120 | 124 | ||
121 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 125 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
122 | { | 126 | { |
127 | compat_ino_t ino; | ||
123 | long err; | 128 | long err; |
124 | 129 | ||
125 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || | 130 | if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || |
126 | !new_valid_dev(stat->rdev)) | 131 | !new_valid_dev(stat->rdev)) |
127 | return -EOVERFLOW; | 132 | return -EOVERFLOW; |
128 | 133 | ||
134 | ino = stat->ino; | ||
135 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
136 | return -EOVERFLOW; | ||
137 | |||
129 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; | 138 | err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT; |
130 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); | 139 | err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev); |
131 | err |= __put_user(stat->ino, &statbuf->st_ino); | 140 | err |= __put_user(ino, &statbuf->st_ino); |
132 | err |= __put_user(stat->mode, &statbuf->st_mode); | 141 | err |= __put_user(stat->mode, &statbuf->st_mode); |
133 | err |= __put_user(stat->nlink, &statbuf->st_nlink); | 142 | err |= __put_user(stat->nlink, &statbuf->st_nlink); |
134 | err |= __put_user(stat->uid, &statbuf->st_uid); | 143 | err |= __put_user(stat->uid, &statbuf->st_uid); |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index c46e3d48e410..e15e1489aef5 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -357,11 +357,16 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned | |||
357 | 357 | ||
358 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 358 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
359 | { | 359 | { |
360 | compat_ino_t ino; | ||
360 | int err; | 361 | int err; |
361 | 362 | ||
362 | if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) | 363 | if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev)) |
363 | return -EOVERFLOW; | 364 | return -EOVERFLOW; |
364 | 365 | ||
366 | ino = stat->ino; | ||
367 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
368 | return -EOVERFLOW; | ||
369 | |||
365 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); | 370 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); |
366 | err |= put_user(stat->ino, &statbuf->st_ino); | 371 | err |= put_user(stat->ino, &statbuf->st_ino); |
367 | err |= put_user(stat->mode, &statbuf->st_mode); | 372 | err |= put_user(stat->mode, &statbuf->st_mode); |
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c index 9d2cd97d1c3a..6f3ac548ee66 100644 --- a/arch/sparc/kernel/sys_sunos.c +++ b/arch/sparc/kernel/sys_sunos.c | |||
@@ -325,21 +325,25 @@ struct sunos_dirent_callback { | |||
325 | #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) | 325 | #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) |
326 | 326 | ||
327 | static int sunos_filldir(void * __buf, const char * name, int namlen, | 327 | static int sunos_filldir(void * __buf, const char * name, int namlen, |
328 | loff_t offset, ino_t ino, unsigned int d_type) | 328 | loff_t offset, u64 ino, unsigned int d_type) |
329 | { | 329 | { |
330 | struct sunos_dirent __user *dirent; | 330 | struct sunos_dirent __user *dirent; |
331 | struct sunos_dirent_callback * buf = __buf; | 331 | struct sunos_dirent_callback * buf = __buf; |
332 | unsigned long d_ino; | ||
332 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 333 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
333 | 334 | ||
334 | buf->error = -EINVAL; /* only used if we fail.. */ | 335 | buf->error = -EINVAL; /* only used if we fail.. */ |
335 | if (reclen > buf->count) | 336 | if (reclen > buf->count) |
336 | return -EINVAL; | 337 | return -EINVAL; |
338 | d_ino = ino; | ||
339 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
340 | return -EOVERFLOW; | ||
337 | dirent = buf->previous; | 341 | dirent = buf->previous; |
338 | if (dirent) | 342 | if (dirent) |
339 | put_user(offset, &dirent->d_off); | 343 | put_user(offset, &dirent->d_off); |
340 | dirent = buf->curr; | 344 | dirent = buf->curr; |
341 | buf->previous = dirent; | 345 | buf->previous = dirent; |
342 | put_user(ino, &dirent->d_ino); | 346 | put_user(d_ino, &dirent->d_ino); |
343 | put_user(namlen, &dirent->d_namlen); | 347 | put_user(namlen, &dirent->d_namlen); |
344 | put_user(reclen, &dirent->d_reclen); | 348 | put_user(reclen, &dirent->d_reclen); |
345 | copy_to_user(dirent->d_name, name, namlen); | 349 | copy_to_user(dirent->d_name, name, namlen); |
@@ -406,19 +410,23 @@ struct sunos_direntry_callback { | |||
406 | }; | 410 | }; |
407 | 411 | ||
408 | static int sunos_filldirentry(void * __buf, const char * name, int namlen, | 412 | static int sunos_filldirentry(void * __buf, const char * name, int namlen, |
409 | loff_t offset, ino_t ino, unsigned int d_type) | 413 | loff_t offset, u64 ino, unsigned int d_type) |
410 | { | 414 | { |
411 | struct sunos_direntry __user *dirent; | 415 | struct sunos_direntry __user *dirent; |
412 | struct sunos_direntry_callback *buf = __buf; | 416 | struct sunos_direntry_callback *buf = __buf; |
417 | unsigned long d_ino; | ||
413 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 418 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
414 | 419 | ||
415 | buf->error = -EINVAL; /* only used if we fail.. */ | 420 | buf->error = -EINVAL; /* only used if we fail.. */ |
416 | if (reclen > buf->count) | 421 | if (reclen > buf->count) |
417 | return -EINVAL; | 422 | return -EINVAL; |
423 | d_ino = ino; | ||
424 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
425 | return -EOVERFLOW; | ||
418 | dirent = buf->previous; | 426 | dirent = buf->previous; |
419 | dirent = buf->curr; | 427 | dirent = buf->curr; |
420 | buf->previous = dirent; | 428 | buf->previous = dirent; |
421 | put_user(ino, &dirent->d_ino); | 429 | put_user(d_ino, &dirent->d_ino); |
422 | put_user(namlen, &dirent->d_namlen); | 430 | put_user(namlen, &dirent->d_namlen); |
423 | put_user(reclen, &dirent->d_reclen); | 431 | put_user(reclen, &dirent->d_reclen); |
424 | copy_to_user(dirent->d_name, name, namlen); | 432 | copy_to_user(dirent->d_name, name, namlen); |
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c index 69444f266e2d..dbc6d1a3be1f 100644 --- a/arch/sparc64/kernel/sys_sparc32.c +++ b/arch/sparc64/kernel/sys_sparc32.c | |||
@@ -337,12 +337,17 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned | |||
337 | 337 | ||
338 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) | 338 | int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) |
339 | { | 339 | { |
340 | compat_ino_t ino; | ||
340 | int err; | 341 | int err; |
341 | 342 | ||
342 | if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || | 343 | if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) || |
343 | !old_valid_dev(stat->rdev)) | 344 | !old_valid_dev(stat->rdev)) |
344 | return -EOVERFLOW; | 345 | return -EOVERFLOW; |
345 | 346 | ||
347 | ino = stat->ino; | ||
348 | if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) | ||
349 | return -EOVERFLOW; | ||
350 | |||
346 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); | 351 | err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev); |
347 | err |= put_user(stat->ino, &statbuf->st_ino); | 352 | err |= put_user(stat->ino, &statbuf->st_ino); |
348 | err |= put_user(stat->mode, &statbuf->st_mode); | 353 | err |= put_user(stat->mode, &statbuf->st_mode); |
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 953296b73f3f..e414c8ef0225 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c | |||
@@ -280,16 +280,20 @@ static int sunos_filldir(void * __buf, const char * name, int namlen, | |||
280 | struct sunos_dirent __user *dirent; | 280 | struct sunos_dirent __user *dirent; |
281 | struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; | 281 | struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; |
282 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 282 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
283 | u32 d_ino; | ||
283 | 284 | ||
284 | buf->error = -EINVAL; /* only used if we fail.. */ | 285 | buf->error = -EINVAL; /* only used if we fail.. */ |
285 | if (reclen > buf->count) | 286 | if (reclen > buf->count) |
286 | return -EINVAL; | 287 | return -EINVAL; |
288 | d_ino = ino; | ||
289 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
290 | return -EOVERFLOW; | ||
287 | dirent = buf->previous; | 291 | dirent = buf->previous; |
288 | if (dirent) | 292 | if (dirent) |
289 | put_user(offset, &dirent->d_off); | 293 | put_user(offset, &dirent->d_off); |
290 | dirent = buf->curr; | 294 | dirent = buf->curr; |
291 | buf->previous = dirent; | 295 | buf->previous = dirent; |
292 | put_user(ino, &dirent->d_ino); | 296 | put_user(d_ino, &dirent->d_ino); |
293 | put_user(namlen, &dirent->d_namlen); | 297 | put_user(namlen, &dirent->d_namlen); |
294 | put_user(reclen, &dirent->d_reclen); | 298 | put_user(reclen, &dirent->d_reclen); |
295 | if (copy_to_user(dirent->d_name, name, namlen)) | 299 | if (copy_to_user(dirent->d_name, name, namlen)) |
@@ -363,14 +367,18 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen, | |||
363 | struct sunos_direntry_callback * buf = | 367 | struct sunos_direntry_callback * buf = |
364 | (struct sunos_direntry_callback *) __buf; | 368 | (struct sunos_direntry_callback *) __buf; |
365 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); | 369 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); |
370 | u32 d_ino; | ||
366 | 371 | ||
367 | buf->error = -EINVAL; /* only used if we fail.. */ | 372 | buf->error = -EINVAL; /* only used if we fail.. */ |
368 | if (reclen > buf->count) | 373 | if (reclen > buf->count) |
369 | return -EINVAL; | 374 | return -EINVAL; |
375 | d_ino = ino; | ||
376 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
377 | return -EOVERFLOW; | ||
370 | dirent = buf->previous; | 378 | dirent = buf->previous; |
371 | dirent = buf->curr; | 379 | dirent = buf->curr; |
372 | buf->previous = dirent; | 380 | buf->previous = dirent; |
373 | put_user(ino, &dirent->d_ino); | 381 | put_user(d_ino, &dirent->d_ino); |
374 | put_user(namlen, &dirent->d_namlen); | 382 | put_user(namlen, &dirent->d_namlen); |
375 | put_user(reclen, &dirent->d_reclen); | 383 | put_user(reclen, &dirent->d_reclen); |
376 | if (copy_to_user(dirent->d_name, name, namlen)) | 384 | if (copy_to_user(dirent->d_name, name, namlen)) |
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 0f0eb6aa1c40..12a940cc791f 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c | |||
@@ -82,12 +82,17 @@ struct sol_stat64 { | |||
82 | 82 | ||
83 | static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) | 83 | static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf) |
84 | { | 84 | { |
85 | u32 ino; | ||
86 | |||
85 | if (kbuf->size > MAX_NON_LFS || | 87 | if (kbuf->size > MAX_NON_LFS || |
86 | !sysv_valid_dev(kbuf->dev) || | 88 | !sysv_valid_dev(kbuf->dev) || |
87 | !sysv_valid_dev(kbuf->rdev)) | 89 | !sysv_valid_dev(kbuf->rdev)) |
88 | return -EOVERFLOW; | 90 | return -EOVERFLOW; |
91 | ino = kbuf->ino; | ||
92 | if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) | ||
93 | return -EOVERFLOW; | ||
89 | if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || | 94 | if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) || |
90 | __put_user (kbuf->ino, &ubuf->st_ino) || | 95 | __put_user (ino, &ubuf->st_ino) || |
91 | __put_user (kbuf->mode, &ubuf->st_mode) || | 96 | __put_user (kbuf->mode, &ubuf->st_mode) || |
92 | __put_user (kbuf->nlink, &ubuf->st_nlink) || | 97 | __put_user (kbuf->nlink, &ubuf->st_nlink) || |
93 | __put_user (kbuf->uid, &ubuf->st_uid) || | 98 | __put_user (kbuf->uid, &ubuf->st_uid) || |
diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index 26a01717cc1a..c9bac3af29d6 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c | |||
@@ -76,6 +76,8 @@ | |||
76 | 76 | ||
77 | int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) | 77 | int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) |
78 | { | 78 | { |
79 | compat_ino_t ino; | ||
80 | |||
79 | typeof(ubuf->st_uid) uid = 0; | 81 | typeof(ubuf->st_uid) uid = 0; |
80 | typeof(ubuf->st_gid) gid = 0; | 82 | typeof(ubuf->st_gid) gid = 0; |
81 | SET_UID(uid, kbuf->uid); | 83 | SET_UID(uid, kbuf->uid); |
@@ -84,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) | |||
84 | return -EOVERFLOW; | 86 | return -EOVERFLOW; |
85 | if (kbuf->size >= 0x7fffffff) | 87 | if (kbuf->size >= 0x7fffffff) |
86 | return -EOVERFLOW; | 88 | return -EOVERFLOW; |
89 | ino = kbuf->ino; | ||
90 | if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) | ||
91 | return -EOVERFLOW; | ||
87 | if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || | 92 | if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || |
88 | __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || | 93 | __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || |
89 | __put_user (kbuf->ino, &ubuf->st_ino) || | 94 | __put_user (ino, &ubuf->st_ino) || |
90 | __put_user (kbuf->mode, &ubuf->st_mode) || | 95 | __put_user (kbuf->mode, &ubuf->st_mode) || |
91 | __put_user (kbuf->nlink, &ubuf->st_nlink) || | 96 | __put_user (kbuf->nlink, &ubuf->st_nlink) || |
92 | __put_user (uid, &ubuf->st_uid) || | 97 | __put_user (uid, &ubuf->st_uid) || |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 2fc99877cb0d..cf8a2cb28505 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
@@ -30,7 +30,7 @@ static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir); | |||
30 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); | 30 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); |
31 | static int afs_d_delete(struct dentry *dentry); | 31 | static int afs_d_delete(struct dentry *dentry); |
32 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, | 32 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, |
33 | loff_t fpos, ino_t ino, unsigned dtype); | 33 | loff_t fpos, u64 ino, unsigned dtype); |
34 | 34 | ||
35 | const struct file_operations afs_dir_file_operations = { | 35 | const struct file_operations afs_dir_file_operations = { |
36 | .open = afs_dir_open, | 36 | .open = afs_dir_open, |
@@ -409,7 +409,7 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir) | |||
409 | * uniquifier through dtype | 409 | * uniquifier through dtype |
410 | */ | 410 | */ |
411 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, | 411 | static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, |
412 | loff_t fpos, ino_t ino, unsigned dtype) | 412 | loff_t fpos, u64 ino, unsigned dtype) |
413 | { | 413 | { |
414 | struct afs_dir_lookup_cookie *cookie = _cookie; | 414 | struct afs_dir_lookup_cookie *cookie = _cookie; |
415 | 415 | ||
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; |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 4c39009350f3..93e77c3d2490 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -315,7 +315,7 @@ struct getdents_callback { | |||
315 | * the name matching the specified inode number. | 315 | * the name matching the specified inode number. |
316 | */ | 316 | */ |
317 | static int filldir_one(void * __buf, const char * name, int len, | 317 | static int filldir_one(void * __buf, const char * name, int len, |
318 | loff_t pos, ino_t ino, unsigned int d_type) | 318 | loff_t pos, u64 ino, unsigned int d_type) |
319 | { | 319 | { |
320 | struct getdents_callback *buf = __buf; | 320 | struct getdents_callback *buf = __buf; |
321 | int result = 0; | 321 | int result = 0; |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 3e50a4166283..69c439f44387 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
@@ -648,7 +648,7 @@ static int fat_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
648 | } | 648 | } |
649 | 649 | ||
650 | static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, | 650 | static int fat_ioctl_filldir(void *__buf, const char *name, int name_len, |
651 | loff_t offset, ino_t ino, unsigned int d_type) | 651 | loff_t offset, u64 ino, unsigned int d_type) |
652 | { | 652 | { |
653 | struct fat_ioctl_filldir_callback *buf = __buf; | 653 | struct fat_ioctl_filldir_callback *buf = __buf; |
654 | struct dirent __user *d1 = buf->dirent; | 654 | struct dirent __user *d1 = buf->dirent; |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index e35d7e52fdeb..1cbd2e4ee122 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -184,7 +184,7 @@ struct dentry_list_arg { | |||
184 | 184 | ||
185 | static int | 185 | static int |
186 | nfsd4_build_dentrylist(void *arg, const char *name, int namlen, | 186 | nfsd4_build_dentrylist(void *arg, const char *name, int namlen, |
187 | loff_t offset, ino_t ino, unsigned int d_type) | 187 | loff_t offset, u64 ino, unsigned int d_type) |
188 | { | 188 | { |
189 | struct dentry_list_arg *dla = arg; | 189 | struct dentry_list_arg *dla = arg; |
190 | struct list_head *dentries = &dla->dentries; | 190 | struct list_head *dentries = &dla->dentries; |
diff --git a/fs/readdir.c b/fs/readdir.c index b6109329b607..bff3ee58e2f8 100644 --- a/fs/readdir.c +++ b/fs/readdir.c | |||
@@ -69,20 +69,24 @@ struct readdir_callback { | |||
69 | }; | 69 | }; |
70 | 70 | ||
71 | static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, | 71 | static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset, |
72 | ino_t ino, unsigned int d_type) | 72 | u64 ino, unsigned int d_type) |
73 | { | 73 | { |
74 | struct readdir_callback * buf = (struct readdir_callback *) __buf; | 74 | struct readdir_callback * buf = (struct readdir_callback *) __buf; |
75 | struct old_linux_dirent __user * dirent; | 75 | struct old_linux_dirent __user * dirent; |
76 | unsigned long d_ino; | ||
76 | 77 | ||
77 | if (buf->result) | 78 | if (buf->result) |
78 | return -EINVAL; | 79 | return -EINVAL; |
80 | d_ino = ino; | ||
81 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
82 | return -EOVERFLOW; | ||
79 | buf->result++; | 83 | buf->result++; |
80 | dirent = buf->dirent; | 84 | dirent = buf->dirent; |
81 | if (!access_ok(VERIFY_WRITE, dirent, | 85 | if (!access_ok(VERIFY_WRITE, dirent, |
82 | (unsigned long)(dirent->d_name + namlen + 1) - | 86 | (unsigned long)(dirent->d_name + namlen + 1) - |
83 | (unsigned long)dirent)) | 87 | (unsigned long)dirent)) |
84 | goto efault; | 88 | goto efault; |
85 | if ( __put_user(ino, &dirent->d_ino) || | 89 | if ( __put_user(d_ino, &dirent->d_ino) || |
86 | __put_user(offset, &dirent->d_offset) || | 90 | __put_user(offset, &dirent->d_offset) || |
87 | __put_user(namlen, &dirent->d_namlen) || | 91 | __put_user(namlen, &dirent->d_namlen) || |
88 | __copy_to_user(dirent->d_name, name, namlen) || | 92 | __copy_to_user(dirent->d_name, name, namlen) || |
@@ -138,22 +142,26 @@ struct getdents_callback { | |||
138 | }; | 142 | }; |
139 | 143 | ||
140 | static int filldir(void * __buf, const char * name, int namlen, loff_t offset, | 144 | static int filldir(void * __buf, const char * name, int namlen, loff_t offset, |
141 | ino_t ino, unsigned int d_type) | 145 | u64 ino, unsigned int d_type) |
142 | { | 146 | { |
143 | struct linux_dirent __user * dirent; | 147 | struct linux_dirent __user * dirent; |
144 | struct getdents_callback * buf = (struct getdents_callback *) __buf; | 148 | struct getdents_callback * buf = (struct getdents_callback *) __buf; |
149 | unsigned long d_ino; | ||
145 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); | 150 | int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2); |
146 | 151 | ||
147 | buf->error = -EINVAL; /* only used if we fail.. */ | 152 | buf->error = -EINVAL; /* only used if we fail.. */ |
148 | if (reclen > buf->count) | 153 | if (reclen > buf->count) |
149 | return -EINVAL; | 154 | return -EINVAL; |
155 | d_ino = ino; | ||
156 | if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) | ||
157 | return -EOVERFLOW; | ||
150 | dirent = buf->previous; | 158 | dirent = buf->previous; |
151 | if (dirent) { | 159 | if (dirent) { |
152 | if (__put_user(offset, &dirent->d_off)) | 160 | if (__put_user(offset, &dirent->d_off)) |
153 | goto efault; | 161 | goto efault; |
154 | } | 162 | } |
155 | dirent = buf->current_dir; | 163 | dirent = buf->current_dir; |
156 | if (__put_user(ino, &dirent->d_ino)) | 164 | if (__put_user(d_ino, &dirent->d_ino)) |
157 | goto efault; | 165 | goto efault; |
158 | if (__put_user(reclen, &dirent->d_reclen)) | 166 | if (__put_user(reclen, &dirent->d_reclen)) |
159 | goto efault; | 167 | goto efault; |
@@ -222,7 +230,7 @@ struct getdents_callback64 { | |||
222 | }; | 230 | }; |
223 | 231 | ||
224 | static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, | 232 | static int filldir64(void * __buf, const char * name, int namlen, loff_t offset, |
225 | ino_t ino, unsigned int d_type) | 233 | u64 ino, unsigned int d_type) |
226 | { | 234 | { |
227 | struct linux_dirent64 __user *dirent; | 235 | struct linux_dirent64 __user *dirent; |
228 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; | 236 | struct getdents_callback64 * buf = (struct getdents_callback64 *) __buf; |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index d935fb9394e3..7bdb0ed443e1 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -773,7 +773,7 @@ int reiserfs_xattr_del(struct inode *inode, const char *name) | |||
773 | 773 | ||
774 | static int | 774 | static int |
775 | reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | 775 | reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, |
776 | loff_t offset, ino_t ino, unsigned int d_type) | 776 | loff_t offset, u64 ino, unsigned int d_type) |
777 | { | 777 | { |
778 | struct dentry *xadir = (struct dentry *)buf; | 778 | struct dentry *xadir = (struct dentry *)buf; |
779 | 779 | ||
@@ -851,7 +851,7 @@ struct reiserfs_chown_buf { | |||
851 | /* XXX: If there is a better way to do this, I'd love to hear about it */ | 851 | /* XXX: If there is a better way to do this, I'd love to hear about it */ |
852 | static int | 852 | static int |
853 | reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, | 853 | reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen, |
854 | loff_t offset, ino_t ino, unsigned int d_type) | 854 | loff_t offset, u64 ino, unsigned int d_type) |
855 | { | 855 | { |
856 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; | 856 | struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf; |
857 | struct dentry *xafile, *xadir = chown_buf->xadir; | 857 | struct dentry *xafile, *xadir = chown_buf->xadir; |
@@ -1036,7 +1036,7 @@ struct reiserfs_listxattr_buf { | |||
1036 | 1036 | ||
1037 | static int | 1037 | static int |
1038 | reiserfs_listxattr_filler(void *buf, const char *name, int namelen, | 1038 | reiserfs_listxattr_filler(void *buf, const char *name, int namelen, |
1039 | loff_t offset, ino_t ino, unsigned int d_type) | 1039 | loff_t offset, u64 ino, unsigned int d_type) |
1040 | { | 1040 | { |
1041 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; | 1041 | struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; |
1042 | int len = 0; | 1042 | int len = 0; |
@@ -140,6 +140,8 @@ static int cp_old_stat(struct kstat *stat, struct __old_kernel_stat __user * sta | |||
140 | memset(&tmp, 0, sizeof(struct __old_kernel_stat)); | 140 | memset(&tmp, 0, sizeof(struct __old_kernel_stat)); |
141 | tmp.st_dev = old_encode_dev(stat->dev); | 141 | tmp.st_dev = old_encode_dev(stat->dev); |
142 | tmp.st_ino = stat->ino; | 142 | tmp.st_ino = stat->ino; |
143 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
144 | return -EOVERFLOW; | ||
143 | tmp.st_mode = stat->mode; | 145 | tmp.st_mode = stat->mode; |
144 | tmp.st_nlink = stat->nlink; | 146 | tmp.st_nlink = stat->nlink; |
145 | if (tmp.st_nlink != stat->nlink) | 147 | if (tmp.st_nlink != stat->nlink) |
@@ -210,6 +212,8 @@ static int cp_new_stat(struct kstat *stat, struct stat __user *statbuf) | |||
210 | tmp.st_dev = new_encode_dev(stat->dev); | 212 | tmp.st_dev = new_encode_dev(stat->dev); |
211 | #endif | 213 | #endif |
212 | tmp.st_ino = stat->ino; | 214 | tmp.st_ino = stat->ino; |
215 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
216 | return -EOVERFLOW; | ||
213 | tmp.st_mode = stat->mode; | 217 | tmp.st_mode = stat->mode; |
214 | tmp.st_nlink = stat->nlink; | 218 | tmp.st_nlink = stat->nlink; |
215 | if (tmp.st_nlink != stat->nlink) | 219 | if (tmp.st_nlink != stat->nlink) |
@@ -347,6 +351,8 @@ static long cp_new_stat64(struct kstat *stat, struct stat64 __user *statbuf) | |||
347 | tmp.st_rdev = huge_encode_dev(stat->rdev); | 351 | tmp.st_rdev = huge_encode_dev(stat->rdev); |
348 | #endif | 352 | #endif |
349 | tmp.st_ino = stat->ino; | 353 | tmp.st_ino = stat->ino; |
354 | if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino) | ||
355 | return -EOVERFLOW; | ||
350 | #ifdef STAT64_HAS_BROKEN_ST_INO | 356 | #ifdef STAT64_HAS_BROKEN_ST_INO |
351 | tmp.__st_ino = stat->ino; | 357 | tmp.__st_ino = stat->ino; |
352 | #endif | 358 | #endif |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 91c0b2a32a90..7b61e94bf8fc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1049,7 +1049,7 @@ int generic_osync_inode(struct inode *, struct address_space *, int); | |||
1049 | * This allows the kernel to read directories into kernel space or | 1049 | * This allows the kernel to read directories into kernel space or |
1050 | * to have different dirent layouts depending on the binary type. | 1050 | * to have different dirent layouts depending on the binary type. |
1051 | */ | 1051 | */ |
1052 | typedef int (*filldir_t)(void *, const char *, int, loff_t, ino_t, unsigned); | 1052 | typedef int (*filldir_t)(void *, const char *, int, loff_t, u64, unsigned); |
1053 | 1053 | ||
1054 | struct block_device_operations { | 1054 | struct block_device_operations { |
1055 | int (*open) (struct inode *, struct file *); | 1055 | int (*open) (struct inode *, struct file *); |
diff --git a/include/linux/stat.h b/include/linux/stat.h index 8669291352db..679ef0d70b6b 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h | |||
@@ -57,7 +57,7 @@ | |||
57 | #include <linux/time.h> | 57 | #include <linux/time.h> |
58 | 58 | ||
59 | struct kstat { | 59 | struct kstat { |
60 | unsigned long ino; | 60 | u64 ino; |
61 | dev_t dev; | 61 | dev_t dev; |
62 | umode_t mode; | 62 | umode_t mode; |
63 | unsigned int nlink; | 63 | unsigned int nlink; |