/* * Note that while the flag value (low two bits) for sys_open means: * 00 - read-only * 01 - write-only * 10 - read-write * 11 - special * it is changed into * 00 - no permissions needed * 01 - read-permission * 10 - write-permission * 11 - read-write * for the internal routines (ie open_namei()/follow_link() etc). 00 is * used by symlinks. */ static struct file *do_filp_open(int dfd, const char *filename, int flags, int mode) { int namei_flags, error; struct nameidata nd; namei_flags = flags; if ((namei_flags+1) & O_ACCMODE) namei_flags++; error = open_namei(dfd, filename, namei_flags, mode, &nd); if (!error){ /* if(active_transaction() && !shadow(nd.dentry->d_inode)){ printk(KERN_ERR "Not shadow for file %s, %p\n", filename, &nd.dentry->d_inode); printk(KERN_ERR "Dentry = %p, %p, %p\n", &nd.dentry, nd.dentry, shadow(nd.dentry)); OSA_MAGIC(OSA_BREAKSIM); } KSTM_BUG_ON(active_transaction() && !shadow(nd.dentry->d_inode)); */ return nameidata_to_filp(&nd, flags); } return ERR_PTR(error); }
/* * Note that a shared library must be both readable and executable due to * security reasons. * * Also note that we take the address to load from from the file itself. */ asmlinkage long sys_uselib(const char __user * library) { struct file * file; struct nameidata nd; const struct _inode *inode; int error; error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); if (error) goto out; error = -EACCES; if (nd.mnt->mnt_flags & MNT_NOEXEC) goto exit; error = -EINVAL; inode = d_get_inode_ro(nd.dentry); if (!S_ISREG(inode->i_mode)) goto exit; error = vfs_permission(inode, &nd, MAY_READ | MAY_EXEC); if (error) goto exit; file = nameidata_to_filp(&nd, O_RDONLY); error = PTR_ERR(file); if (IS_ERR(file)) goto out; error = -ENOEXEC; if(file->f_op) { struct linux_binfmt * fmt; read_lock(&binfmt_lock); for (fmt = formats ; fmt ; fmt = fmt->next) { if (!fmt->load_shlib) continue; if (!try_module_get(fmt->module)) continue; read_unlock(&binfmt_lock); error = fmt->load_shlib(file); read_lock(&binfmt_lock); put_binfmt(fmt); if (error != -ENOEXEC) break; } read_unlock(&binfmt_lock); } fput(file); out: return error; exit: release_open_intent(&nd); path_release(&nd); goto out; }
/* * Note that while the flag value (low two bits) for sys_open means: * 00 - read-only * 01 - write-only * 10 - read-write * 11 - special * it is changed into * 00 - no permissions needed * 01 - read-permission * 10 - write-permission * 11 - read-write * for the internal routines (ie open_namei()/follow_link() etc). 00 is * used by symlinks. */ static struct file *do_filp_open(int dfd, const char *filename, int flags, int mode) { int namei_flags, error; struct nameidata nd; namei_flags = flags; if ((namei_flags+1) & O_ACCMODE) namei_flags++; error = open_namei(dfd, filename, namei_flags, mode, &nd); if (!error) return nameidata_to_filp(&nd, flags); return ERR_PTR(error); }