SYSCALL_DEFINE1(uselib, const char __user *, library)
{
struct file *file;
- struct nameidata nd;
char *tmp = getname(library);
int error = PTR_ERR(tmp);
- if (!IS_ERR(tmp)) {
- error = path_lookup_open(AT_FDCWD, tmp,
- LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- putname(tmp);
- }
- if (error)
+ if (IS_ERR(tmp))
+ goto out;
+
+ file = do_filp_open(AT_FDCWD, tmp,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_READ | MAY_EXEC | MAY_OPEN);
+ putname(tmp);
+ error = PTR_ERR(file);
+ if (IS_ERR(file))
goto out;
error = -EINVAL;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
goto exit;
error = -EACCES;
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto exit;
-
- error = inode_permission(nd.path.dentry->d_inode,
- MAY_READ | MAY_EXEC | MAY_OPEN);
- if (error)
- goto exit;
- error = ima_path_check(&nd.path, MAY_READ | MAY_EXEC | MAY_OPEN,
- IMA_COUNT_UPDATE);
- if (error)
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- error = PTR_ERR(file);
- if (IS_ERR(file))
- goto out;
-
fsnotify_open(file->f_path.dentry);
error = -ENOEXEC;
}
read_unlock(&binfmt_lock);
}
+ exit:
fput(file);
out:
return error;
- exit:
- release_open_intent(&nd);
- path_put(&nd.path);
- goto out;
}
#ifdef CONFIG_MMU
struct file *open_exec(const char *name)
{
- struct nameidata nd;
struct file *file;
int err;
- err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
- FMODE_READ|FMODE_EXEC);
- if (err)
+ file = do_filp_open(AT_FDCWD, name,
+ O_LARGEFILE | O_RDONLY | FMODE_EXEC, 0,
+ MAY_EXEC | MAY_OPEN);
+ if (IS_ERR(file))
goto out;
err = -EACCES;
- if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
- goto out_path_put;
-
- if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
- goto out_path_put;
-
- err = inode_permission(nd.path.dentry->d_inode, MAY_EXEC | MAY_OPEN);
- if (err)
- goto out_path_put;
- err = ima_path_check(&nd.path, MAY_EXEC | MAY_OPEN, IMA_COUNT_UPDATE);
- if (err)
- goto out_path_put;
+ if (!S_ISREG(file->f_path.dentry->d_inode->i_mode))
+ goto exit;
- file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
- if (IS_ERR(file))
- return file;
+ if (file->f_path.mnt->mnt_flags & MNT_NOEXEC)
+ goto exit;
fsnotify_open(file->f_path.dentry);
err = deny_write_access(file);
- if (err) {
- fput(file);
- goto out;
- }
+ if (err)
+ goto exit;
+ out:
return file;
- out_path_put:
- release_open_intent(&nd);
- path_put(&nd.path);
- out:
+ exit:
+ fput(file);
return ERR_PTR(err);
}
EXPORT_SYMBOL(open_exec);
commit_creds(bprm->cred);
bprm->cred = NULL;
- /* cred_exec_mutex must be held at least to this point to prevent
+ /* cred_guard_mutex must be held at least to this point to prevent
* ptrace_attach() from altering our determination of the task's
* credentials; any time after this it may be unlocked */
/*
* determine how safe it is to execute the proposed program
- * - the caller must hold current->cred_exec_mutex to protect against
+ * - the caller must hold current->cred_guard_mutex to protect against
* PTRACE_ATTACH
*/
int check_unsafe_exec(struct linux_binprm *bprm)
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;
/* 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)
out_unlock:
current->in_execve = 0;
- mutex_unlock(¤t->cred_exec_mutex);
+ mutex_unlock(¤t->cred_guard_mutex);
out_free:
free_bprm(bprm);
#include <linux/dnotify.h>
#include <linux/statfs.h>
#include <linux/security.h>
+#include <linux/ima.h>
#include <asm/uaccess.h>
return retval;
}
- /*
- * Read a page. Again trivial. If it didn't already exist
- * in the page cache, it is zero-filled.
- */
- static int hugetlbfs_readpage(struct file *file, struct page * page)
- {
- unlock_page(page);
- return -EINVAL;
- }
-
static int hugetlbfs_write_begin(struct file *file,
struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags,
}
static const struct address_space_operations hugetlbfs_aops = {
- .readpage = hugetlbfs_readpage,
.write_begin = hugetlbfs_write_begin,
.write_end = hugetlbfs_write_end,
.set_page_dirty = hugetlbfs_set_page_dirty,
&hugetlbfs_file_operations);
if (!file)
goto out_dentry; /* inode is already attached */
+ ima_counts_get(file);
return file;
err = inode_permission(nd->path.dentry->d_inode,
MAY_EXEC);
if (!err)
- err = ima_path_check(&nd->path, MAY_EXEC);
+ err = ima_path_check(&nd->path, MAY_EXEC,
+ IMA_COUNT_UPDATE);
if (err)
break;
* @nd: pointer to nameidata
* @open_flags: open intent flags
*/
- int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
- struct nameidata *nd, int open_flags)
+ static int path_lookup_open(int dfd, const char *name,
+ unsigned int lookup_flags, struct nameidata *nd, int open_flags)
{
struct file *filp = get_empty_filp();
int err;
return error;
error = ima_path_check(path,
- acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC));
+ acc_mode & (MAY_READ | MAY_WRITE | MAY_EXEC),
+ IMA_COUNT_UPDATE);
if (error)
return error;
/*
* open_to_namei_flags() for more details.
*/
struct file *do_filp_open(int dfd, const char *pathname,
- int open_flag, int mode)
+ int open_flag, int mode, int acc_mode)
{
struct file *filp;
struct nameidata nd;
- int acc_mode, error;
+ int error;
struct path path;
struct dentry *dir;
int count = 0;
int will_write;
int flag = open_to_namei_flags(open_flag);
- acc_mode = MAY_OPEN | ACC_MODE(flag);
+ if (!acc_mode)
+ acc_mode = MAY_OPEN | ACC_MODE(flag);
/* O_TRUNC implies we need access checks for write permissions */
if (flag & O_TRUNC)
*/
struct file *filp_open(const char *filename, int flags, int mode)
{
- return do_filp_open(AT_FDCWD, filename, flags, mode);
+ return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
}
EXPORT_SYMBOL(filp_open);
static int __maybe_unused two = 2;
static unsigned long one_ul = 1;
static int one_hundred = 100;
- static int one_thousand = 1000;
/* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */
static unsigned long dirty_bytes_min = 2 * PAGE_SIZE;
#ifdef CONFIG_MODULES
extern char modprobe_path[];
+extern int modules_disabled;
#endif
#ifdef CONFIG_CHR_DEV_SG
extern int sg_big_buff;
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
},
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "modules_disabled",
+ .data = &modules_disabled,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ /* only handle a transition from default "0" to "1" */
+ .proc_handler = &proc_dointvec_minmax,
+ .extra1 = &one,
+ .extra2 = &one,
+ },
#endif
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
{
.mode = 0444 /* read-only*/,
.proc_handler = &proc_dointvec,
},
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "nr_pdflush_threads_min",
- .data = &nr_pdflush_threads_min,
- .maxlen = sizeof nr_pdflush_threads_min,
- .mode = 0644 /* read-write */,
- .proc_handler = &proc_dointvec_minmax,
- .strategy = &sysctl_intvec,
- .extra1 = &one,
- .extra2 = &nr_pdflush_threads_max,
- },
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "nr_pdflush_threads_max",
- .data = &nr_pdflush_threads_max,
- .maxlen = sizeof nr_pdflush_threads_max,
- .mode = 0644 /* read-write */,
- .proc_handler = &proc_dointvec_minmax,
- .strategy = &sysctl_intvec,
- .extra1 = &nr_pdflush_threads_min,
- .extra2 = &one_thousand,
- },
{
.ctl_name = VM_SWAPPINESS,
.procname = "swappiness",