Merge with Linux 2.5.48.
[linux-2.6/linux-mips.git] / fs / binfmt_misc.c
blobc549fd26ed09431e33fe763cd72ae0226e9e92df
1 /*
2 * binfmt_misc.c
4 * Copyright (C) 1997 Richard Günther
6 * binfmt_misc detects binaries via a magic or filename extension and invokes
7 * a specified wrapper. This should obsolete binfmt_java, binfmt_em86 and
8 * binfmt_mz.
10 * 1997-04-25 first version
11 * [...]
12 * 1997-05-19 cleanup
13 * 1997-06-26 hpa: pass the real filename rather than argv[0]
14 * 1997-06-30 minor cleanup
15 * 1997-08-09 removed extension stripping, locking cleanup
16 * 2001-02-28 AV: rewritten into something that resembles C. Original didn't.
19 #include <linux/module.h>
20 #include <linux/init.h>
22 #include <linux/binfmts.h>
23 #include <linux/slab.h>
24 #include <linux/ctype.h>
25 #include <linux/file.h>
26 #include <linux/pagemap.h>
27 #include <linux/namei.h>
28 #include <linux/mount.h>
30 #include <asm/uaccess.h>
32 enum {
33 VERBOSE_STATUS = 1 /* make it zero to save 400 bytes kernel memory */
36 static LIST_HEAD(entries);
37 static int enabled = 1;
39 enum {Enabled, Magic};
40 #define MISC_FMT_PRESERVE_ARGV0 (1<<31)
42 typedef struct {
43 struct list_head list;
44 unsigned long flags; /* type, status, etc. */
45 int offset; /* offset of magic */
46 int size; /* size of magic/mask */
47 char *magic; /* magic or filename extension */
48 char *mask; /* mask, NULL for exact match */
49 char *interpreter; /* filename of interpreter */
50 char *name;
51 struct dentry *dentry;
52 } Node;
54 static rwlock_t entries_lock __attribute__((unused)) = RW_LOCK_UNLOCKED;
55 static struct vfsmount *bm_mnt;
56 static int entry_count = 0;
58 /*
59 * Check if we support the binfmt
60 * if we do, return the node, else NULL
61 * locking is done in load_misc_binary
63 static Node *check_file(struct linux_binprm *bprm)
65 char *p = strrchr(bprm->filename, '.');
66 struct list_head *l;
68 list_for_each(l, &entries) {
69 Node *e = list_entry(l, Node, list);
70 char *s;
71 int j;
73 if (!test_bit(Enabled, &e->flags))
74 continue;
76 if (!test_bit(Magic, &e->flags)) {
77 if (p && !strcmp(e->magic, p + 1))
78 return e;
79 continue;
82 s = bprm->buf + e->offset;
83 if (e->mask) {
84 for (j = 0; j < e->size; j++)
85 if ((*s++ ^ e->magic[j]) & e->mask[j])
86 break;
87 } else {
88 for (j = 0; j < e->size; j++)
89 if ((*s++ ^ e->magic[j]))
90 break;
92 if (j == e->size)
93 return e;
95 return NULL;
99 * the loader itself
101 static int load_misc_binary(struct linux_binprm *bprm, struct pt_regs *regs)
103 Node *fmt;
104 struct file * file;
105 char iname[BINPRM_BUF_SIZE];
106 char *iname_addr = iname;
107 int retval;
109 retval = -ENOEXEC;
110 if (!enabled)
111 goto _ret;
113 /* to keep locking time low, we copy the interpreter string */
114 read_lock(&entries_lock);
115 fmt = check_file(bprm);
116 if (fmt) {
117 strncpy(iname, fmt->interpreter, BINPRM_BUF_SIZE - 1);
118 iname[BINPRM_BUF_SIZE - 1] = '\0';
120 read_unlock(&entries_lock);
121 if (!fmt)
122 goto _ret;
124 allow_write_access(bprm->file);
125 fput(bprm->file);
126 bprm->file = NULL;
128 /* Build args for interpreter */
129 if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
130 remove_arg_zero(bprm);
132 retval = copy_strings_kernel(1, &bprm->filename, bprm);
133 if (retval < 0) goto _ret;
134 bprm->argc++;
135 retval = copy_strings_kernel(1, &iname_addr, bprm);
136 if (retval < 0) goto _ret;
137 bprm->argc++;
138 bprm->filename = iname; /* for binfmt_script */
140 file = open_exec(iname);
141 retval = PTR_ERR(file);
142 if (IS_ERR(file))
143 goto _ret;
144 bprm->file = file;
146 retval = prepare_binprm(bprm);
147 if (retval >= 0)
148 retval = search_binary_handler(bprm, regs);
149 _ret:
150 return retval;
153 /* Command parsers */
156 * parses and copies one argument enclosed in del from *sp to *dp,
157 * recognising the \x special.
158 * returns pointer to the copied argument or NULL in case of an
159 * error (and sets err) or null argument length.
161 static char *scanarg(char *s, char del)
163 char c;
165 while ((c = *s++) != del) {
166 if (c == '\\' && *s == 'x') {
167 s++;
168 if (!isxdigit(*s++))
169 return NULL;
170 if (!isxdigit(*s++))
171 return NULL;
174 return s;
177 static int unquote(char *from)
179 char c = 0, *s = from, *p = from;
181 while ((c = *s++) != '\0') {
182 if (c == '\\' && *s == 'x') {
183 s++;
184 c = toupper(*s++);
185 *p = (c - (isdigit(c) ? '0' : 'A' - 10)) << 4;
186 c = toupper(*s++);
187 *p++ |= c - (isdigit(c) ? '0' : 'A' - 10);
188 continue;
190 *p++ = c;
192 return p - from;
196 * This registers a new binary format, it recognises the syntax
197 * ':name:type:offset:magic:mask:interpreter:'
198 * where the ':' is the IFS, that can be chosen with the first char
200 static Node *create_entry(const char *buffer, size_t count)
202 Node *e;
203 int memsize, err;
204 char *buf, *p;
205 char del;
207 /* some sanity checks */
208 err = -EINVAL;
209 if ((count < 11) || (count > 256))
210 goto out;
212 err = -ENOMEM;
213 memsize = sizeof(Node) + count + 8;
214 e = (Node *) kmalloc(memsize, GFP_USER);
215 if (!e)
216 goto out;
218 p = buf = (char *)e + sizeof(Node);
220 memset(e, 0, sizeof(Node));
221 if (copy_from_user(buf, buffer, count))
222 goto Efault;
224 del = *p++; /* delimeter */
226 memset(buf+count, del, 8);
228 e->name = p;
229 p = strchr(p, del);
230 if (!p)
231 goto Einval;
232 *p++ = '\0';
233 if (!e->name[0] ||
234 !strcmp(e->name, ".") ||
235 !strcmp(e->name, "..") ||
236 strchr(e->name, '/'))
237 goto Einval;
238 switch (*p++) {
239 case 'E': e->flags = 1<<Enabled; break;
240 case 'M': e->flags = (1<<Enabled) | (1<<Magic); break;
241 default: goto Einval;
243 if (*p++ != del)
244 goto Einval;
245 if (test_bit(Magic, &e->flags)) {
246 char *s = strchr(p, del);
247 if (!s)
248 goto Einval;
249 *s++ = '\0';
250 e->offset = simple_strtoul(p, &p, 10);
251 if (*p++)
252 goto Einval;
253 e->magic = p;
254 p = scanarg(p, del);
255 if (!p)
256 goto Einval;
257 p[-1] = '\0';
258 if (!e->magic[0])
259 goto Einval;
260 e->mask = p;
261 p = scanarg(p, del);
262 if (!p)
263 goto Einval;
264 p[-1] = '\0';
265 if (!e->mask[0])
266 e->mask = NULL;
267 e->size = unquote(e->magic);
268 if (e->mask && unquote(e->mask) != e->size)
269 goto Einval;
270 if (e->size + e->offset > BINPRM_BUF_SIZE)
271 goto Einval;
272 } else {
273 p = strchr(p, del);
274 if (!p)
275 goto Einval;
276 *p++ = '\0';
277 e->magic = p;
278 p = strchr(p, del);
279 if (!p)
280 goto Einval;
281 *p++ = '\0';
282 if (!e->magic[0] || strchr(e->magic, '/'))
283 goto Einval;
284 p = strchr(p, del);
285 if (!p)
286 goto Einval;
287 *p++ = '\0';
289 e->interpreter = p;
290 p = strchr(p, del);
291 if (!p)
292 goto Einval;
293 *p++ = '\0';
294 if (!e->interpreter[0])
295 goto Einval;
297 if (*p == 'P') {
298 p++;
299 e->flags |= MISC_FMT_PRESERVE_ARGV0;
302 if (*p == '\n')
303 p++;
304 if (p != buf + count)
305 goto Einval;
306 return e;
308 out:
309 return ERR_PTR(err);
311 Efault:
312 kfree(e);
313 return ERR_PTR(-EFAULT);
314 Einval:
315 kfree(e);
316 return ERR_PTR(-EINVAL);
320 * Set status of entry/binfmt_misc:
321 * '1' enables, '0' disables and '-1' clears entry/binfmt_misc
323 static int parse_command(const char *buffer, size_t count)
325 char s[4];
327 if (!count)
328 return 0;
329 if (count > 3)
330 return -EINVAL;
331 if (copy_from_user(s, buffer, count))
332 return -EFAULT;
333 if (s[count-1] == '\n')
334 count--;
335 if (count == 1 && s[0] == '0')
336 return 1;
337 if (count == 1 && s[0] == '1')
338 return 2;
339 if (count == 2 && s[0] == '-' && s[1] == '1')
340 return 3;
341 return -EINVAL;
344 /* generic stuff */
346 static void entry_status(Node *e, char *page)
348 char *dp;
349 char *status = "disabled";
351 if (test_bit(Enabled, &e->flags))
352 status = "enabled";
354 if (!VERBOSE_STATUS) {
355 sprintf(page, "%s\n", status);
356 return;
359 sprintf(page, "%s\ninterpreter %s\n", status, e->interpreter);
360 dp = page + strlen(page);
361 if (!test_bit(Magic, &e->flags)) {
362 sprintf(dp, "extension .%s\n", e->magic);
363 } else {
364 int i;
366 sprintf(dp, "offset %i\nmagic ", e->offset);
367 dp = page + strlen(page);
368 for (i = 0; i < e->size; i++) {
369 sprintf(dp, "%02x", 0xff & (int) (e->magic[i]));
370 dp += 2;
372 if (e->mask) {
373 sprintf(dp, "\nmask ");
374 dp += 6;
375 for (i = 0; i < e->size; i++) {
376 sprintf(dp, "%02x", 0xff & (int) (e->mask[i]));
377 dp += 2;
380 *dp++ = '\n';
381 *dp = '\0';
385 static struct inode *bm_get_inode(struct super_block *sb, int mode)
387 struct inode * inode = new_inode(sb);
389 if (inode) {
390 inode->i_mode = mode;
391 inode->i_uid = 0;
392 inode->i_gid = 0;
393 inode->i_blksize = PAGE_CACHE_SIZE;
394 inode->i_blocks = 0;
395 inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
397 return inode;
400 static void bm_clear_inode(struct inode *inode)
402 Node *e = inode->u.generic_ip;
404 if (e) {
405 struct vfsmount *mnt;
406 write_lock(&entries_lock);
407 list_del(&e->list);
408 mnt = bm_mnt;
409 if (!--entry_count)
410 bm_mnt = NULL;
411 write_unlock(&entries_lock);
412 kfree(e);
413 mntput(mnt);
417 static void kill_node(Node *e)
419 struct dentry *dentry;
421 write_lock(&entries_lock);
422 dentry = e->dentry;
423 if (dentry) {
424 list_del_init(&e->list);
425 e->dentry = NULL;
427 write_unlock(&entries_lock);
429 if (dentry) {
430 dentry->d_inode->i_nlink--;
431 d_drop(dentry);
432 dput(dentry);
436 /* /<entry> */
438 static ssize_t
439 bm_entry_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
441 Node *e = file->f_dentry->d_inode->u.generic_ip;
442 loff_t pos = *ppos;
443 ssize_t res;
444 char *page;
445 int len;
447 if (!(page = (char*) __get_free_page(GFP_KERNEL)))
448 return -ENOMEM;
450 entry_status(e, page);
451 len = strlen(page);
453 res = -EINVAL;
454 if (pos < 0)
455 goto out;
456 res = 0;
457 if (pos >= len)
458 goto out;
459 if (len < pos + nbytes)
460 nbytes = len - pos;
461 res = -EFAULT;
462 if (copy_to_user(buf, page + pos, nbytes))
463 goto out;
464 *ppos = pos + nbytes;
465 res = nbytes;
466 out:
467 free_page((unsigned long) page);
468 return res;
471 static ssize_t bm_entry_write(struct file *file, const char *buffer,
472 size_t count, loff_t *ppos)
474 struct dentry *root;
475 Node *e = file->f_dentry->d_inode->u.generic_ip;
476 int res = parse_command(buffer, count);
478 switch (res) {
479 case 1: clear_bit(Enabled, &e->flags);
480 break;
481 case 2: set_bit(Enabled, &e->flags);
482 break;
483 case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
484 down(&root->d_inode->i_sem);
486 kill_node(e);
488 up(&root->d_inode->i_sem);
489 dput(root);
490 break;
491 default: return res;
493 return count;
496 static struct file_operations bm_entry_operations = {
497 .read = bm_entry_read,
498 .write = bm_entry_write,
501 static struct file_system_type bm_fs_type;
503 /* /register */
505 static ssize_t bm_register_write(struct file *file, const char *buffer,
506 size_t count, loff_t *ppos)
508 Node *e;
509 struct inode *inode;
510 struct vfsmount *mnt = NULL;
511 struct dentry *root, *dentry;
512 struct super_block *sb = file->f_vfsmnt->mnt_sb;
513 int err = 0;
515 e = create_entry(buffer, count);
517 if (IS_ERR(e))
518 return PTR_ERR(e);
520 root = dget(sb->s_root);
521 down(&root->d_inode->i_sem);
522 dentry = lookup_one_len(e->name, root, strlen(e->name));
523 err = PTR_ERR(dentry);
524 if (IS_ERR(dentry))
525 goto out;
527 err = -EEXIST;
528 if (dentry->d_inode)
529 goto out2;
531 inode = bm_get_inode(sb, S_IFREG | 0644);
533 err = -ENOMEM;
534 if (!inode)
535 goto out2;
537 write_lock(&entries_lock);
538 if (!bm_mnt) {
539 write_unlock(&entries_lock);
540 mnt = kern_mount(&bm_fs_type);
541 if (IS_ERR(mnt)) {
542 err = PTR_ERR(mnt);
543 iput(inode);
544 inode = NULL;
545 goto out2;
547 write_lock(&entries_lock);
548 if (!bm_mnt)
549 bm_mnt = mnt;
551 mntget(bm_mnt);
552 entry_count++;
554 e->dentry = dget(dentry);
555 inode->u.generic_ip = e;
556 inode->i_fop = &bm_entry_operations;
557 d_instantiate(dentry, inode);
559 list_add(&e->list, &entries);
560 write_unlock(&entries_lock);
562 mntput(mnt);
563 err = 0;
564 out2:
565 dput(dentry);
566 out:
567 up(&root->d_inode->i_sem);
568 dput(root);
570 if (err) {
571 kfree(e);
572 return -EINVAL;
574 return count;
577 static struct file_operations bm_register_operations = {
578 .write = bm_register_write,
581 /* /status */
583 static ssize_t
584 bm_status_read(struct file * file, char * buf, size_t nbytes, loff_t *ppos)
586 char *s = enabled ? "enabled" : "disabled";
587 int len = strlen(s);
588 loff_t pos = *ppos;
590 if (pos < 0)
591 return -EINVAL;
592 if (pos >= len)
593 return 0;
594 if (len < pos + nbytes)
595 nbytes = len - pos;
596 if (copy_to_user(buf, s + pos, nbytes))
597 return -EFAULT;
598 *ppos = pos + nbytes;
599 return nbytes;
602 static ssize_t bm_status_write(struct file * file, const char * buffer,
603 size_t count, loff_t *ppos)
605 int res = parse_command(buffer, count);
606 struct dentry *root;
608 switch (res) {
609 case 1: enabled = 0; break;
610 case 2: enabled = 1; break;
611 case 3: root = dget(file->f_vfsmnt->mnt_sb->s_root);
612 down(&root->d_inode->i_sem);
614 while (!list_empty(&entries))
615 kill_node(list_entry(entries.next, Node, list));
617 up(&root->d_inode->i_sem);
618 dput(root);
619 default: return res;
621 return count;
624 static struct file_operations bm_status_operations = {
625 .read = bm_status_read,
626 .write = bm_status_write,
629 /* Superblock handling */
631 static struct super_operations s_ops = {
632 .statfs = simple_statfs,
633 .drop_inode = generic_delete_inode,
634 .clear_inode = bm_clear_inode,
637 static int bm_fill_super(struct super_block * sb, void * data, int silent)
639 struct qstr names[2] = {{.name = "status"}, {.name = "register"}};
640 struct inode * inode;
641 struct dentry * dentry[3];
642 int i;
644 for (i=0; i<sizeof(names)/sizeof(names[0]); i++) {
645 names[i].len = strlen(names[i].name);
646 names[i].hash = full_name_hash(names[i].name, names[i].len);
649 sb->s_blocksize = PAGE_CACHE_SIZE;
650 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
651 sb->s_magic = 0x42494e4d;
652 sb->s_op = &s_ops;
654 inode = bm_get_inode(sb, S_IFDIR | 0755);
655 if (!inode)
656 return -ENOMEM;
657 inode->i_op = &simple_dir_inode_operations;
658 inode->i_fop = &simple_dir_operations;
659 dentry[0] = d_alloc_root(inode);
660 if (!dentry[0]) {
661 iput(inode);
662 return -ENOMEM;
664 dentry[1] = d_alloc(dentry[0], &names[0]);
665 if (!dentry[1])
666 goto out1;
667 dentry[2] = d_alloc(dentry[0], &names[1]);
668 if (!dentry[2])
669 goto out2;
670 inode = bm_get_inode(sb, S_IFREG | 0644);
671 if (!inode)
672 goto out3;
673 inode->i_fop = &bm_status_operations;
674 d_add(dentry[1], inode);
675 inode = bm_get_inode(sb, S_IFREG | 0400);
676 if (!inode)
677 goto out3;
678 inode->i_fop = &bm_register_operations;
679 d_add(dentry[2], inode);
681 sb->s_root = dentry[0];
682 return 0;
684 out3:
685 dput(dentry[2]);
686 out2:
687 dput(dentry[1]);
688 out1:
689 dput(dentry[0]);
690 return -ENOMEM;
693 static struct super_block *bm_get_sb(struct file_system_type *fs_type,
694 int flags, char *dev_name, void *data)
696 return get_sb_single(fs_type, flags, data, bm_fill_super);
699 static struct linux_binfmt misc_format = {
700 .module = THIS_MODULE,
701 .load_binary = load_misc_binary,
704 static struct file_system_type bm_fs_type = {
705 .owner = THIS_MODULE,
706 .name = "binfmt_misc",
707 .get_sb = bm_get_sb,
708 .kill_sb = kill_litter_super,
711 static int __init init_misc_binfmt(void)
713 int err = register_filesystem(&bm_fs_type);
714 if (!err) {
715 err = register_binfmt(&misc_format);
716 if (err)
717 unregister_filesystem(&bm_fs_type);
719 return err;
722 static void __exit exit_misc_binfmt(void)
724 unregister_binfmt(&misc_format);
725 unregister_filesystem(&bm_fs_type);
728 module_init(init_misc_binfmt);
729 module_exit(exit_misc_binfmt);
730 MODULE_LICENSE("GPL");