aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c48
1 files changed, 20 insertions, 28 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 3f84d5f1588..681ed81e6be 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -181,22 +181,24 @@ asmlinkage long compat_sys_newstat(char __user * filename,
181 struct compat_stat __user *statbuf) 181 struct compat_stat __user *statbuf)
182{ 182{
183 struct kstat stat; 183 struct kstat stat;
184 int error = vfs_stat_fd(AT_FDCWD, filename, &stat); 184 int error;
185 185
186 if (!error) 186 error = vfs_stat(filename, &stat);
187 error = cp_compat_stat(&stat, statbuf); 187 if (error)
188 return error; 188 return error;
189 return cp_compat_stat(&stat, statbuf);
189} 190}
190 191
191asmlinkage long compat_sys_newlstat(char __user * filename, 192asmlinkage long compat_sys_newlstat(char __user * filename,
192 struct compat_stat __user *statbuf) 193 struct compat_stat __user *statbuf)
193{ 194{
194 struct kstat stat; 195 struct kstat stat;
195 int error = vfs_lstat_fd(AT_FDCWD, filename, &stat); 196 int error;
196 197
197 if (!error) 198 error = vfs_lstat(filename, &stat);
198 error = cp_compat_stat(&stat, statbuf); 199 if (error)
199 return error; 200 return error;
201 return cp_compat_stat(&stat, statbuf);
200} 202}
201 203
202#ifndef __ARCH_WANT_STAT64 204#ifndef __ARCH_WANT_STAT64
@@ -204,21 +206,12 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user *filename,
204 struct compat_stat __user *statbuf, int flag) 206 struct compat_stat __user *statbuf, int flag)
205{ 207{
206 struct kstat stat; 208 struct kstat stat;
207 int error = -EINVAL; 209 int error;
208
209 if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
210 goto out;
211
212 if (flag & AT_SYMLINK_NOFOLLOW)
213 error = vfs_lstat_fd(dfd, filename, &stat);
214 else
215 error = vfs_stat_fd(dfd, filename, &stat);
216
217 if (!error)
218 error = cp_compat_stat(&stat, statbuf);
219 210
220out: 211 error = vfs_fstatat(dfd, filename, &stat, flag);
221 return error; 212 if (error)
213 return error;
214 return cp_compat_stat(&stat, statbuf);
222} 215}
223#endif 216#endif
224 217
@@ -1483,6 +1476,7 @@ int compat_do_execve(char * filename,
1483 struct linux_binprm *bprm; 1476 struct linux_binprm *bprm;
1484 struct file *file; 1477 struct file *file;
1485 struct files_struct *displaced; 1478 struct files_struct *displaced;
1479 bool clear_in_exec;
1486 int retval; 1480 int retval;
1487 1481
1488 retval = unshare_files(&displaced); 1482 retval = unshare_files(&displaced);
@@ -1505,8 +1499,9 @@ int compat_do_execve(char * filename,
1505 goto out_unlock; 1499 goto out_unlock;
1506 1500
1507 retval = check_unsafe_exec(bprm); 1501 retval = check_unsafe_exec(bprm);
1508 if (retval) 1502 if (retval < 0)
1509 goto out_unlock; 1503 goto out_unlock;
1504 clear_in_exec = retval;
1510 1505
1511 file = open_exec(filename); 1506 file = open_exec(filename);
1512 retval = PTR_ERR(file); 1507 retval = PTR_ERR(file);
@@ -1553,9 +1548,7 @@ int compat_do_execve(char * filename,
1553 goto out; 1548 goto out;
1554 1549
1555 /* execve succeeded */ 1550 /* execve succeeded */
1556 write_lock(&current->fs->lock);
1557 current->fs->in_exec = 0; 1551 current->fs->in_exec = 0;
1558 write_unlock(&current->fs->lock);
1559 current->in_execve = 0; 1552 current->in_execve = 0;
1560 mutex_unlock(&current->cred_exec_mutex); 1553 mutex_unlock(&current->cred_exec_mutex);
1561 acct_update_integrals(current); 1554 acct_update_integrals(current);
@@ -1575,9 +1568,8 @@ out_file:
1575 } 1568 }
1576 1569
1577out_unmark: 1570out_unmark:
1578 write_lock(&current->fs->lock); 1571 if (clear_in_exec)
1579 current->fs->in_exec = 0; 1572 current->fs->in_exec = 0;
1580 write_unlock(&current->fs->lock);
1581 1573
1582out_unlock: 1574out_unlock:
1583 current->in_execve = 0; 1575 current->in_execve = 0;