Commit 3231dd58 authored by Vegard Nossum's avatar Vegard Nossum Committed by Jonathan Corbet
Browse files

docs: kernel_abi.py: fix command injection

The kernel-abi 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.

Link: https://fosstodon.org/@jani/111676532203641247


Reported-by: default avatarJani Nikula <jani.nikula@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarVegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: default avatarJonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/20231231235959.3342928-2-vegard.nossum@oracle.com
parent 5889d6ed
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -7,5 +7,5 @@ marked to be removed at some later point in time.
The description of the interface will document the reason why it is
obsolete and when it can be expected to be removed.

.. kernel-abi:: $srctree/Documentation/ABI/obsolete
.. kernel-abi:: ABI/obsolete
   :rst:
+1 −1
Original line number Diff line number Diff line
ABI removed symbols
===================

.. kernel-abi:: $srctree/Documentation/ABI/removed
.. kernel-abi:: ABI/removed
   :rst:
+1 −1
Original line number Diff line number Diff line
@@ -10,5 +10,5 @@ for at least 2 years.
Most interfaces (like syscalls) are expected to never change and always
be available.

.. kernel-abi:: $srctree/Documentation/ABI/stable
.. kernel-abi:: ABI/stable
   :rst:
+1 −1
Original line number Diff line number Diff line
@@ -16,5 +16,5 @@ Programs that use these interfaces are strongly encouraged to add their
name to the description of these interfaces, so that the kernel
developers can easily notify them if any changes occur.

.. kernel-abi:: $srctree/Documentation/ABI/testing
.. kernel-abi:: ABI/testing
   :rst:
+10 −46
Original line number Diff line number Diff line
@@ -39,8 +39,6 @@ import sys
import re
import kernellog

from os import path

from docutils import nodes, statemachine
from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive
@@ -73,60 +71,26 @@ class KernelCmd(Directive):
    }

    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_abi.pl rest --enable-lineno --dir "
        cmd += self.arguments[0]

        if 'rst' in self.options:
            cmd += " --rst-source"

        srctree = path.abspath(os.environ["srctree"])
        srctree = os.path.abspath(os.environ["srctree"])

        fname = cmd
        args = [
            os.path.join(srctree, 'scripts/get_abi.pl'),
            'rest',
            '--enable-lineno',
            '--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 'rst' in self.options:
            args.append('--rst-source')

        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')
        nodeList = self.nestedParse(lines, self.arguments[0])
        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):
        env = self.state.document.settings.env
        content = ViewList()