summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/exit.c11
-rw-r--r--kernel/fork.c16
-rw-r--r--kernel/ksyms.c20
-rw-r--r--kernel/module.c12
-rw-r--r--kernel/sys.c114
-rw-r--r--kernel/sysctl.c24
6 files changed, 135 insertions, 62 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index f6e8fb9b1..9a725e9c8 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -369,8 +369,11 @@ static inline void close_files(struct files_struct * files)
break;
while (set) {
if (set & 1) {
- close_fp(files->fd[i]);
- files->fd[i] = NULL;
+ struct file * file = files->fd[i];
+ if (file) {
+ files->fd[i] = NULL;
+ close_fp(file);
+ }
}
i++;
set >>= 1;
@@ -405,8 +408,8 @@ static inline void __exit_fs(struct task_struct *tsk)
if (fs) {
tsk->fs = NULL;
if (!--fs->count) {
- iput(fs->root);
- iput(fs->pwd);
+ dput(fs->root);
+ dput(fs->pwd);
kfree(fs);
}
}
diff --git a/kernel/fork.c b/kernel/fork.c
index c3bcf7cca..900d6015c 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -211,7 +211,7 @@ static inline int dup_mmap(struct mm_struct * mm)
flush_cache_mm(current->mm);
pprev = &mm->mmap;
for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) {
- struct inode *inode;
+ struct dentry *dentry;
tmp = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
if (!tmp) {
@@ -223,11 +223,11 @@ static inline int dup_mmap(struct mm_struct * mm)
tmp->vm_flags &= ~VM_LOCKED;
tmp->vm_mm = mm;
tmp->vm_next = NULL;
- inode = tmp->vm_inode;
- if (inode) {
- atomic_inc(&inode->i_count);
+ dentry = tmp->vm_dentry;
+ if (dentry) {
+ dentry->d_count++;
if (tmp->vm_flags & VM_DENYWRITE)
- inode->i_writecount--;
+ dentry->d_inode->i_writecount--;
/* insert tmp into the share list, just after mpnt */
if((tmp->vm_next_share = mpnt->vm_next_share) != NULL)
@@ -302,10 +302,8 @@ static inline int copy_fs(unsigned long clone_flags, struct task_struct * tsk)
return -1;
tsk->fs->count = 1;
tsk->fs->umask = current->fs->umask;
- if ((tsk->fs->root = current->fs->root))
- atomic_inc(&tsk->fs->root->i_count);
- if ((tsk->fs->pwd = current->fs->pwd))
- atomic_inc(&tsk->fs->pwd->i_count);
+ tsk->fs->root = dget(current->fs->root);
+ tsk->fs->pwd = dget(current->fs->pwd);
return 0;
}
diff --git a/kernel/ksyms.c b/kernel/ksyms.c
index 8e5607e1e..fff97a75a 100644
--- a/kernel/ksyms.c
+++ b/kernel/ksyms.c
@@ -141,12 +141,19 @@ EXPORT_SYMBOL(update_vm_cache);
EXPORT_SYMBOL(getname);
EXPORT_SYMBOL(putname);
EXPORT_SYMBOL(__fput);
-EXPORT_SYMBOL(__iget);
-EXPORT_SYMBOL(_iput);
-EXPORT_SYMBOL(namei);
+EXPORT_SYMBOL(iget);
+EXPORT_SYMBOL(iput);
+EXPORT_SYMBOL(__namei);
+EXPORT_SYMBOL(lookup_dentry);
EXPORT_SYMBOL(open_namei);
EXPORT_SYMBOL(sys_close);
EXPORT_SYMBOL(close_fp);
+EXPORT_SYMBOL(d_alloc_root);
+EXPORT_SYMBOL(d_delete);
+EXPORT_SYMBOL(d_add);
+EXPORT_SYMBOL(d_move);
+EXPORT_SYMBOL(d_instantiate);
+EXPORT_SYMBOL(__mark_inode_dirty);
EXPORT_SYMBOL(insert_file_free);
EXPORT_SYMBOL(check_disk_change);
EXPORT_SYMBOL(invalidate_buffers);
@@ -177,6 +184,7 @@ EXPORT_SYMBOL(posix_lock_file);
EXPORT_SYMBOL(posix_test_lock);
EXPORT_SYMBOL(posix_block_lock);
EXPORT_SYMBOL(posix_unblock_lock);
+EXPORT_SYMBOL(dput);
#if !defined(CONFIG_NFSD) && defined(CONFIG_NFSD_MODULE)
EXPORT_SYMBOL(do_nfsservctl);
@@ -329,7 +337,7 @@ EXPORT_SYMBOL(setup_arg_pages);
EXPORT_SYMBOL(copy_strings);
EXPORT_SYMBOL(do_execve);
EXPORT_SYMBOL(flush_old_exec);
-EXPORT_SYMBOL(open_inode);
+EXPORT_SYMBOL(open_dentry);
EXPORT_SYMBOL(read_exec);
/* Miscellaneous access points */
@@ -341,7 +349,7 @@ EXPORT_SYMBOL(set_writetime);
EXPORT_SYMBOL(sys_tz);
EXPORT_SYMBOL(__wait_on_super);
EXPORT_SYMBOL(file_fsync);
-EXPORT_SYMBOL(_clear_inode);
+EXPORT_SYMBOL(clear_inode);
EXPORT_SYMBOL(refile_buffer);
EXPORT_SYMBOL(nr_async_pages);
EXPORT_SYMBOL(___strtok);
@@ -352,7 +360,7 @@ EXPORT_SYMBOL(chrdev_inode_operations);
EXPORT_SYMBOL(blkdev_inode_operations);
EXPORT_SYMBOL(read_ahead);
EXPORT_SYMBOL(get_hash_table);
-EXPORT_SYMBOL(_get_empty_inode);
+EXPORT_SYMBOL(get_empty_inode);
EXPORT_SYMBOL(insert_inode_hash);
EXPORT_SYMBOL(event);
EXPORT_SYMBOL(__down);
diff --git a/kernel/module.c b/kernel/module.c
index 885539b5c..c584eb3ae 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -79,7 +79,8 @@ get_mod_name(const char *user_name, char **buf)
unsigned long page;
long retval;
- if ((unsigned long)user_name >= TASK_SIZE)
+ if ((unsigned long)user_name >= TASK_SIZE
+ && get_fs () != KERNEL_DS)
return -EFAULT;
page = __get_free_page(GFP_KERNEL);
@@ -134,7 +135,7 @@ sys_create_module(const char *name_user, size_t size)
error = -EEXIST;
goto err1;
}
- if ((mod = (struct module *)vmalloc(size)) == NULL) {
+ if ((mod = (struct module *)module_map(size)) == NULL) {
error = -ENOMEM;
goto err1;
}
@@ -685,6 +686,7 @@ sys_get_kernel_syms(struct kernel_sym *table)
{
struct module *mod;
int i;
+ struct kernel_sym ksym;
lock_kernel();
for (mod = module_list, i = 0; mod; mod = mod->next) {
@@ -695,8 +697,10 @@ sys_get_kernel_syms(struct kernel_sym *table)
if (table == NULL)
goto out;
+ /* So that we don't give the user our stack content */
+ memset (&ksym, 0, sizeof (ksym));
+
for (mod = module_list, i = 0; mod; mod = mod->next) {
- struct kernel_sym ksym;
struct module_symbol *msym;
unsigned int j;
@@ -790,7 +794,7 @@ free_module(struct module *mod)
/* And free the memory. */
- vfree(mod);
+ module_unmap(mod);
}
/*
diff --git a/kernel/sys.c b/kernel/sys.c
index ca3d17807..27d41eed1 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -21,7 +21,6 @@
#include <linux/fcntl.h>
#include <linux/acct.h>
#include <linux/tty.h>
-#include <linux/nametrans.h>
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/notifier.h>
@@ -397,10 +396,8 @@ int acct_process(long exitcode)
fs = get_fs();
set_fs(KERNEL_DS);
- acct_file.f_op->write(acct_file.f_inode, &acct_file,
+ acct_file.f_op->write(acct_file.f_dentry->d_inode, &acct_file,
(char *)&ac, sizeof(struct acct));
- /* inode->i_status |= ST_MODIFIED is willingly *not* done here */
-
set_fs(fs);
}
return 0;
@@ -408,8 +405,6 @@ int acct_process(long exitcode)
asmlinkage int sys_acct(const char *name)
{
- struct inode *inode = (struct inode *)0;
- char *tmp;
int error = -EPERM;
lock_kernel();
@@ -419,10 +414,10 @@ asmlinkage int sys_acct(const char *name)
if (name == (char *)0) {
if (acct_active) {
if (acct_file.f_op->release)
- acct_file.f_op->release(acct_file.f_inode, &acct_file);
+ acct_file.f_op->release(acct_file.f_dentry->d_inode, &acct_file);
- if (acct_file.f_inode != (struct inode *) 0)
- iput(acct_file.f_inode);
+ if (acct_file.f_dentry != NULL)
+ dput(acct_file.f_dentry);
acct_active = 0;
}
@@ -430,40 +425,51 @@ asmlinkage int sys_acct(const char *name)
} else {
error = -EBUSY;
if (!acct_active) {
- if ((error = getname(name, &tmp)) != 0)
+ struct dentry *dentry;
+ struct inode *inode;
+ char *tmp;
+
+ tmp = getname(name);
+ error = PTR_ERR(tmp);
+ if (IS_ERR(tmp))
goto out;
- error = open_namei(tmp, O_RDWR, 0600, &inode, 0);
+ dentry = open_namei(tmp, O_RDWR, 0600);
putname(tmp);
- if (error)
+
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
goto out;
+ inode = dentry->d_inode;
error = -EACCES;
if (!S_ISREG(inode->i_mode)) {
- iput(inode);
+ dput(dentry);
goto out;
}
error = -EIO;
if (!inode->i_op || !inode->i_op->default_file_ops ||
!inode->i_op->default_file_ops->write) {
- iput(inode);
+ dput(dentry);
goto out;
}
acct_file.f_mode = 3;
acct_file.f_flags = 0;
acct_file.f_count = 1;
- acct_file.f_inode = inode;
+ acct_file.f_dentry = dentry;
acct_file.f_pos = inode->i_size;
acct_file.f_reada = 0;
acct_file.f_op = inode->i_op->default_file_ops;
- if(acct_file.f_op->open)
- if(acct_file.f_op->open(acct_file.f_inode, &acct_file)) {
- iput(inode);
+ if(acct_file.f_op->open) {
+ error = acct_file.f_op->open(inode, &acct_file);
+ if (error) {
+ dput(dentry);
goto out;
}
+ }
acct_active = 1;
error = 0;
@@ -612,21 +618,17 @@ asmlinkage int sys_setuid(uid_t uid)
*/
asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
{
- uid_t old_ruid, old_euid, old_suid;
-
- old_ruid = current->uid;
- old_euid = current->euid;
- old_suid = current->suid;
-
- if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
- (ruid != current->euid) && (ruid != current->suid))
- return -EPERM;
- if ((euid != (uid_t) -1) && (euid != current->uid) &&
- (euid != current->euid) && (euid != current->suid))
- return -EPERM;
- if ((suid != (uid_t) -1) && (suid != current->uid) &&
- (suid != current->euid) && (suid != current->suid))
- return -EPERM;
+ if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
+ if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
+ (ruid != current->euid) && (ruid != current->suid))
+ return -EPERM;
+ if ((euid != (uid_t) -1) && (euid != current->uid) &&
+ (euid != current->euid) && (euid != current->suid))
+ return -EPERM;
+ if ((suid != (uid_t) -1) && (suid != current->uid) &&
+ (suid != current->euid) && (suid != current->suid))
+ return -EPERM;
+ }
if (ruid != (uid_t) -1) {
/* See above commentary about NPROC rlimit issues here. */
charge_uid(current, -1);
@@ -634,8 +636,12 @@ asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
if(ruid)
charge_uid(current, 1);
}
- if (euid != (uid_t) -1)
+ if (euid != (uid_t) -1) {
+ if (euid != current->euid)
+ current->dumpable = 0;
current->euid = euid;
+ current->fsuid = euid;
+ }
if (suid != (uid_t) -1)
current->suid = suid;
return 0;
@@ -652,6 +658,46 @@ asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
return retval;
}
+/*
+ * Same as above, but for rgid, egid, sgid.
+ */
+asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
+{
+ if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
+ if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
+ (rgid != current->egid) && (rgid != current->sgid))
+ return -EPERM;
+ if ((egid != (gid_t) -1) && (egid != current->gid) &&
+ (egid != current->egid) && (egid != current->sgid))
+ return -EPERM;
+ if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
+ (sgid != current->egid) && (sgid != current->sgid))
+ return -EPERM;
+ }
+ if (rgid != (gid_t) -1)
+ current->gid = rgid;
+ if (egid != (gid_t) -1) {
+ if (egid != current->egid)
+ current->dumpable = 0;
+ current->egid = egid;
+ current->fsgid = egid;
+ }
+ if (sgid != (gid_t) -1)
+ current->sgid = sgid;
+ return 0;
+}
+
+asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
+{
+ int retval;
+
+ if (!(retval = put_user(current->gid, rgid)) &&
+ !(retval = put_user(current->egid, egid)))
+ retval = put_user(current->sgid, sgid);
+
+ return retval;
+}
+
/*
* "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index e4bdcfc1a..205190e9a 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -16,7 +16,6 @@
#include <linux/mm.h>
#include <linux/sysctl.h>
#include <linux/swapctl.h>
-#include <linux/nametrans.h>
#include <linux/proc_fs.h>
#include <linux/malloc.h>
#include <linux/stat.h>
@@ -103,6 +102,7 @@ struct inode_operations proc_sys_inode_operations =
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
+ NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
@@ -171,10 +171,6 @@ static ctl_table kern_table[] = {
{KERN_JAVA_APPLETVIEWER, "java-appletviewer", binfmt_java_appletviewer,
64, 0644, NULL, &proc_dostring, &sysctl_string },
#endif
-#ifdef CONFIG_TRANS_NAMES
- {KERN_NAMETRANS, "nametrans", nametrans_txt, MAX_DEFAULT_TRANSLEN,
- 0644, NULL, &nametrans_dostring, &nametrans_string},
-#endif
#ifdef __sparc__
{KERN_SPARC_REBOOT, "reboot-cmd", reboot_command,
256, 0644, NULL, &proc_dostring, &sysctl_string },
@@ -822,6 +818,12 @@ int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
#else /* CONFIG_PROC_FS */
+int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return -ENOSYS;
+}
+
int proc_dostring(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp)
{
@@ -840,6 +842,12 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
return -ENOSYS;
}
+int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return -ENOSYS;
+}
+
#endif /* CONFIG_PROC_FS */
@@ -1040,6 +1048,12 @@ int proc_dointvec_minmax(ctl_table *table, int write, struct file *filp,
return -ENOSYS;
}
+int proc_dointvec_jiffies(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp)
+{
+ return -ENOSYS;
+}
+
struct ctl_table_header * register_sysctl_table(ctl_table * table,
int insert_at_head)
{