aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2008-10-16 01:02:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 14:21:33 -0400
commitf7a5000f7a8924e9c5fad1801616601d6dc65a17 (patch)
tree82bd7f554378b26fe23707a3755359787b252574 /arch
parentf7ad160b49c49dc9cd383b9184c6fa4a9b4f7ebb (diff)
compat: move cp_compat_stat to common code
struct stat / compat_stat is the same on all architectures, so cp_compat_stat should be, too. Turns out it is, except that various architectures have slightly and some high2lowuid/high2lowgid or the direct assignment instead of the SET_UID/SET_GID that expands to the correct one anyway. This patch replaces the arch-specific cp_compat_stat implementations with a common one based on the x86-64 one. Signed-off-by: Christoph Hellwig <hch@lst.de> Acked-by: David S. Miller <davem@davemloft.net> [ sparc bits ] Acked-by: Kyle McMartin <kyle@mcmartin.ca> [ parisc bits ] Cc: <linux-arch@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/ia64/ia32/sys_ia32.c35
-rw-r--r--arch/mips/kernel/linux32.c35
-rw-r--r--arch/parisc/kernel/sys_parisc32.c47
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c36
-rw-r--r--arch/s390/kernel/compat_linux.c35
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c35
-rw-r--r--arch/x86/ia32/sys_ia32.c35
7 files changed, 0 insertions, 258 deletions
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index bf196cbb3796..2362a8eefb30 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -118,41 +118,6 @@ sys32_execve (char __user *name, compat_uptr_t __user *argv, compat_uptr_t __use
118 return error; 118 return error;
119} 119}
120 120
121int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
122{
123 compat_ino_t ino;
124 int err;
125
126 if ((u64) stat->size > MAX_NON_LFS ||
127 !old_valid_dev(stat->dev) ||
128 !old_valid_dev(stat->rdev))
129 return -EOVERFLOW;
130
131 ino = stat->ino;
132 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
133 return -EOVERFLOW;
134
135 if (clear_user(ubuf, sizeof(*ubuf)))
136 return -EFAULT;
137
138 err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
139 err |= __put_user(ino, &ubuf->st_ino);
140 err |= __put_user(stat->mode, &ubuf->st_mode);
141 err |= __put_user(stat->nlink, &ubuf->st_nlink);
142 err |= __put_user(high2lowuid(stat->uid), &ubuf->st_uid);
143 err |= __put_user(high2lowgid(stat->gid), &ubuf->st_gid);
144 err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
145 err |= __put_user(stat->size, &ubuf->st_size);
146 err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
147 err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
148 err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
149 err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
150 err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
151 err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
152 err |= __put_user(stat->blksize, &ubuf->st_blksize);
153 err |= __put_user(stat->blocks, &ubuf->st_blocks);
154 return err;
155}
156 121
157#if PAGE_SHIFT > IA32_PAGE_SHIFT 122#if PAGE_SHIFT > IA32_PAGE_SHIFT
158 123
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 2fefb14414b7..89223a9bff2c 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -63,41 +63,6 @@
63#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL)) 63#define merge_64(r1, r2) ((((r2) & 0xffffffffUL) << 32) + ((r1) & 0xffffffffUL))
64#endif 64#endif
65 65
66/*
67 * Revalidate the inode. This is required for proper NFS attribute caching.
68 */
69
70int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
71{
72 struct compat_stat tmp;
73
74 if (!new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev))
75 return -EOVERFLOW;
76
77 memset(&tmp, 0, sizeof(tmp));
78 tmp.st_dev = new_encode_dev(stat->dev);
79 tmp.st_ino = stat->ino;
80 if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
81 return -EOVERFLOW;
82 tmp.st_mode = stat->mode;
83 tmp.st_nlink = stat->nlink;
84 SET_UID(tmp.st_uid, stat->uid);
85 SET_GID(tmp.st_gid, stat->gid);
86 tmp.st_rdev = new_encode_dev(stat->rdev);
87 tmp.st_size = stat->size;
88 tmp.st_atime = stat->atime.tv_sec;
89 tmp.st_mtime = stat->mtime.tv_sec;
90 tmp.st_ctime = stat->ctime.tv_sec;
91#ifdef STAT_HAVE_NSEC
92 tmp.st_atime_nsec = stat->atime.tv_nsec;
93 tmp.st_mtime_nsec = stat->mtime.tv_nsec;
94 tmp.st_ctime_nsec = stat->ctime.tv_nsec;
95#endif
96 tmp.st_blocks = stat->blocks;
97 tmp.st_blksize = stat->blksize;
98 return copy_to_user(statbuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
99}
100
101asmlinkage unsigned long 66asmlinkage unsigned long
102sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 67sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
103 unsigned long flags, unsigned long fd, unsigned long pgoff) 68 unsigned long flags, unsigned long fd, unsigned long pgoff)
diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c
index 71efd6a28e2a..2c3af17e049c 100644
--- a/arch/parisc/kernel/sys_parisc32.c
+++ b/arch/parisc/kernel/sys_parisc32.c
@@ -237,53 +237,6 @@ int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user
237 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); 237 return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
238} 238}
239 239
240int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
241{
242 compat_ino_t ino;
243 int err;
244
245 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
246 !new_valid_dev(stat->rdev))
247 return -EOVERFLOW;
248
249 ino = stat->ino;
250 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
251 return -EOVERFLOW;
252
253 err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
254 err |= put_user(ino, &statbuf->st_ino);
255 err |= put_user(stat->mode, &statbuf->st_mode);
256 err |= put_user(stat->nlink, &statbuf->st_nlink);
257 err |= put_user(0, &statbuf->st_reserved1);
258 err |= put_user(0, &statbuf->st_reserved2);
259 err |= put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
260 err |= put_user(stat->size, &statbuf->st_size);
261 err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
262 err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
263 err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
264 err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
265 err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
266 err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
267 err |= put_user(stat->blksize, &statbuf->st_blksize);
268 err |= put_user(stat->blocks, &statbuf->st_blocks);
269 err |= put_user(0, &statbuf->__unused1);
270 err |= put_user(0, &statbuf->__unused2);
271 err |= put_user(0, &statbuf->__unused3);
272 err |= put_user(0, &statbuf->__unused4);
273 err |= put_user(0, &statbuf->__unused5);
274 err |= put_user(0, &statbuf->st_fstype); /* not avail */
275 err |= put_user(0, &statbuf->st_realdev); /* not avail */
276 err |= put_user(0, &statbuf->st_basemode); /* not avail */
277 err |= put_user(0, &statbuf->st_spareshort);
278 err |= put_user(stat->uid, &statbuf->st_uid);
279 err |= put_user(stat->gid, &statbuf->st_gid);
280 err |= put_user(0, &statbuf->st_spare4[0]);
281 err |= put_user(0, &statbuf->st_spare4[1]);
282 err |= put_user(0, &statbuf->st_spare4[2]);
283
284 return err;
285}
286
287/*** copied from mips64 ***/ 240/*** copied from mips64 ***/
288/* 241/*
289 * Ooo, nasty. We need here to frob 32-bit unsigned longs to 242 * Ooo, nasty. We need here to frob 32-bit unsigned longs to
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index ff7de7b0797e..d00599bb24a1 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -61,42 +61,6 @@ asmlinkage long ppc32_select(u32 n, compat_ulong_t __user *inp,
61 return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x)); 61 return compat_sys_select((int)n, inp, outp, exp, compat_ptr(tvp_x));
62} 62}
63 63
64int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
65{
66 compat_ino_t ino;
67 long err;
68
69 if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) ||
70 !new_valid_dev(stat->rdev))
71 return -EOVERFLOW;
72
73 ino = stat->ino;
74 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
75 return -EOVERFLOW;
76
77 err = access_ok(VERIFY_WRITE, statbuf, sizeof(*statbuf)) ? 0 : -EFAULT;
78 err |= __put_user(new_encode_dev(stat->dev), &statbuf->st_dev);
79 err |= __put_user(ino, &statbuf->st_ino);
80 err |= __put_user(stat->mode, &statbuf->st_mode);
81 err |= __put_user(stat->nlink, &statbuf->st_nlink);
82 err |= __put_user(stat->uid, &statbuf->st_uid);
83 err |= __put_user(stat->gid, &statbuf->st_gid);
84 err |= __put_user(new_encode_dev(stat->rdev), &statbuf->st_rdev);
85 err |= __put_user(stat->size, &statbuf->st_size);
86 err |= __put_user(stat->atime.tv_sec, &statbuf->st_atime);
87 err |= __put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
88 err |= __put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
89 err |= __put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
90 err |= __put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
91 err |= __put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
92 err |= __put_user(stat->blksize, &statbuf->st_blksize);
93 err |= __put_user(stat->blocks, &statbuf->st_blocks);
94 err |= __put_user(0, &statbuf->__unused4[0]);
95 err |= __put_user(0, &statbuf->__unused4[1]);
96
97 return err;
98}
99
100/* Note: it is necessary to treat option as an unsigned int, 64/* Note: it is necessary to treat option as an unsigned int,
101 * with the corresponding cast to a signed int to insure that the 65 * with the corresponding cast to a signed int to insure that the
102 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) 66 * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 98e246dc0233..9b471d785ec1 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -362,41 +362,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
362 return sys_ftruncate(fd, (high << 32) | low); 362 return sys_ftruncate(fd, (high << 32) | low);
363} 363}
364 364
365int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
366{
367 compat_ino_t ino;
368 int err;
369
370 if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
371 return -EOVERFLOW;
372
373 ino = stat->ino;
374 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
375 return -EOVERFLOW;
376
377 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
378 err |= put_user(stat->ino, &statbuf->st_ino);
379 err |= put_user(stat->mode, &statbuf->st_mode);
380 err |= put_user(stat->nlink, &statbuf->st_nlink);
381 err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
382 err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
383 err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
384 err |= put_user(stat->size, &statbuf->st_size);
385 err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
386 err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
387 err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
388 err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
389 err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
390 err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
391 err |= put_user(stat->blksize, &statbuf->st_blksize);
392 err |= put_user(stat->blocks, &statbuf->st_blocks);
393/* fixme
394 err |= put_user(0, &statbuf->__unused4[0]);
395 err |= put_user(0, &statbuf->__unused4[1]);
396*/
397 return err;
398}
399
400asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid, 365asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
401 struct compat_timespec __user *interval) 366 struct compat_timespec __user *interval)
402{ 367{
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 3320c9d0075f..73a33dc3bcca 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -148,41 +148,6 @@ asmlinkage long sys32_ftruncate64(unsigned int fd, unsigned long high, unsigned
148 return sys_ftruncate(fd, (high << 32) | low); 148 return sys_ftruncate(fd, (high << 32) | low);
149} 149}
150 150
151int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf)
152{
153 compat_ino_t ino;
154 int err;
155
156 if (stat->size > MAX_NON_LFS || !old_valid_dev(stat->dev) ||
157 !old_valid_dev(stat->rdev))
158 return -EOVERFLOW;
159
160 ino = stat->ino;
161 if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
162 return -EOVERFLOW;
163
164 err = put_user(old_encode_dev(stat->dev), &statbuf->st_dev);
165 err |= put_user(stat->ino, &statbuf->st_ino);
166 err |= put_user(stat->mode, &statbuf->st_mode);
167 err |= put_user(stat->nlink, &statbuf->st_nlink);
168 err |= put_user(high2lowuid(stat->uid), &statbuf->st_uid);
169 err |= put_user(high2lowgid(stat->gid), &statbuf->st_gid);
170 err |= put_user(old_encode_dev(stat->rdev), &statbuf->st_rdev);
171 err |= put_user(stat->size, &statbuf->st_size);
172 err |= put_user(stat->atime.tv_sec, &statbuf->st_atime);
173 err |= put_user(stat->atime.tv_nsec, &statbuf->st_atime_nsec);
174 err |= put_user(stat->mtime.tv_sec, &statbuf->st_mtime);
175 err |= put_user(stat->mtime.tv_nsec, &statbuf->st_mtime_nsec);
176 err |= put_user(stat->ctime.tv_sec, &statbuf->st_ctime);
177 err |= put_user(stat->ctime.tv_nsec, &statbuf->st_ctime_nsec);
178 err |= put_user(stat->blksize, &statbuf->st_blksize);
179 err |= put_user(stat->blocks, &statbuf->st_blocks);
180 err |= put_user(0, &statbuf->__unused4[0]);
181 err |= put_user(0, &statbuf->__unused4[1]);
182
183 return err;
184}
185
186static int cp_compat_stat64(struct kstat *stat, 151static int cp_compat_stat64(struct kstat *stat,
187 struct compat_stat64 __user *statbuf) 152 struct compat_stat64 __user *statbuf)
188{ 153{
diff --git a/arch/x86/ia32/sys_ia32.c b/arch/x86/ia32/sys_ia32.c
index beda4232ce69..4d3ad8d78a4d 100644
--- a/arch/x86/ia32/sys_ia32.c
+++ b/arch/x86/ia32/sys_ia32.c
@@ -49,41 +49,6 @@
49 49
50#define AA(__x) ((unsigned long)(__x)) 50#define AA(__x) ((unsigned long)(__x))
51 51
52int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf)
53{
54 compat_ino_t ino;
55
56 typeof(ubuf->st_uid) uid = 0;
57 typeof(ubuf->st_gid) gid = 0;
58 SET_UID(uid, kbuf->uid);
59 SET_GID(gid, kbuf->gid);
60 if (!old_valid_dev(kbuf->dev) || !old_valid_dev(kbuf->rdev))
61 return -EOVERFLOW;
62 if (kbuf->size >= 0x7fffffff)
63 return -EOVERFLOW;
64 ino = kbuf->ino;
65 if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
66 return -EOVERFLOW;
67 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) ||
68 __put_user(old_encode_dev(kbuf->dev), &ubuf->st_dev) ||
69 __put_user(ino, &ubuf->st_ino) ||
70 __put_user(kbuf->mode, &ubuf->st_mode) ||
71 __put_user(kbuf->nlink, &ubuf->st_nlink) ||
72 __put_user(uid, &ubuf->st_uid) ||
73 __put_user(gid, &ubuf->st_gid) ||
74 __put_user(old_encode_dev(kbuf->rdev), &ubuf->st_rdev) ||
75 __put_user(kbuf->size, &ubuf->st_size) ||
76 __put_user(kbuf->atime.tv_sec, &ubuf->st_atime) ||
77 __put_user(kbuf->atime.tv_nsec, &ubuf->st_atime_nsec) ||
78 __put_user(kbuf->mtime.tv_sec, &ubuf->st_mtime) ||
79 __put_user(kbuf->mtime.tv_nsec, &ubuf->st_mtime_nsec) ||
80 __put_user(kbuf->ctime.tv_sec, &ubuf->st_ctime) ||
81 __put_user(kbuf->ctime.tv_nsec, &ubuf->st_ctime_nsec) ||
82 __put_user(kbuf->blksize, &ubuf->st_blksize) ||
83 __put_user(kbuf->blocks, &ubuf->st_blocks))
84 return -EFAULT;
85 return 0;
86}
87 52
88asmlinkage long sys32_truncate64(char __user *filename, 53asmlinkage long sys32_truncate64(char __user *filename,
89 unsigned long offset_low, 54 unsigned long offset_low,