Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'binfmt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/binfmt_misc

Pull binfmt_misc update from James Bottomley:
"This update is to allow architecture emulation containers to function
such that the emulation binary can be housed outside the container
itself. The container and fs parts both have acks from relevant
experts.

To use the new feature you have to add an F option to your binfmt_misc
configuration"

From the docs:
"The usual behaviour of binfmt_misc is to spawn the binary lazily when
the misc format file is invoked. However, this doesn't work very well
in the face of mount namespaces and changeroots, so the F mode opens
the binary as soon as the emulation is installed and uses the opened
image to spawn the emulator, meaning it is always available once
installed, regardless of how the environment changes"

* tag 'binfmt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/binfmt_misc:
binfmt_misc: add F option description to documentation
binfmt_misc: add persistent opened binary handler for containers
fs: add filp_clone_open API

+67 -2
+7
Documentation/binfmt_misc.txt
··· 66 66 This feature should be used with care as the interpreter 67 67 will run with root permissions when a setuid binary owned by root 68 68 is run with binfmt_misc. 69 + 'F' - fix binary. The usual behaviour of binfmt_misc is to spawn the 70 + binary lazily when the misc format file is invoked. However, 71 + this doesn't work very well in the face of mount namespaces and 72 + changeroots, so the F mode opens the binary as soon as the 73 + emulation is installed and uses the opened image to spawn the 74 + emulator, meaning it is always available once installed, 75 + regardless of how the environment changes. 69 76 70 77 71 78 There are some restrictions:
+39 -2
fs/binfmt_misc.c
··· 26 26 #include <linux/fs.h> 27 27 #include <linux/uaccess.h> 28 28 29 + #include "internal.h" 30 + 29 31 #ifdef DEBUG 30 32 # define USE_DEBUG 1 31 33 #else ··· 45 43 #define MISC_FMT_PRESERVE_ARGV0 (1 << 31) 46 44 #define MISC_FMT_OPEN_BINARY (1 << 30) 47 45 #define MISC_FMT_CREDENTIALS (1 << 29) 46 + #define MISC_FMT_OPEN_FILE (1 << 28) 48 47 49 48 typedef struct { 50 49 struct list_head list; ··· 57 54 char *interpreter; /* filename of interpreter */ 58 55 char *name; 59 56 struct dentry *dentry; 57 + struct file *interp_file; 60 58 } Node; 61 59 62 60 static DEFINE_RWLOCK(entries_lock); ··· 205 201 if (retval < 0) 206 202 goto error; 207 203 208 - interp_file = open_exec(iname); 204 + if (fmt->flags & MISC_FMT_OPEN_FILE && fmt->interp_file) { 205 + interp_file = filp_clone_open(fmt->interp_file); 206 + if (!IS_ERR(interp_file)) 207 + deny_write_access(interp_file); 208 + } else { 209 + interp_file = open_exec(iname); 210 + } 209 211 retval = PTR_ERR(interp_file); 210 212 if (IS_ERR(interp_file)) 211 213 goto error; ··· 294 284 open-binary flag */ 295 285 e->flags |= (MISC_FMT_CREDENTIALS | 296 286 MISC_FMT_OPEN_BINARY); 287 + break; 288 + case 'F': 289 + pr_debug("register: flag: F: open interpreter file now\n"); 290 + p++; 291 + e->flags |= MISC_FMT_OPEN_FILE; 297 292 break; 298 293 default: 299 294 cont = 0; ··· 558 543 *dp++ = 'O'; 559 544 if (e->flags & MISC_FMT_CREDENTIALS) 560 545 *dp++ = 'C'; 546 + if (e->flags & MISC_FMT_OPEN_FILE) 547 + *dp++ = 'F'; 561 548 *dp++ = '\n'; 562 549 563 550 if (!test_bit(Magic, &e->flags)) { ··· 606 589 e->dentry = NULL; 607 590 } 608 591 write_unlock(&entries_lock); 592 + 593 + if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) { 594 + filp_close(e->interp_file, NULL); 595 + e->interp_file = NULL; 596 + } 609 597 610 598 if (dentry) { 611 599 drop_nlink(d_inode(dentry)); ··· 718 696 goto out2; 719 697 } 720 698 699 + if (e->flags & MISC_FMT_OPEN_FILE) { 700 + struct file *f; 701 + 702 + f = open_exec(e->interpreter); 703 + if (IS_ERR(f)) { 704 + err = PTR_ERR(f); 705 + pr_notice("register: failed to install interpreter file %s\n", e->interpreter); 706 + simple_release_fs(&bm_mnt, &entry_count); 707 + iput(inode); 708 + inode = NULL; 709 + goto out2; 710 + } 711 + e->interp_file = f; 712 + } 713 + 721 714 e->dentry = dget(dentry); 722 715 inode->i_private = e; 723 716 inode->i_fop = &bm_entry_operations; ··· 750 713 751 714 if (err) { 752 715 kfree(e); 753 - return -EINVAL; 716 + return err; 754 717 } 755 718 return count; 756 719 }
+1
fs/internal.h
··· 111 111 struct file_handle __user *ufh, int open_flag); 112 112 extern int open_check_o_direct(struct file *f); 113 113 extern int vfs_open(const struct path *, struct file *, const struct cred *); 114 + extern struct file *filp_clone_open(struct file *); 114 115 115 116 /* 116 117 * inode.c
+20
fs/open.c
··· 998 998 } 999 999 EXPORT_SYMBOL(file_open_root); 1000 1000 1001 + struct file *filp_clone_open(struct file *oldfile) 1002 + { 1003 + struct file *file; 1004 + int retval; 1005 + 1006 + file = get_empty_filp(); 1007 + if (IS_ERR(file)) 1008 + return file; 1009 + 1010 + file->f_flags = oldfile->f_flags; 1011 + retval = vfs_open(&oldfile->f_path, file, oldfile->f_cred); 1012 + if (retval) { 1013 + put_filp(file); 1014 + return ERR_PTR(retval); 1015 + } 1016 + 1017 + return file; 1018 + } 1019 + EXPORT_SYMBOL(filp_clone_open); 1020 + 1001 1021 long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) 1002 1022 { 1003 1023 struct open_flags op;