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: Jani Nikula <jani.nikula@intel.com>
Cc: stable@vger.kernel.org
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Link: https://lore.kernel.org/r/20231231235959.3342928-2-vegard.nossum@oracle.com
This commit is contained in:
Vegard Nossum 2024-01-01 00:59:59 +01:00 committed by Jonathan Corbet
parent 5889d6ede5
commit 3231dd5862
5 changed files with 14 additions and 50 deletions

View File

@ -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 The description of the interface will document the reason why it is
obsolete and when it can be expected to be removed. obsolete and when it can be expected to be removed.
.. kernel-abi:: $srctree/Documentation/ABI/obsolete .. kernel-abi:: ABI/obsolete
:rst: :rst:

View File

@ -1,5 +1,5 @@
ABI removed symbols ABI removed symbols
=================== ===================
.. kernel-abi:: $srctree/Documentation/ABI/removed .. kernel-abi:: ABI/removed
:rst: :rst:

View File

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

View File

@ -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 name to the description of these interfaces, so that the kernel
developers can easily notify them if any changes occur. developers can easily notify them if any changes occur.
.. kernel-abi:: $srctree/Documentation/ABI/testing .. kernel-abi:: ABI/testing
:rst: :rst:

View File

@ -39,8 +39,6 @@ import sys
import re import re
import kernellog import kernellog
from os import path
from docutils import nodes, statemachine from docutils import nodes, statemachine
from docutils.statemachine import ViewList from docutils.statemachine import ViewList
from docutils.parsers.rst import directives, Directive from docutils.parsers.rst import directives, Directive
@ -73,60 +71,26 @@ class KernelCmd(Directive):
} }
def run(self): def run(self):
doc = self.state.document doc = self.state.document
if not doc.settings.file_insertion_enabled: if not doc.settings.file_insertion_enabled:
raise self.warning("docutils: file insertion disabled") raise self.warning("docutils: file insertion disabled")
env = doc.settings.env srctree = os.path.abspath(os.environ["srctree"])
cwd = path.dirname(doc.current_source)
cmd = "get_abi.pl rest --enable-lineno --dir " args = [
cmd += self.arguments[0] os.path.join(srctree, 'scripts/get_abi.pl'),
'rest',
'--enable-lineno',
'--dir', os.path.join(srctree, 'Documentation', self.arguments[0]),
]
if 'rst' in self.options: if 'rst' in self.options:
cmd += " --rst-source" args.append('--rst-source')
srctree = path.abspath(os.environ["srctree"]) lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8')
fname = cmd
# 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
lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env)
nodeList = self.nestedParse(lines, self.arguments[0]) nodeList = self.nestedParse(lines, self.arguments[0])
return nodeList 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): def nestedParse(self, lines, fname):
env = self.state.document.settings.env env = self.state.document.settings.env
content = ViewList() content = ViewList()