git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gerg/m68knommu
[safe/jmp/linux-2.6]
/
fs
/
binfmt_misc.c
diff --git
a/fs/binfmt_misc.c
b/fs/binfmt_misc.c
index
599f36f
..
c4e8353
100644
(file)
--- a/
fs/binfmt_misc.c
+++ b/
fs/binfmt_misc.c
@@
-1,7
+1,7
@@
/*
* binfmt_misc.c
*
/*
* binfmt_misc.c
*
- * Copyright (C) 1997 Richard G
ü
nther
+ * Copyright (C) 1997 Richard G
ü
nther
*
* binfmt_misc detects binaries via a magic or filename extension and invokes
* a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
*
* binfmt_misc detects binaries via a magic or filename extension and invokes
* a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
@@
-18,7
+18,7
@@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/init.h>
-
+#include <linux/sched.h>
#include <linux/binfmts.h>
#include <linux/slab.h>
#include <linux/ctype.h>
#include <linux/binfmts.h>
#include <linux/slab.h>
#include <linux/ctype.h>
@@
-27,6
+27,7
@@
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/syscalls.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/syscalls.h>
+#include <linux/fs.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
@@
-55,6
+56,7
@@
typedef struct {
} Node;
static DEFINE_RWLOCK(entries_lock);
} Node;
static DEFINE_RWLOCK(entries_lock);
+static struct file_system_type bm_fs_type;
static struct vfsmount *bm_mnt;
static int entry_count;
static struct vfsmount *bm_mnt;
static int entry_count;
@@
-109,12
+111,15
@@
static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
char *iname_addr = iname;
int retval;
int fd_binary = -1;
char *iname_addr = iname;
int retval;
int fd_binary = -1;
- struct files_struct *files = NULL;
retval = -ENOEXEC;
if (!enabled)
goto _ret;
retval = -ENOEXEC;
if (!enabled)
goto _ret;
+ retval = -ENOEXEC;
+ if (bprm->recursion_depth > BINPRM_MAX_RECURSION)
+ goto _ret;
+
/* to keep locking time low, we copy the interpreter string */
read_lock(&entries_lock);
fmt = check_file(bprm);
/* to keep locking time low, we copy the interpreter string */
read_lock(&entries_lock);
fmt = check_file(bprm);
@@
-125,26
+130,20
@@
static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
goto _ret;
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
goto _ret;
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
- remove_arg_zero(bprm);
+ retval = remove_arg_zero(bprm);
+ if (retval)
+ goto _ret;
}
if (fmt->flags & MISC_FMT_OPEN_BINARY) {
}
if (fmt->flags & MISC_FMT_OPEN_BINARY) {
- files = current->files;
- retval = unshare_files();
- if (retval < 0)
- goto _ret;
- if (files == current->files) {
- put_files_struct(files);
- files = NULL;
- }
/* if the binary should be opened on behalf of the
* interpreter than keep it open and assign descriptor
* to it */
fd_binary = get_unused_fd();
if (fd_binary < 0) {
retval = fd_binary;
/* if the binary should be opened on behalf of the
* interpreter than keep it open and assign descriptor
* to it */
fd_binary = get_unused_fd();
if (fd_binary < 0) {
retval = fd_binary;
- goto _
unshare
;
+ goto _
ret
;
}
fd_install(fd_binary, bprm->file);
}
fd_install(fd_binary, bprm->file);
@@
-198,14
+197,12
@@
static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
if (retval < 0)
goto _error;
if (retval < 0)
goto _error;
+ bprm->recursion_depth++;
+
retval = search_binary_handler (bprm, regs);
if (retval < 0)
goto _error;
retval = search_binary_handler (bprm, regs);
if (retval < 0)
goto _error;
- if (files) {
- put_files_struct(files);
- files = NULL;
- }
_ret:
return retval;
_error:
_ret:
return retval;
_error:
@@
-213,11
+210,6
@@
_error:
sys_close(fd_binary);
bprm->interp_flags = 0;
bprm->interp_data = 0;
sys_close(fd_binary);
bprm->interp_flags = 0;
bprm->interp_data = 0;
-_unshare:
- if (files) {
- put_files_struct(current->files);
- current->files = files;
- }
goto _ret;
}
goto _ret;
}
@@
-312,7
+304,7
@@
static Node *create_entry(const char __user *buffer, size_t count)
err = -ENOMEM;
memsize = sizeof(Node) + count + 8;
err = -ENOMEM;
memsize = sizeof(Node) + count + 8;
- e =
(Node *)
kmalloc(memsize, GFP_USER);
+ e = kmalloc(memsize, GFP_USER);
if (!e)
goto out;
if (!e)
goto out;
@@
-504,10
+496,6
@@
static struct inode *bm_get_inode(struct super_block *sb, int mode)
if (inode) {
inode->i_mode = mode;
if (inode) {
inode->i_mode = mode;
- inode->i_uid = 0;
- inode->i_gid = 0;
- inode->i_blksize = PAGE_CACHE_SIZE;
- inode->i_blocks = 0;
inode->i_atime = inode->i_mtime = inode->i_ctime =
current_fs_time(inode->i_sb);
}
inode->i_atime = inode->i_mtime = inode->i_ctime =
current_fs_time(inode->i_sb);
}
@@
-516,7
+504,7
@@
static struct inode *bm_get_inode(struct super_block *sb, int mode)
static void bm_clear_inode(struct inode *inode)
{
static void bm_clear_inode(struct inode *inode)
{
- kfree(inode->
u.generic_ip
);
+ kfree(inode->
i_private
);
}
static void kill_node(Node *e)
}
static void kill_node(Node *e)
@@
-544,32
+532,17
@@
static void kill_node(Node *e)
static ssize_t
bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
{
static ssize_t
bm_entry_read(struct file * file, char __user * buf, size_t nbytes, loff_t *ppos)
{
- Node *e = file->f_dentry->d_inode->u.generic_ip;
- loff_t pos = *ppos;
+ Node *e = file->f_path.dentry->d_inode->i_private;
ssize_t res;
char *page;
ssize_t res;
char *page;
- int len;
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
entry_status(e, page);
if (!(page = (char*) __get_free_page(GFP_KERNEL)))
return -ENOMEM;
entry_status(e, page);
- len = strlen(page);
- res = -EINVAL;
- if (pos < 0)
- goto out;
- res = 0;
- if (pos >= len)
- goto out;
- if (len < pos + nbytes)
- nbytes = len - pos;
- res = -EFAULT;
- if (copy_to_user(buf, page + pos, nbytes))
- goto out;
- *ppos = pos + nbytes;
- res = nbytes;
-out:
+ res = simple_read_from_buffer(buf, nbytes, ppos, page, strlen(page));
+
free_page((unsigned long) page);
return res;
}
free_page((unsigned long) page);
return res;
}
@@
-578,7
+551,7
@@
static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
{
struct dentry *root;
size_t count, loff_t *ppos)
{
struct dentry *root;
- Node *e = file->f_
dentry->d_inode->u.generic_ip
;
+ Node *e = file->f_
path.dentry->d_inode->i_private
;
int res = parse_command(buffer, count);
switch (res) {
int res = parse_command(buffer, count);
switch (res) {
@@
-586,7
+559,7
@@
static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
break;
case 2: set_bit(Enabled, &e->flags);
break;
break;
case 2: set_bit(Enabled, &e->flags);
break;
- case 3: root = dget(file->f_
vfs
mnt->mnt_sb->s_root);
+ case 3: root = dget(file->f_
path.
mnt->mnt_sb->s_root);
mutex_lock(&root->d_inode->i_mutex);
kill_node(e);
mutex_lock(&root->d_inode->i_mutex);
kill_node(e);
@@
-612,7
+585,7
@@
static ssize_t bm_register_write(struct file *file, const char __user *buffer,
Node *e;
struct inode *inode;
struct dentry *root, *dentry;
Node *e;
struct inode *inode;
struct dentry *root, *dentry;
- struct super_block *sb = file->f_
vfs
mnt->mnt_sb;
+ struct super_block *sb = file->f_
path.
mnt->mnt_sb;
int err = 0;
e = create_entry(buffer, count);
int err = 0;
e = create_entry(buffer, count);
@@
-637,7
+610,7
@@
static ssize_t bm_register_write(struct file *file, const char __user *buffer,
if (!inode)
goto out2;
if (!inode)
goto out2;
- err = simple_pin_fs(
"binfmt_misc"
, &bm_mnt, &entry_count);
+ err = simple_pin_fs(
&bm_fs_type
, &bm_mnt, &entry_count);
if (err) {
iput(inode);
inode = NULL;
if (err) {
iput(inode);
inode = NULL;
@@
-645,7
+618,7
@@
static ssize_t bm_register_write(struct file *file, const char __user *buffer,
}
e->dentry = dget(dentry);
}
e->dentry = dget(dentry);
- inode->
u.generic_ip
= e;
+ inode->
i_private
= e;
inode->i_fop = &bm_entry_operations;
d_instantiate(dentry, inode);
inode->i_fop = &bm_entry_operations;
d_instantiate(dentry, inode);
@@
-676,20
+649,9
@@
static const struct file_operations bm_register_operations = {
static ssize_t
bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
static ssize_t
bm_status_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
- char *s = enabled ? "enabled" : "disabled";
- int len = strlen(s);
- loff_t pos = *ppos;
+ char *s = enabled ? "enabled\n" : "disabled\n";
- if (pos < 0)
- return -EINVAL;
- if (pos >= len)
- return 0;
- if (len < pos + nbytes)
- nbytes = len - pos;
- if (copy_to_user(buf, s + pos, nbytes))
- return -EFAULT;
- *ppos = pos + nbytes;
- return nbytes;
+ return simple_read_from_buffer(buf, nbytes, ppos, s, strlen(s));
}
static ssize_t bm_status_write(struct file * file, const char __user * buffer,
}
static ssize_t bm_status_write(struct file * file, const char __user * buffer,
@@
-701,7
+663,7
@@
static ssize_t bm_status_write(struct file * file, const char __user * buffer,
switch (res) {
case 1: enabled = 0; break;
case 2: enabled = 1; break;
switch (res) {
case 1: enabled = 0; break;
case 2: enabled = 1; break;
- case 3: root = dget(file->f_
vfs
mnt->mnt_sb->s_root);
+ case 3: root = dget(file->f_
path.
mnt->mnt_sb->s_root);
mutex_lock(&root->d_inode->i_mutex);
while (!list_empty(&entries))
mutex_lock(&root->d_inode->i_mutex);
while (!list_empty(&entries))
@@
-721,7
+683,7
@@
static const struct file_operations bm_status_operations = {
/* Superblock handling */
/* Superblock handling */
-static struct super_operations s_ops = {
+static
const
struct super_operations s_ops = {
.statfs = simple_statfs,
.clear_inode = bm_clear_inode,
};
.statfs = simple_statfs,
.clear_inode = bm_clear_inode,
};
@@
-729,8
+691,8
@@
static struct super_operations s_ops = {
static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
static struct tree_descr bm_files[] = {
static int bm_fill_super(struct super_block * sb, void * data, int silent)
{
static struct tree_descr bm_files[] = {
- [
1
] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
- [
2
] = {"register", &bm_register_operations, S_IWUSR},
+ [
2
] = {"status", &bm_status_operations, S_IWUSR|S_IRUGO},
+ [
3
] = {"register", &bm_register_operations, S_IWUSR},
/* last one */ {""}
};
int err = simple_fill_super(sb, 0x42494e4d, bm_files);
/* last one */ {""}
};
int err = simple_fill_super(sb, 0x42494e4d, bm_files);
@@
-739,10
+701,10
@@
static int bm_fill_super(struct super_block * sb, void * data, int silent)
return err;
}
return err;
}
-static
struct super_block *
bm_get_sb(struct file_system_type *fs_type,
- int flags, const char *dev_name, void *data)
+static
int
bm_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data
, struct vfsmount *mnt
)
{
{
- return get_sb_single(fs_type, flags, data, bm_fill_super);
+ return get_sb_single(fs_type, flags, data, bm_fill_super
, mnt
);
}
static struct linux_binfmt misc_format = {
}
static struct linux_binfmt misc_format = {