Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

authored by

Vegard Nossum and committed by
Jonathan Corbet
3231dd58 5889d6ed

+14 -50
+1 -1
Documentation/admin-guide/abi-obsolete.rst
··· 7 7 The description of the interface will document the reason why it is 8 8 obsolete and when it can be expected to be removed. 9 9 10 - .. kernel-abi:: $srctree/Documentation/ABI/obsolete 10 + .. kernel-abi:: ABI/obsolete 11 11 :rst:
+1 -1
Documentation/admin-guide/abi-removed.rst
··· 1 1 ABI removed symbols 2 2 =================== 3 3 4 - .. kernel-abi:: $srctree/Documentation/ABI/removed 4 + .. kernel-abi:: ABI/removed 5 5 :rst:
+1 -1
Documentation/admin-guide/abi-stable.rst
··· 10 10 Most interfaces (like syscalls) are expected to never change and always 11 11 be available. 12 12 13 - .. kernel-abi:: $srctree/Documentation/ABI/stable 13 + .. kernel-abi:: ABI/stable 14 14 :rst:
+1 -1
Documentation/admin-guide/abi-testing.rst
··· 16 16 name to the description of these interfaces, so that the kernel 17 17 developers can easily notify them if any changes occur. 18 18 19 - .. kernel-abi:: $srctree/Documentation/ABI/testing 19 + .. kernel-abi:: ABI/testing 20 20 :rst:
+10 -46
Documentation/sphinx/kernel_abi.py
··· 39 39 import re 40 40 import kernellog 41 41 42 - from os import path 43 - 44 42 from docutils import nodes, statemachine 45 43 from docutils.statemachine import ViewList 46 44 from docutils.parsers.rst import directives, Directive ··· 71 73 } 72 74 73 75 def run(self): 74 - 75 76 doc = self.state.document 76 77 if not doc.settings.file_insertion_enabled: 77 78 raise self.warning("docutils: file insertion disabled") 78 79 79 - env = doc.settings.env 80 - cwd = path.dirname(doc.current_source) 81 - cmd = "get_abi.pl rest --enable-lineno --dir " 82 - cmd += self.arguments[0] 80 + srctree = os.path.abspath(os.environ["srctree"]) 81 + 82 + args = [ 83 + os.path.join(srctree, 'scripts/get_abi.pl'), 84 + 'rest', 85 + '--enable-lineno', 86 + '--dir', os.path.join(srctree, 'Documentation', self.arguments[0]), 87 + ] 83 88 84 89 if 'rst' in self.options: 85 - cmd += " --rst-source" 90 + args.append('--rst-source') 86 91 87 - srctree = path.abspath(os.environ["srctree"]) 88 - 89 - fname = cmd 90 - 91 - # extend PATH with $(srctree)/scripts 92 - path_env = os.pathsep.join([ 93 - srctree + os.sep + "scripts", 94 - os.environ["PATH"] 95 - ]) 96 - shell_env = os.environ.copy() 97 - shell_env["PATH"] = path_env 98 - shell_env["srctree"] = srctree 99 - 100 - lines = self.runCmd(cmd, shell=True, cwd=cwd, env=shell_env) 92 + lines = subprocess.check_output(args, cwd=os.path.dirname(doc.current_source)).decode('utf-8') 101 93 nodeList = self.nestedParse(lines, self.arguments[0]) 102 94 return nodeList 103 - 104 - def runCmd(self, cmd, **kwargs): 105 - u"""Run command ``cmd`` and return its stdout as unicode.""" 106 - 107 - try: 108 - proc = subprocess.Popen( 109 - cmd 110 - , stdout = subprocess.PIPE 111 - , stderr = subprocess.PIPE 112 - , **kwargs 113 - ) 114 - out, err = proc.communicate() 115 - 116 - out, err = codecs.decode(out, 'utf-8'), codecs.decode(err, 'utf-8') 117 - 118 - if proc.returncode != 0: 119 - raise self.severe( 120 - u"command '%s' failed with return code %d" 121 - % (cmd, proc.returncode) 122 - ) 123 - except OSError as exc: 124 - raise self.severe(u"problems with '%s' directive: %s." 125 - % (self.name, ErrorString(exc))) 126 - return out 127 95 128 96 def nestedParse(self, lines, fname): 129 97 env = self.state.document.settings.env