Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/fs/binfmt_script.c
15109 views
1
/*
2
* linux/fs/binfmt_script.c
3
*
4
* Copyright (C) 1996 Martin von Löwis
5
* original #!-checking implemented by tytso.
6
*/
7
8
#include <linux/module.h>
9
#include <linux/string.h>
10
#include <linux/stat.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
17
static int load_script(struct linux_binprm *bprm,struct pt_regs *regs)
18
{
19
const char *i_arg, *i_name;
20
char *cp;
21
struct file *file;
22
char interp[BINPRM_BUF_SIZE];
23
int retval;
24
25
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!') ||
26
(bprm->recursion_depth > BINPRM_MAX_RECURSION))
27
return -ENOEXEC;
28
/*
29
* This section does the #! interpretation.
30
* Sorta complicated, but hopefully it will work. -TYT
31
*/
32
33
bprm->recursion_depth++;
34
allow_write_access(bprm->file);
35
fput(bprm->file);
36
bprm->file = NULL;
37
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
strcpy (interp, i_name);
61
/*
62
* OK, we've parsed out the interpreter name and
63
* (optional) argument.
64
* Splice in (1) the interpreter's name for argv[0]
65
* (2) (optional) argument to interpreter
66
* (3) filename of shell script (replace argv[0])
67
*
68
* This is done in reverse order, because of how the
69
* user environment and arguments are stored.
70
*/
71
retval = remove_arg_zero(bprm);
72
if (retval)
73
return retval;
74
retval = copy_strings_kernel(1, &bprm->interp, bprm);
75
if (retval < 0) return retval;
76
bprm->argc++;
77
if (i_arg) {
78
retval = copy_strings_kernel(1, &i_arg, bprm);
79
if (retval < 0) return retval;
80
bprm->argc++;
81
}
82
retval = copy_strings_kernel(1, &i_name, bprm);
83
if (retval) return retval;
84
bprm->argc++;
85
bprm->interp = interp;
86
87
/*
88
* OK, now restart the process with the interpreter's dentry.
89
*/
90
file = open_exec(interp);
91
if (IS_ERR(file))
92
return PTR_ERR(file);
93
94
bprm->file = file;
95
retval = prepare_binprm(bprm);
96
if (retval < 0)
97
return retval;
98
return search_binary_handler(bprm,regs);
99
}
100
101
static struct linux_binfmt script_format = {
102
.module = THIS_MODULE,
103
.load_binary = load_script,
104
};
105
106
static int __init init_script_binfmt(void)
107
{
108
return register_binfmt(&script_format);
109
}
110
111
static void __exit exit_script_binfmt(void)
112
{
113
unregister_binfmt(&script_format);
114
}
115
116
core_initcall(init_script_binfmt);
117
module_exit(exit_script_binfmt);
118
MODULE_LICENSE("GPL");
119
120