Re: [PATCH] docs: kernel_feat.py: fix command injection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 10 Jan 2024, Vegard Nossum <vegard.nossum@xxxxxxxxxx> wrote:
> The kernel-feat directive passes its argument straight to the shell.
> This is unfortunate and unnecessary.
>
> Let's always use paths relative to $srctree/Documentation/ and use
> subprocess.check_call() instead of subprocess.Popen(shell=True).
>
> This also makes the code shorter.
>
> This is analogous to commit 3231dd586277 ("docs: kernel_abi.py: fix
> command injection") where we did exactly the same thing for
> kernel_abi.py, somehow I completely missed this one.
>
> Link: https://fosstodon.org/@jani/111676532203641247
> Reported-by: Jani Nikula <jani.nikula@xxxxxxxxx>
> Signed-off-by: Vegard Nossum <vegard.nossum@xxxxxxxxxx>

Good stuff, thanks for doing this.

> diff --git a/Documentation/sphinx/kernel_feat.py b/Documentation/sphinx/kernel_feat.py
> index b5fa2f0542a5..b9df61eb4501 100644
> --- a/Documentation/sphinx/kernel_feat.py
> +++ b/Documentation/sphinx/kernel_feat.py
> @@ -37,8 +37,6 @@ import re
>  import subprocess
>  import sys
>  
> -from os import path
> -
>  from docutils import nodes, statemachine
>  from docutils.statemachine import ViewList
>  from docutils.parsers.rst import directives, Directive
> @@ -76,33 +74,26 @@ class KernelFeat(Directive):
>          self.state.document.settings.env.app.warn(message, prefix="")
>  
>      def run(self):
> -
>          doc = self.state.document
>          if not doc.settings.file_insertion_enabled:
>              raise self.warning("docutils: file insertion disabled")
>  
>          env = doc.settings.env
> -        cwd = path.dirname(doc.current_source)
> -        cmd = "get_feat.pl rest --enable-fname --dir "
> -        cmd += self.arguments[0]
> -
> -        if len(self.arguments) > 1:
> -            cmd += " --arch " + self.arguments[1]
>  
> -        srctree = path.abspath(os.environ["srctree"])
> +        srctree = os.path.abspath(os.environ["srctree"])

As a follow-up, please replace the srctree environment variable with

        srctree = os.path.join(env.srcdir, '..')

or something like that. env.srcdir points at the Documentation
directory.

Ditto for the kernel_abi.py extension.

> -        fname = cmd
> +        args = [
> +            os.path.join(srctree, 'scripts/get_feat.pl'),
> +            'rest',
> +            '--enable-fname',
> +            '--dir',
> +            os.path.join(srctree, 'Documentation', self.arguments[0]),
> +        ]
>  
> -        # extend PATH with $(srctree)/scripts
> -        path_env = os.pathsep.join([
> -            srctree + os.sep + "scripts",
> -            os.environ["PATH"]
> -        ])
> -        shell_env = os.environ.copy()
> -        shell_env["PATH"]    = path_env
> -        shell_env["srctree"] = srctree
> +        if len(self.arguments) > 1:
> +            args.extend(['--arch', self.arguments[1]])
>  
> -        lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
> +        lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')

Another nice cleanup might be to always run the tools in the top level
directory instead of changing the cwd. Like, we don't change he working
directory for the compiler either.

BR,
Jani.

>  
>          line_regex = re.compile(r"^\.\. FILE (\S+)$")
>  
> @@ -121,30 +112,6 @@ class KernelFeat(Directive):
>          nodeList = self.nestedParse(out_lines, fname)
>          return nodeList
>  
> -    def runCmd(self, cmd, **kwargs):
> -        u"""Run command ``cmd`` and return its stdout as unicode."""
> -
> -        try:
> -            proc = subprocess.Popen(
> -                cmd
> -                , stdout = subprocess.PIPE
> -                , stderr = subprocess.PIPE
> -                , **kwargs
> -            )
> -            out, err = proc.communicate()
> -
> -            out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8')
> -
> -            if proc.returncode != 0:
> -                raise self.severe(
> -                    u"command '%s' failed with return code %d"
> -                    % (cmd, proc.returncode)
> -                )
> -        except OSError as exc:
> -            raise self.severe(u"problems with '%s' directive: %s."
> -                              % (self.name, ErrorString(exc)))
> -        return out
> -
>      def nestedParse(self, lines, fname):
>          content = ViewList()
>          node    = nodes.section()

-- 
Jani Nikula, Intel




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux