diff options
Diffstat (limited to 'arch')
-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 |
13 files changed, 110 insertions, 25 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) || |