aboutsummaryrefslogtreecommitdiffstats
path: root/fs/binfmt_misc.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-09 03:02:35 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-09 03:02:35 -0400
commit1236d6bb6e19fc72ffc6bbcdeb1bfefe450e54ee (patch)
tree47da3feee8e263e8c9352c85cf518e624be3c211 /fs/binfmt_misc.c
parent750b1a6894ecc9b178c6e3d0a1170122971b2036 (diff)
parent8a5776a5f49812d29fe4b2d0a2d71675c3facf3f (diff)
Merge 4.14-rc4 into staging-next
We want the staging/iio fixes in here as well to handle merge issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/binfmt_misc.c')
-rw-r--r--fs/binfmt_misc.c56
1 files changed, 26 insertions, 30 deletions
diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c
index ce7181ea60fa..2a46762def31 100644
--- a/fs/binfmt_misc.c
+++ b/fs/binfmt_misc.c
@@ -54,7 +54,7 @@ typedef struct {
54 int size; /* size of magic/mask */ 54 int size; /* size of magic/mask */
55 char *magic; /* magic or filename extension */ 55 char *magic; /* magic or filename extension */
56 char *mask; /* mask, NULL for exact match */ 56 char *mask; /* mask, NULL for exact match */
57 char *interpreter; /* filename of interpreter */ 57 const char *interpreter; /* filename of interpreter */
58 char *name; 58 char *name;
59 struct dentry *dentry; 59 struct dentry *dentry;
60 struct file *interp_file; 60 struct file *interp_file;
@@ -131,27 +131,26 @@ static int load_misc_binary(struct linux_binprm *bprm)
131{ 131{
132 Node *fmt; 132 Node *fmt;
133 struct file *interp_file = NULL; 133 struct file *interp_file = NULL;
134 char iname[BINPRM_BUF_SIZE];
135 const char *iname_addr = iname;
136 int retval; 134 int retval;
137 int fd_binary = -1; 135 int fd_binary = -1;
138 136
139 retval = -ENOEXEC; 137 retval = -ENOEXEC;
140 if (!enabled) 138 if (!enabled)
141 goto ret; 139 return retval;
142 140
143 /* to keep locking time low, we copy the interpreter string */ 141 /* to keep locking time low, we copy the interpreter string */
144 read_lock(&entries_lock); 142 read_lock(&entries_lock);
145 fmt = check_file(bprm); 143 fmt = check_file(bprm);
146 if (fmt) 144 if (fmt)
147 strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE); 145 dget(fmt->dentry);
148 read_unlock(&entries_lock); 146 read_unlock(&entries_lock);
149 if (!fmt) 147 if (!fmt)
150 goto ret; 148 return retval;
151 149
152 /* Need to be able to load the file after exec */ 150 /* Need to be able to load the file after exec */
151 retval = -ENOENT;
153 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE) 152 if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
154 return -ENOENT; 153 goto ret;
155 154
156 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) { 155 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
157 retval = remove_arg_zero(bprm); 156 retval = remove_arg_zero(bprm);
@@ -195,22 +194,22 @@ static int load_misc_binary(struct linux_binprm *bprm)
195 bprm->argc++; 194 bprm->argc++;
196 195
197 /* add the interp as argv[0] */ 196 /* add the interp as argv[0] */
198 retval = copy_strings_kernel(1, &iname_addr, bprm); 197 retval = copy_strings_kernel(1, &fmt->interpreter, bprm);
199 if (retval < 0) 198 if (retval < 0)
200 goto error; 199 goto error;
201 bprm->argc++; 200 bprm->argc++;
202 201
203 /* Update interp in case binfmt_script needs it. */ 202 /* Update interp in case binfmt_script needs it. */
204 retval = bprm_change_interp(iname, bprm); 203 retval = bprm_change_interp(fmt->interpreter, bprm);
205 if (retval < 0) 204 if (retval < 0)
206 goto error; 205 goto error;
207 206
208 if (fmt->flags & MISC_FMT_OPEN_FILE && fmt->interp_file) { 207 if (fmt->flags & MISC_FMT_OPEN_FILE) {
209 interp_file = filp_clone_open(fmt->interp_file); 208 interp_file = filp_clone_open(fmt->interp_file);
210 if (!IS_ERR(interp_file)) 209 if (!IS_ERR(interp_file))
211 deny_write_access(interp_file); 210 deny_write_access(interp_file);
212 } else { 211 } else {
213 interp_file = open_exec(iname); 212 interp_file = open_exec(fmt->interpreter);
214 } 213 }
215 retval = PTR_ERR(interp_file); 214 retval = PTR_ERR(interp_file);
216 if (IS_ERR(interp_file)) 215 if (IS_ERR(interp_file))
@@ -238,6 +237,7 @@ static int load_misc_binary(struct linux_binprm *bprm)
238 goto error; 237 goto error;
239 238
240ret: 239ret:
240 dput(fmt->dentry);
241 return retval; 241 return retval;
242error: 242error:
243 if (fd_binary > 0) 243 if (fd_binary > 0)
@@ -594,8 +594,13 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode)
594 594
595static void bm_evict_inode(struct inode *inode) 595static void bm_evict_inode(struct inode *inode)
596{ 596{
597 Node *e = inode->i_private;
598
599 if (e->flags & MISC_FMT_OPEN_FILE)
600 filp_close(e->interp_file, NULL);
601
597 clear_inode(inode); 602 clear_inode(inode);
598 kfree(inode->i_private); 603 kfree(e);
599} 604}
600 605
601static void kill_node(Node *e) 606static void kill_node(Node *e)
@@ -603,24 +608,14 @@ static void kill_node(Node *e)
603 struct dentry *dentry; 608 struct dentry *dentry;
604 609
605 write_lock(&entries_lock); 610 write_lock(&entries_lock);
606 dentry = e->dentry; 611 list_del_init(&e->list);
607 if (dentry) {
608 list_del_init(&e->list);
609 e->dentry = NULL;
610 }
611 write_unlock(&entries_lock); 612 write_unlock(&entries_lock);
612 613
613 if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) { 614 dentry = e->dentry;
614 filp_close(e->interp_file, NULL); 615 drop_nlink(d_inode(dentry));
615 e->interp_file = NULL; 616 d_drop(dentry);
616 } 617 dput(dentry);
617 618 simple_release_fs(&bm_mnt, &entry_count);
618 if (dentry) {
619 drop_nlink(d_inode(dentry));
620 d_drop(dentry);
621 dput(dentry);
622 simple_release_fs(&bm_mnt, &entry_count);
623 }
624} 619}
625 620
626/* /<entry> */ 621/* /<entry> */
@@ -665,7 +660,8 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
665 root = file_inode(file)->i_sb->s_root; 660 root = file_inode(file)->i_sb->s_root;
666 inode_lock(d_inode(root)); 661 inode_lock(d_inode(root));
667 662
668 kill_node(e); 663 if (!list_empty(&e->list))
664 kill_node(e);
669 665
670 inode_unlock(d_inode(root)); 666 inode_unlock(d_inode(root));
671 break; 667 break;
@@ -794,7 +790,7 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer,
794 inode_lock(d_inode(root)); 790 inode_lock(d_inode(root));
795 791
796 while (!list_empty(&entries)) 792 while (!list_empty(&entries))
797 kill_node(list_entry(entries.next, Node, list)); 793 kill_node(list_first_entry(&entries, Node, list));
798 794
799 inode_unlock(d_inode(root)); 795 inode_unlock(d_inode(root));
800 break; 796 break;