diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-07-20 14:56:40 +0000 |
commit | e308faf24f68e262d92d294a01ddca7a17e76762 (patch) | |
tree | 22c47cb315811834861f013067878ff664e95abd /arch/mips | |
parent | 30c6397ce63178fcb3e7963ac247f0a03132aca9 (diff) |
Sync with Linux 2.1.46.
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/defconfig | 1 | ||||
-rw-r--r-- | arch/mips/kernel/irixelf.c | 99 | ||||
-rw-r--r-- | arch/mips/kernel/syscall.c | 13 | ||||
-rw-r--r-- | arch/mips/kernel/syscalls.h | 4 | ||||
-rw-r--r-- | arch/mips/kernel/sysirix.c | 287 | ||||
-rw-r--r-- | arch/mips/kernel/sysmips.c | 15 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 23 | ||||
-rw-r--r-- | arch/mips/mm/init.c | 1 |
8 files changed, 268 insertions, 175 deletions
diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 9c6fb9073..099cb8406 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -86,6 +86,7 @@ CONFIG_INET=y # CONFIG_IP_ACCT is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set +# CONFIG_SYN_COOKIES is not set # # (it is safe to leave these untouched) diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index fc0d542fc..dabd91762 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -228,7 +228,7 @@ unsigned long * create_irix_tables(char * p, int argc, int envc, * an ELF header. */ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, - struct inode * interpreter_inode, + struct dentry * interpreter_dentry, unsigned int *interp_load_addr) { struct file * file; @@ -256,8 +256,8 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, if((interp_elf_ex->e_type != ET_EXEC && interp_elf_ex->e_type != ET_DYN) || !elf_check_arch(interp_elf_ex->e_machine) || - (!interpreter_inode->i_op || - !interpreter_inode->i_op->default_file_ops->mmap)){ + (!interpreter_dentry->d_inode->i_op || + !interpreter_dentry->d_inode->i_op->default_file_ops->mmap)) { printk("IRIX interp has bad e_type %d\n", interp_elf_ex->e_type); return 0xffffffff; } @@ -288,7 +288,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, return 0xffffffff; } - retval = read_exec(interpreter_inode, interp_elf_ex->e_phoff, + retval = read_exec(interpreter_dentry, interp_elf_ex->e_phoff, (char *) elf_phdata, sizeof(struct elf_phdr) * interp_elf_ex->e_phnum, 1); @@ -296,7 +296,7 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex, dump_phdrs(elf_phdata, interp_elf_ex->e_phnum); #endif - elf_exec_fileno = open_inode(interpreter_inode, O_RDONLY); + elf_exec_fileno = open_dentry(interpreter_dentry, O_RDONLY); if (elf_exec_fileno < 0) { printk("Could not open IRIX interp inode.\n"); kfree(elf_phdata); @@ -408,8 +408,9 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm) /* First of all, some simple consistency checks */ if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) || !elf_check_arch(ehp->e_machine) || - (!bprm->inode->i_op || !bprm->inode->i_op->default_file_ops || - !bprm->inode->i_op->default_file_ops->mmap)) { + (!bprm->dentry->d_inode->i_op || + !bprm->dentry->d_inode->i_op->default_file_ops || + !bprm->dentry->d_inode->i_op->default_file_ops->mmap)) { return -ENOEXEC; } @@ -435,13 +436,14 @@ static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm) /* Look for an IRIX ELF interpreter. */ static inline int look_for_irix_interpreter(char **name, - struct inode **interpreter_inode, + struct dentry **interpreter_dentry, struct elfhdr *interp_elf_ex, struct elf_phdr *epp, struct linux_binprm *bprm, int pnum) { int i, old_fs; int retval = -EINVAL; + struct dentry *dentry = NULL; *name = NULL; for(i = 0; i < pnum; i++, epp++) { @@ -450,7 +452,7 @@ static inline int look_for_irix_interpreter(char **name, /* It is illegal to have two interpreters for one executable. */ if(*name != NULL) - goto losing; + goto out; *name = (char *) kmalloc((epp->p_filesz + strlen(IRIX_INTERP_PREFIX)), @@ -459,26 +461,31 @@ static inline int look_for_irix_interpreter(char **name, return -ENOMEM; strcpy(*name, IRIX_INTERP_PREFIX); - retval = read_exec(bprm->inode, epp->p_offset, (*name + 16), + retval = read_exec(bprm->dentry, epp->p_offset, (*name + 16), epp->p_filesz, 1); if(retval < 0) - goto losing; + goto out; old_fs = get_fs(); set_fs(get_ds()); - retval = namei(NAM_FOLLOW_LINK, *name, interpreter_inode); + dentry = namei(*name); set_fs(old_fs); - if(retval < 0) - goto losing; + if(IS_ERR(dentry)) { + retval = PTR_ERR(dentry); + goto out; + } - retval = read_exec(*interpreter_inode, 0, bprm->buf, 128, 1); - if(retval < 0) - goto losing; + retval = read_exec(dentry, 0, bprm->buf, 128, 1); + if(retval) + goto dput_and_out; *interp_elf_ex = *((struct elfhdr *) bprm->buf); } + *interpreter_dentry = dentry; return 0; -losing: +dput_and_out: + dput(dentry); +out: kfree(*name); return retval; } @@ -538,7 +545,7 @@ static inline void map_executable(struct file *fp, struct elf_phdr *epp, int pnu } static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp, - struct inode *iino, unsigned int *iladdr, + struct dentry *identry, unsigned int *iladdr, int pnum, int old_fs, unsigned int *eentry) { @@ -554,11 +561,11 @@ static inline int map_interpreter(struct elf_phdr *epp, struct elfhdr *ihp, return -1; set_fs(old_fs); - *eentry = load_irix_interp(ihp, iino, iladdr); + *eentry = load_irix_interp(ihp, identry, iladdr); old_fs = get_fs(); set_fs(get_ds()); - iput(iino); + dput(identry); if(*eentry == 0xffffffff) return -1; @@ -573,7 +580,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, struct pt_regs * regs) { struct elfhdr elf_ex, interp_elf_ex; - struct inode *interpreter_inode; + struct dentry *interpreter_dentry; struct elf_phdr *elf_phdata, *elf_ihdr, *elf_ephdr; unsigned int load_addr, elf_bss, elf_brk; unsigned int elf_entry, interp_load_addr = 0; @@ -599,7 +606,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, if (elf_phdata == NULL) return -ENOMEM; - retval = read_exec(bprm->inode, elf_ex.e_phoff, (char *) elf_phdata, + retval = read_exec(bprm->dentry, elf_ex.e_phoff, (char *) elf_phdata, elf_ex.e_phentsize * elf_ex.e_phnum, 1); if (retval < 0) { kfree (elf_phdata); @@ -629,7 +636,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, elf_bss = 0; elf_brk = 0; - elf_exec_fileno = open_inode(bprm->inode, O_RDONLY); + elf_exec_fileno = open_dentry(bprm->dentry, O_RDONLY); if (elf_exec_fileno < 0) { kfree (elf_phdata); @@ -642,7 +649,8 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, end_code = 0; end_data = 0; - retval = look_for_irix_interpreter(&elf_interpreter, &interpreter_inode, + retval = look_for_irix_interpreter(&elf_interpreter, + &interpreter_dentry, &interp_elf_ex, elf_phdata, bprm, elf_ex.e_phnum); if(retval) { @@ -703,7 +711,7 @@ static inline int do_load_irix_binary(struct linux_binprm * bprm, if(elf_interpreter) { retval = map_interpreter(elf_phdata, &interp_elf_ex, - interpreter_inode, &interp_load_addr, + interpreter_dentry, &interp_load_addr, elf_ex.e_phnum, old_fs, &elf_entry); kfree(elf_interpreter); if(retval) { @@ -795,7 +803,8 @@ static inline int do_load_irix_library(int fd) struct file * file; struct elfhdr elf_ex; struct elf_phdr *elf_phdata = NULL; - struct inode * inode; + struct dentry *dentry; + struct inode *inode; unsigned int len; int elf_bss; int retval; @@ -805,7 +814,8 @@ static inline int do_load_irix_library(int fd) len = 0; file = current->files->fd[fd]; - inode = file->f_inode; + dentry = file->f_dentry; + inode = dentry->d_inode; elf_bss = 0; if (!file || !file->f_op) @@ -831,7 +841,8 @@ static inline int do_load_irix_library(int fd) /* First of all, some simple consistency checks. */ if(elf_ex.e_type != ET_EXEC || elf_ex.e_phnum > 2 || !elf_check_arch(elf_ex.e_machine) || - (!inode->i_op || !inode->i_op->default_file_ops->mmap)) + (!dentry->d_inode->i_op || + !dentry->d_inode->i_op->default_file_ops->mmap)) return -ENOEXEC; /* Now read in all of the header information. */ @@ -843,7 +854,7 @@ static inline int do_load_irix_library(int fd) if (elf_phdata == NULL) return -ENOMEM; - retval = read_exec(inode, elf_ex.e_phoff, (char *) elf_phdata, + retval = read_exec(dentry, elf_ex.e_phoff, (char *) elf_phdata, sizeof(struct elf_phdr) * elf_ex.e_phnum, 1); j = 0; @@ -973,14 +984,13 @@ unsigned long irix_mapelf(int fd, struct elf_phdr *user_phdrp, int cnt) */ static int dump_write(struct file *file, const void *addr, int nr) { - file->f_inode->i_status |= ST_MODIFIED; - return file->f_op->write(file->f_inode, file, addr, nr) == nr; + return file->f_op->write(file->f_dentry->d_inode, file, addr, nr) == nr; } static int dump_seek(struct file *file, off_t off) { if (file->f_op->llseek) { - if (file->f_op->llseek(file->f_inode, file, off, 0) != off) + if (file->f_op->llseek(file->f_dentry->d_inode, file, off, 0) != off) return 0; } else file->f_pos = off; @@ -1071,6 +1081,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs) { int has_dumped = 0; struct file file; + struct dentry *dentry; struct inode *inode; unsigned short fs; char corefile[6+sizeof(current->comm)]; @@ -1138,30 +1149,24 @@ static int irix_core_dump(long signr, struct pt_regs * regs) fs = get_fs(); set_fs(KERNEL_DS); - memcpy(corefile,"core.",5); + memcpy(corefile,"core.", 5); #if 0 memcpy(corefile+5,current->comm,sizeof(current->comm)); #else corefile[4] = '\0'; #endif - if (open_namei(corefile,O_CREAT | 2 | O_TRUNC,0600,&inode,NULL)) { + dentry = open_namei(corefile, O_CREAT | 2 | O_TRUNC, 0600); + if (IS_ERR(dentry)) { inode = NULL; goto end_coredump; } + inode = dentry->d_inode; if (!S_ISREG(inode->i_mode)) goto end_coredump; if (!inode->i_op || !inode->i_op->default_file_ops) goto end_coredump; - file.f_mode = 3; - file.f_flags = 0; - file.f_count = 1; - file.f_inode = inode; - file.f_pos = 0; - file.f_reada = 0; - file.f_op = inode->i_op->default_file_ops; - if (file.f_op->open) - if (file.f_op->open(inode,&file)) - goto end_coredump; + if (init_private_file(&file, dentry, 3)) + goto end_coredump; if (!file.f_op->write) goto close_coredump; has_dumped = 1; @@ -1330,11 +1335,11 @@ static int irix_core_dump(long signr, struct pt_regs * regs) close_coredump: if (file.f_op->release) - file.f_op->release(inode,&file); + file.f_op->release(inode, &file); end_coredump: set_fs(fs); - iput(inode); + dput(dentry); #ifndef CONFIG_BINFMT_ELF MOD_DEC_USE_COUNT; #endif diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c index 2faf604c7..f1b117a63 100644 --- a/arch/mips/kernel/syscall.c +++ b/arch/mips/kernel/syscall.c @@ -131,20 +131,21 @@ asmlinkage int sys_clone(struct pt_regs *regs) */ asmlinkage int sys_execve(struct pt_regs *regs) { - int res; + int error; char * filename; lock_kernel(); - res = getname((char *) (long)regs->regs[4], &filename); - if (res) + filename = getname((char *) (long)regs->regs[4]); + error = PTR_ERR(filename); + if (IS_ERR(filename)) goto out; - res = do_execve(filename, (char **) (long)regs->regs[5], - (char **) (long)regs->regs[6], regs); + error = do_execve(filename, (char **) (long)regs->regs[5], + (char **) (long)regs->regs[6], regs); putname(filename); out: unlock_kernel(); - return res; + return error; } /* diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index b8fc556fa..66d66ce5b 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: syscalls.h,v 1.3 1997/06/20 09:48:49 ralf Exp $ + * $Id: syscalls.h,v 1.4 1997/06/25 20:07:40 ralf Exp $ */ /* @@ -208,3 +208,5 @@ SYS(sys_getresuid, 3) SYS(sys_query_module, 5) SYS(sys_poll, 3) SYS(sys_nfsservctl, 3) +SYS(sys_setresgid, 3) /* 4190 */ +SYS(sys_getresgid, 3) diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 95a0dc1c6..e87e5084b 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c @@ -1,4 +1,4 @@ -/* $Id: sysirix.c,v 1.14 1996/07/14 01:59:51 dm Exp $ +/* $Id: sysirix.c,v 1.4 1997/07/19 19:03:18 root Exp $ * sysirix.c: IRIX system call emulation. * * Copyright (C) 1996 David S. Miller @@ -652,6 +652,7 @@ struct irix_statfs { asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf, int len, int fs_type) { + struct dentry *dentry; struct inode *inode; struct statfs kbuf; int error, old_fs, i; @@ -664,20 +665,19 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf, error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs)); if (error) goto out; - error = namei(NAM_FOLLOW_LINK, path, &inode); - if (error) - goto out; - if (!inode->i_sb->s_op->statfs) { - iput(inode); - error = -ENOSYS; + dentry = namei(path); + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) goto out; - } + inode = dentry->d_inode; old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto dput_and_out; - iput(inode); __put_user(kbuf.f_type, &buf->f_type); __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); @@ -691,6 +691,8 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf, } error = 0; +dput_and_out: + dput(dentry); out: unlock_kernel(); return error; @@ -698,7 +700,8 @@ out: asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf) { - struct inode * inode; + struct dentry *dentry; + struct inode *inode; struct statfs kbuf; struct file *file; int error, old_fs, i; @@ -711,18 +714,29 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf) error = -EBADF; goto out; } - if (!(inode = file->f_inode)) { + if (!(dentry = file->f_dentry)) { + error = -ENOENT; + goto out; + } + if (!(inode = dentry->d_inode)) { error = -ENOENT; goto out; } + if (!inode->i_sb) { + error = -ENODEV; + goto out; + } if (!inode->i_sb->s_op->statfs) { error = -ENOSYS; goto out; } old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto out; __put_user(kbuf.f_type, &buf->f_type); __put_user(kbuf.f_bsize, &buf->f_bsize); @@ -789,13 +803,14 @@ out: asmlinkage int irix_exec(struct pt_regs *regs) { int error, base = 0; - char * filename; + char *filename; lock_kernel(); if(regs->regs[2] == 1000) base = 1; - error = getname((char *) (long)regs->regs[base + 4], &filename); - if (error) + filename = getname((char *) (long)regs->regs[base + 4]); + error = PTR_ERR(filename); + if (IS_ERR(filename)) goto out; error = do_execve(filename, (char **) (long)regs->regs[base + 5], (char **) 0, regs); @@ -809,13 +824,14 @@ out: asmlinkage int irix_exece(struct pt_regs *regs) { int error, base = 0; - char * filename; + char *filename; lock_kernel(); if(regs->regs[2] == 1000) base = 1; - error = getname((char *) (long)regs->regs[base + 4], &filename); - if (error) + filename = getname((char *) (long)regs->regs[base + 4]); + error = PTR_ERR(filename); + if (IS_ERR(filename)) goto out; error = do_execve(filename, (char **) (long)regs->regs[base + 5], (char **) (long)regs->regs[base + 6], regs); @@ -1380,6 +1396,7 @@ struct irix_statvfs { asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf) { + struct dentry *dentry; struct inode *inode; struct statfs kbuf; int error, old_fs, i; @@ -1390,20 +1407,23 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf) error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); if(error) goto out; - error = namei(NAM_FOLLOW_LINK, fname, &inode); - if(error) - goto out; - if(!inode->i_sb->s_op->statfs) { - iput(inode); - error = -ENOSYS; + dentry = namei(fname); + error = PTR_ERR(dentry); + if(!IS_ERR(dentry)) goto out; - } + inode = dentry->d_inode; + + error = -ENOSYS; + if(!inode->i_sb->s_op->statfs) + goto dput_and_out; old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto dput_and_out; - iput(inode); __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); __put_user(kbuf.f_blocks, &buf->f_blocks); @@ -1426,6 +1446,8 @@ asmlinkage int irix_statvfs(char *fname, struct irix_statvfs *buf) error = 0; +dput_and_out: + dput(dentry); out: unlock_kernel(); return error; @@ -1433,7 +1455,8 @@ out: asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf) { - struct inode * inode; + struct dentry *dentry; + struct inode *inode; struct statfs kbuf; struct file *file; int error, old_fs, i; @@ -1449,7 +1472,11 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf) error = -EBADF; goto out; } - if (!(inode = file->f_inode)) { + if (!(dentry = file->f_dentry)) { + error = -ENOENT; + goto out; + } + if (!(inode = dentry->d_inode)) { error = -ENOENT; goto out; } @@ -1459,8 +1486,11 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf) } old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto out; __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); @@ -1489,26 +1519,28 @@ out: return error; } -#define NOFOLLOW_LINKS NAM_FOLLOW_TRAILSLASH -#define FOLLOW_LINKS NAM_FOLLOW_LINK +#define NOFOLLOW_LINKS 0 +#define FOLLOW_LINKS 1 -static inline int chown_common(char *filename, uid_t user, gid_t group, int follow) +static inline int chown_common(uid_t user, gid_t group, struct dentry *dentry) { struct inode * inode; int error; struct iattr newattrs; - error = namei(follow, filename,&inode); - if (error) - return error; - if (IS_RDONLY(inode)) { - iput(inode); - return -EROFS; - } - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) { - iput(inode); - return -EPERM; - } + error = PTR_ERR(dentry); + if (IS_ERR(dentry)) + goto out; + inode = dentry->d_inode; + + error = -EROFS; + if (IS_RDONLY(inode)) + goto dput_and_out; + + error = -EPERM; + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + goto dput_and_out; + if (user == (uid_t) -1) user = inode->i_uid; if (group == (gid_t) -1) @@ -1534,38 +1566,45 @@ static inline int chown_common(char *filename, uid_t user, gid_t group, int foll newattrs.ia_mode &= ~S_ISGID; newattrs.ia_valid |= ATTR_MODE; } - inode->i_dirt = 1; if (inode->i_sb->dq_op) { inode->i_sb->dq_op->initialize(inode, -1); + error = -EDQUOT; if (inode->i_sb->dq_op->transfer(inode, &newattrs, 0)) - return -EDQUOT; + goto dput_and_out; error = notify_change(inode, &newattrs); if (error) inode->i_sb->dq_op->transfer(inode, &newattrs, 1); } else error = notify_change(inode, &newattrs); - iput(inode); - return(error); + +dput_and_out: + dput(dentry); +out: + return error; } -asmlinkage int irix_chown(char *fname, int uid, int gid) +asmlinkage int irix_chown(const char *filename, int uid, int gid) { int retval; + struct dentry *dentry; lock_kernel(); /* Do follow any and all links... */ - retval = chown_common(fname, uid, gid, FOLLOW_LINKS); + dentry = namei(filename); + retval = chown_common(uid, gid, dentry); unlock_kernel(); return retval; } -asmlinkage int irix_lchown(char *fname, int uid, int gid) +asmlinkage int irix_lchown(const char *filename, int uid, int gid) { int retval; + struct dentry *dentry; lock_kernel(); /* Do _not_ follow any links... */ - retval = chown_common(fname, uid, gid, NOFOLLOW_LINKS); + dentry = lnamei(filename); + retval = chown_common(uid, gid, dentry); unlock_kernel(); return retval; } @@ -1722,6 +1761,7 @@ struct irix_statvfs64 { asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf) { + struct dentry *dentry; struct inode *inode; struct statfs kbuf; int error, old_fs, i; @@ -1731,20 +1771,22 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf) error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs)); if(error) goto out; - error = namei(NAM_FOLLOW_LINK, fname, &inode); - if(error) - goto out; - if(!inode->i_sb->s_op->statfs) { - iput(inode); - error = -ENOSYS; + dentry = namei(fname); + error = PTR_ERR(dentry); + if(IS_ERR(dentry)) goto out; - } + error = -ENOSYS; + inode = dentry->d_inode; + if(!inode->i_sb->s_op->statfs) + goto dput_and_out; old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto dput_and_out; - iput(inode); __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); __put_user(kbuf.f_blocks, &buf->f_blocks); @@ -1767,6 +1809,8 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf) error = 0; +dput_and_out: + dput(dentry); out: unlock_kernel(); return error; @@ -1774,7 +1818,8 @@ out: asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf) { - struct inode * inode; + struct dentry *dentry; + struct inode *inode; struct statfs kbuf; struct file *file; int error, old_fs, i; @@ -1790,7 +1835,11 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf) error = -EBADF; goto out; } - if (!(inode = file->f_inode)) { + if (!(dentry = file->f_dentry)) { + error = -ENOENT; + goto out; + } + if (!(inode = dentry->d_inode)) { error = -ENOENT; goto out; } @@ -1800,8 +1849,11 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf) } old_fs = get_fs(); set_fs(get_ds()); - inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, sizeof(struct statfs)); + error = inode->i_sb->s_op->statfs(inode->i_sb, &kbuf, + sizeof(struct statfs)); set_fs(old_fs); + if (error) + goto out; __put_user(kbuf.f_bsize, &buf->f_bsize); __put_user(kbuf.f_frsize, &buf->f_frsize); @@ -1927,6 +1979,8 @@ out: asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob) { struct file *file; + struct dentry *dentry; + struct inode *inode; struct irix_dirent32 *lastdirent; struct irix_dirent32_callback buf; int error; @@ -1936,25 +1990,34 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count printk("[%s:%d] ngetdents(%d, %p, %d, %p) ", current->comm, current->pid, fd, dirent, count, eob); #endif - if (fd >= NR_OPEN || !(file = current->files->fd[fd])) { - error = -EBADF; + error = -EBADF; + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) goto out; - } - if (!file->f_op || !file->f_op->readdir) { - error = -ENOTDIR; + + dentry = file->f_dentry; + if (!dentry) goto out; - } - if(verify_area(VERIFY_WRITE, dirent, count) || - verify_area(VERIFY_WRITE, eob, sizeof(*eob))) { - error = -EFAULT; + + inode = dentry->d_inode; + if (!inode) goto out; - } + + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + + error = -EFAULT; + if(!access_ok(VERIFY_WRITE, dirent, count) || + !access_ok(VERIFY_WRITE, eob, sizeof(*eob))) + goto out; + __put_user(0, eob); buf.current_dir = (struct irix_dirent32 *) dirent; buf.previous = NULL; buf.count = count; buf.error = 0; - error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir32); + + error = file->f_op->readdir(inode, file, &buf, irix_filldir32); if (error < 0) goto out; lastdirent = buf.previous; @@ -2027,6 +2090,8 @@ out: asmlinkage int irix_getdents64(int fd, void *dirent, int cnt) { struct file *file; + struct dentry *dentry; + struct inode *inode; struct irix_dirent64 *lastdirent; struct irix_dirent64_callback buf; int error; @@ -2036,28 +2101,35 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt) printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm, current->pid, fd, dirent, cnt); #endif - if (fd >= NR_OPEN || !(file = current->files->fd[fd])) { - error = -EBADF; + error = -EBADF; + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) goto out; - } - if (!file->f_op || !file->f_op->readdir) { - error = -ENOTDIR; + + dentry = file->f_dentry; + if (!dentry) goto out; - } - if(verify_area(VERIFY_WRITE, dirent, cnt)) { - error = -EFAULT; + + inode = dentry->d_inode; + if (!inode) goto out; - } - if(cnt < (sizeof(struct irix_dirent64) + 255)) { - error = -EINVAL; + + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + + error = -EFAULT; + if(!access_ok(VERIFY_WRITE, dirent, cnt)) + goto out; + + error = -EINVAL; + if(cnt < (sizeof(struct irix_dirent64) + 255)) goto out; - } buf.curr = (struct irix_dirent64 *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; - error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir64); + error = file->f_op->readdir(inode, file, &buf, irix_filldir64); if (error < 0) goto out; lastdirent = buf.previous; @@ -2079,6 +2151,8 @@ out: asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob) { struct file *file; + struct dentry *dentry; + struct inode *inode; struct irix_dirent64 *lastdirent; struct irix_dirent64_callback buf; int error; @@ -2088,30 +2162,37 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob) printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm, current->pid, fd, dirent, cnt); #endif - if (fd >= NR_OPEN || !(file = current->files->fd[fd])) { - error = -EBADF; + error = -EBADF; + if (fd >= NR_OPEN || !(file = current->files->fd[fd])) goto out; - } - if (!file->f_op || !file->f_op->readdir) { - error = -ENOTDIR; + + dentry = file->f_dentry; + if (!dentry) goto out; - } - if(verify_area(VERIFY_WRITE, dirent, cnt) || - verify_area(VERIFY_WRITE, eob, sizeof(*eob))) { - error = -EFAULT; + + inode = dentry->d_inode; + if (!inode) goto out; - } - if(cnt < (sizeof(struct irix_dirent64) + 255)) { - error = -EINVAL; + + error = -ENOTDIR; + if (!file->f_op || !file->f_op->readdir) + goto out; + + error = -EFAULT; + if(!access_ok(VERIFY_WRITE, dirent, cnt) || + !access_ok(VERIFY_WRITE, eob, sizeof(*eob))) + goto out; + + error = -EINVAL; + if(cnt < (sizeof(struct irix_dirent64) + 255)) goto out; - } *eob = 0; buf.curr = (struct irix_dirent64 *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; - error = file->f_op->readdir(file->f_inode, file, &buf, irix_filldir64); + error = file->f_op->readdir(inode, file, &buf, irix_filldir64); if (error < 0) goto out; lastdirent = buf.previous; diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c index ae99466e4..e73598345 100644 --- a/arch/mips/kernel/sysmips.c +++ b/arch/mips/kernel/sysmips.c @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: sysmips.c,v 1.2 1997/06/28 23:26:25 ralf Exp $ + * $Id: sysmips.c,v 1.2 1997/07/01 08:59:08 ralf Exp $ */ #include <linux/errno.h> #include <linux/linkage.h> @@ -57,18 +57,21 @@ sys_sysmips(int cmd, int arg1, int arg2, int arg3) switch(cmd) { case SETNAME: - if (!suser()) { - retval = -EPERM; + retval = -EPERM; + if (!suser()) goto out; - } + name = (char *) arg1; len = strlen_user(name); + + retval = len; if (len < 0) - retval = len; goto out; + + retval = -EINVAL; if (len == 0 || len > __NEW_UTS_LEN) - retval = -EINVAL; goto out; + copy_from_user(system_utsname.nodename, name, len); system_utsname.nodename[len] = '\0'; retval = 0; diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 3ad703b1f..f1ebab648 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -81,17 +81,6 @@ good_area: */ bad_area: up(&mm->mmap_sem); - /* Did we have an exception handler installed? */ - - fixup = search_exception_table(regs->cp0_epc); - if (fixup) { - long new_epc; - new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); - printk(KERN_DEBUG "Exception at [<%lx>] (%lx)\n", - regs->cp0_epc, new_epc); - regs->cp0_epc = new_epc; - goto out; - } if (user_mode(regs)) { tsk->tss.cp0_badvaddr = address; @@ -111,6 +100,18 @@ bad_area: force_sig(SIGSEGV, tsk); goto out; } + + /* Did we have an exception handler installed? */ + fixup = search_exception_table(regs->cp0_epc); + if (fixup) { + long new_epc; + new_epc = fixup_exception(dpf_reg, fixup, regs->cp0_epc); + printk(KERN_DEBUG "%s: Exception at [<%lx>] (%lx)\n", + tsk->comm, regs->cp0_epc, new_epc); + regs->cp0_epc = new_epc; + goto out; + } + /* * Oops. The kernel tried to access some bad page. We'll have to * terminate things with extreme prejudice. diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 7a4b6df4b..b62e571d6 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c @@ -156,7 +156,6 @@ static inline void zeropage(unsigned long page) { flush_page_to_ram(page); - sync_mem(); __zeropage(page); } |