#include <linux/poll.h>
#include <linux/mm.h>
#include <linux/eventpoll.h>
+#include <linux/fs_struct.h>
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
struct compat_stat __user *statbuf)
{
struct kstat stat;
- int error = vfs_stat_fd(AT_FDCWD, filename, &stat);
+ int error;
- if (!error)
- error = cp_compat_stat(&stat, statbuf);
- return error;
+ error = vfs_stat(filename, &stat);
+ if (error)
+ return error;
+ return cp_compat_stat(&stat, statbuf);
}
asmlinkage long compat_sys_newlstat(char __user * filename,
struct compat_stat __user *statbuf)
{
struct kstat stat;
- int error = vfs_lstat_fd(AT_FDCWD, filename, &stat);
+ int error;
- if (!error)
- error = cp_compat_stat(&stat, statbuf);
- return error;
+ error = vfs_lstat(filename, &stat);
+ if (error)
+ return error;
+ return cp_compat_stat(&stat, statbuf);
}
#ifndef __ARCH_WANT_STAT64
struct compat_stat __user *statbuf, int flag)
{
struct kstat stat;
- int error = -EINVAL;
-
- if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0)
- goto out;
-
- if (flag & AT_SYMLINK_NOFOLLOW)
- error = vfs_lstat_fd(dfd, filename, &stat);
- else
- error = vfs_stat_fd(dfd, filename, &stat);
-
- if (!error)
- error = cp_compat_stat(&stat, statbuf);
+ int error;
-out:
- return error;
+ error = vfs_fstatat(dfd, filename, &stat, flag);
+ if (error)
+ return error;
+ return cp_compat_stat(&stat, statbuf);
}
#endif
ret = sys_fcntl(fd, cmd, (unsigned long)&f);
set_fs(old_fs);
if (cmd == F_GETLK && ret == 0) {
- /* GETLK was successfule and we need to return the data...
+ /* GETLK was successful and we need to return the data...
* but it needs to fit in the compat structure.
* l_start shouldn't be too big, unless the original
* start + end is greater than COMPAT_OFF_T_MAX, in which
}
}
- lock_kernel();
retval = do_mount((char*)dev_page, dir_page, (char*)type_page,
flags, (void*)data_page);
- unlock_kernel();
out4:
free_page(data_page);
unsigned long vlen)
{
struct file *file;
+ int fput_needed;
ssize_t ret;
- file = fget(fd);
+ file = fget_light(fd, &fput_needed);
if (!file)
return -EBADF;
ret = compat_readv(file, vec, vlen, &file->f_pos);
- fput(file);
+ fput_light(file, fput_needed);
return ret;
}
asmlinkage ssize_t
compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low)
+ unsigned long vlen, u32 pos_low, u32 pos_high)
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
struct file *file;
+ int fput_needed;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget(fd);
+ file = fget_light(fd, &fput_needed);
if (!file)
return -EBADF;
ret = compat_readv(file, vec, vlen, &pos);
- fput(file);
+ fput_light(file, fput_needed);
return ret;
}
unsigned long vlen)
{
struct file *file;
+ int fput_needed;
ssize_t ret;
- file = fget(fd);
+ file = fget_light(fd, &fput_needed);
if (!file)
return -EBADF;
ret = compat_writev(file, vec, vlen, &file->f_pos);
- fput(file);
+ fput_light(file, fput_needed);
return ret;
}
asmlinkage ssize_t
compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
- unsigned long vlen, u32 pos_high, u32 pos_low)
+ unsigned long vlen, u32 pos_low, u32 pos_high)
{
loff_t pos = ((loff_t)pos_high << 32) | pos_low;
struct file *file;
+ int fput_needed;
ssize_t ret;
if (pos < 0)
return -EINVAL;
- file = fget(fd);
+ file = fget_light(fd, &fput_needed);
if (!file)
return -EBADF;
ret = compat_writev(file, vec, vlen, &pos);
- fput(file);
+ fput_light(file, fput_needed);
return ret;
}
struct linux_binprm *bprm;
struct file *file;
struct files_struct *displaced;
+ bool clear_in_exec;
int retval;
retval = unshare_files(&displaced);
if (!bprm)
goto out_files;
- retval = mutex_lock_interruptible(¤t->cred_exec_mutex);
+ retval = mutex_lock_interruptible(¤t->cred_guard_mutex);
if (retval < 0)
goto out_free;
current->in_execve = 1;
bprm->cred = prepare_exec_creds();
if (!bprm->cred)
goto out_unlock;
- check_unsafe_exec(bprm);
+
+ retval = check_unsafe_exec(bprm);
+ if (retval < 0)
+ goto out_unlock;
+ clear_in_exec = retval;
file = open_exec(filename);
retval = PTR_ERR(file);
if (IS_ERR(file))
- goto out_unlock;
+ goto out_unmark;
sched_exec();
goto out;
/* execve succeeded */
+ current->fs->in_exec = 0;
current->in_execve = 0;
- mutex_unlock(¤t->cred_exec_mutex);
+ mutex_unlock(¤t->cred_guard_mutex);
acct_update_integrals(current);
free_bprm(bprm);
if (displaced)
fput(bprm->file);
}
+out_unmark:
+ if (clear_in_exec)
+ current->fs->in_exec = 0;
+
out_unlock:
current->in_execve = 0;
- mutex_unlock(¤t->cred_exec_mutex);
+ mutex_unlock(¤t->cred_guard_mutex);
out_free:
free_bprm(bprm);