binfmt_script.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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/binfmts.h>
  11. #include <linux/init.h>
  12. #include <linux/file.h>
  13. #include <linux/err.h>
  14. #include <linux/fs.h>
  15. static int load_script(struct linux_binprm *bprm)
  16. {
  17. const char *i_arg, *i_name;
  18. char *cp;
  19. struct file *file;
  20. int retval;
  21. if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
  22. return -ENOEXEC;
  23. /*
  24. * If the script filename will be inaccessible after exec, typically
  25. * because it is a "/dev/fd/<fd>/.." path against an O_CLOEXEC fd, give
  26. * up now (on the assumption that the interpreter will want to load
  27. * this file).
  28. */
  29. if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
  30. return -ENOENT;
  31. /*
  32. * This section does the #! interpretation.
  33. * Sorta complicated, but hopefully it will work. -TYT
  34. */
  35. allow_write_access(bprm->file);
  36. fput(bprm->file);
  37. bprm->file = NULL;
  38. bprm->buf[BINPRM_BUF_SIZE - 1] = '\0';
  39. if ((cp = strchr(bprm->buf, '\n')) == NULL)
  40. cp = bprm->buf+BINPRM_BUF_SIZE-1;
  41. *cp = '\0';
  42. while (cp > bprm->buf) {
  43. cp--;
  44. if ((*cp == ' ') || (*cp == '\t'))
  45. *cp = '\0';
  46. else
  47. break;
  48. }
  49. for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
  50. if (*cp == '\0')
  51. return -ENOEXEC; /* No interpreter name found */
  52. i_name = cp;
  53. i_arg = NULL;
  54. for ( ; *cp && (*cp != ' ') && (*cp != '\t'); cp++)
  55. /* nothing */ ;
  56. while ((*cp == ' ') || (*cp == '\t'))
  57. *cp++ = '\0';
  58. if (*cp)
  59. i_arg = cp;
  60. /*
  61. * OK, we've parsed out the interpreter name and
  62. * (optional) argument.
  63. * Splice in (1) the interpreter's name for argv[0]
  64. * (2) (optional) argument to interpreter
  65. * (3) filename of shell script (replace argv[0])
  66. *
  67. * This is done in reverse order, because of how the
  68. * user environment and arguments are stored.
  69. */
  70. retval = remove_arg_zero(bprm);
  71. if (retval)
  72. return retval;
  73. retval = copy_strings_kernel(1, &bprm->interp, bprm);
  74. if (retval < 0)
  75. return retval;
  76. bprm->argc++;
  77. if (i_arg) {
  78. retval = copy_strings_kernel(1, &i_arg, bprm);
  79. if (retval < 0)
  80. return retval;
  81. bprm->argc++;
  82. }
  83. retval = copy_strings_kernel(1, &i_name, bprm);
  84. if (retval)
  85. return retval;
  86. bprm->argc++;
  87. retval = bprm_change_interp(i_name, bprm);
  88. if (retval < 0)
  89. return retval;
  90. /*
  91. * OK, now restart the process with the interpreter's dentry.
  92. */
  93. file = open_exec(i_name);
  94. if (IS_ERR(file))
  95. return PTR_ERR(file);
  96. bprm->file = file;
  97. retval = prepare_binprm(bprm);
  98. if (retval < 0)
  99. return retval;
  100. return search_binary_handler(bprm);
  101. }
  102. static struct linux_binfmt script_format = {
  103. .module = THIS_MODULE,
  104. .load_binary = load_script,
  105. };
  106. static int __init init_script_binfmt(void)
  107. {
  108. register_binfmt(&script_format);
  109. return 0;
  110. }
  111. static void __exit exit_script_binfmt(void)
  112. {
  113. unregister_binfmt(&script_format);
  114. }
  115. core_initcall(init_script_binfmt);
  116. module_exit(exit_script_binfmt);
  117. MODULE_LICENSE("GPL");