binfmt_script.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. /*
  2. * linux/fs/binfmt_script.c
  3. *
  4. * Copyright (C) 1996 Martin von Löwis
  5. * original #!-checking implemented by tytso.
  6. */
  7. #include <linux/module.h>
  8. #include <linux/string.h>
  9. #include <linux/stat.h>
  10. #include <linux/slab.h>
  11. #include <linux/binfmts.h>
  12. #include <linux/init.h>
  13. #include <linux/file.h>
  14. #include <linux/err.h>
  15. #include <linux/fs.h>
  16. static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
  17. {
  18. char *cp, *i_name, *i_arg;
  19. struct file *file;
  20. char interp[BINPRM_BUF_SIZE];
  21. int retval;
  22. if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') || (bprm->sh_bang))
  23. return -ENOEXEC;
  24. /*
  25. * This section does the #! interpretation.
  26. * Sorta complicated, but hopefully it will work. -TYT
  27. */
  28. bprm->sh_bang++;
  29. allow_write_access(bprm->file);
  30. fput(bprm->file);
  31. bprm->file = NULL;
  32. bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
  33. if ((cp = strchr(bprm->buf, '\n')) == NULL)
  34. cp = bprm->buf+BINPRM_BUF_SIZE-1;
  35. *cp = '\0';
  36. while (cp > bprm->buf) {
  37. cp--;
  38. if ((*cp == ' ') || (*cp == '\t'))
  39. *cp = '\0';
  40. else
  41. break;
  42. }
  43. for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
  44. if (*cp == '\0')
  45. return -ENOEXEC; /* No interpreter name found */
  46. i_name = cp;
  47. i_arg = NULL;
  48. for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++)
  49. /* nothing */ ;
  50. while ((*cp == ' ') || (*cp == '\t'))
  51. *cp++ = '\0';
  52. if (*cp)
  53. i_arg = cp;
  54. strcpy (interp, i_name);
  55. /*
  56. * OK, we've parsed out the interpreter name and
  57. * (optional) argument.
  58. * Splice in (1) the interpreter's name for argv[0]
  59. * (2) (optional) argument to interpreter
  60. * (3) filename of shell script (replace argv[0])
  61. *
  62. * This is done in reverse order, because of how the
  63. * user environment and arguments are stored.
  64. */
  65. retval = remove_arg_zero(bprm);
  66. if (retval)
  67. return retval;
  68. retval = copy_strings_kernel(1, &bprm->interp, bprm);
  69. if (retval < 0) return retval;
  70. bprm->argc++;
  71. if (i_arg) {
  72. retval = copy_strings_kernel(1, &i_arg, bprm);
  73. if (retval < 0) return retval;
  74. bprm->argc++;
  75. }
  76. retval = copy_strings_kernel(1, &i_name, bprm);
  77. if (retval) return retval;
  78. bprm->argc++;
  79. bprm->interp = interp;
  80. /*
  81. * OK, now restart the process with the interpreter's dentry.
  82. */
  83. file = open_exec(interp);
  84. if (IS_ERR(file))
  85. return PTR_ERR(file);
  86. bprm->file = file;
  87. retval = prepare_binprm(bprm);
  88. if (retval < 0)
  89. return retval;
  90. return search_binary_handler(bprm,regs);
  91. }
  92. static struct linux_binfmt script_format = {
  93. .module = THIS_MODULE,
  94. .load_binary = load_script,
  95. };
  96. static int __init init_script_binfmt(void)
  97. {
  98. return register_binfmt(&script_format);
  99. }
  100. static void __exit exit_script_binfmt(void)
  101. {
  102. unregister_binfmt(&script_format);
  103. }
  104. core_initcall(init_script_binfmt);
  105. module_exit(exit_script_binfmt);
  106. MODULE_LICENSE("GPL");