MediaWiki REL1_32
FirejailCommand.php
Go to the documentation of this file.
1<?php
21namespace MediaWiki\Shell;
22
23use RuntimeException;
24
31class FirejailCommand extends Command {
32
36 private $firejail;
37
41 private $whitelistedPaths = [];
42
46 public function __construct( $firejail ) {
47 parent::__construct();
48 $this->firejail = $firejail;
49 }
50
54 public function whitelistPaths( array $paths ) {
55 $this->whitelistedPaths = array_merge( $this->whitelistedPaths, $paths );
56 return $this;
57 }
58
62 protected function buildFinalCommand( $command ) {
63 // If there are no restrictions, don't use firejail
64 if ( $this->restrictions === 0 ) {
65 $splitCommand = explode( ' ', $command, 2 );
66 $this->logger->debug(
67 "firejail: Command {$splitCommand[0]} {params} has no restrictions",
68 [ 'params' => $splitCommand[1] ?? '' ]
69 );
70 return parent::buildFinalCommand( $command );
71 }
72
73 if ( $this->firejail === false ) {
74 throw new RuntimeException( 'firejail is enabled, but cannot be found' );
75 }
76 // quiet has to come first to prevent firejail from adding
77 // any output.
78 $cmd = [ $this->firejail, '--quiet' ];
79 // Use a profile that allows people to add local overrides
80 // if their system is setup in an incompatible manner. Also it
81 // prevents any default profiles from running.
82 // FIXME: Doesn't actually override command-line switches?
83 $cmd[] = '--profile=' . __DIR__ . '/firejail.profile';
84
85 // By default firejail hides all other user directories, so if
86 // MediaWiki is inside a home directory (/home) but not the
87 // current user's home directory, pass --allusers to whitelist
88 // the home directories again.
89 static $useAllUsers = null;
90 if ( $useAllUsers === null ) {
91 global $IP;
92 // In case people are doing funny things with symlinks
93 // or relative paths, resolve them all.
94 $realIP = realpath( $IP );
95 $currentUser = posix_getpwuid( posix_geteuid() );
96 $useAllUsers = ( strpos( $realIP, '/home/' ) === 0 )
97 && ( strpos( $realIP, $currentUser['dir'] ) !== 0 );
98 if ( $useAllUsers ) {
99 $this->logger->warning( 'firejail: MediaWiki is located ' .
100 'in a home directory that does not belong to the ' .
101 'current user, so allowing access to all home ' .
102 'directories (--allusers)' );
103 }
104 }
105
106 if ( $useAllUsers ) {
107 $cmd[] = '--allusers';
108 }
109
110 if ( $this->whitelistedPaths ) {
111 // Always whitelist limit.sh
112 $cmd[] = '--whitelist=' . __DIR__ . '/limit.sh';
113 foreach ( $this->whitelistedPaths as $whitelistedPath ) {
114 $cmd[] = "--whitelist={$whitelistedPath}";
115 }
116 }
117
118 if ( $this->hasRestriction( Shell::NO_LOCALSETTINGS ) ) {
119 $cmd[] = '--blacklist=' . realpath( MW_CONFIG_FILE );
120 }
121
122 if ( $this->hasRestriction( Shell::NO_ROOT ) ) {
123 $cmd[] = '--noroot';
124 }
125
126 $useSeccomp = $this->hasRestriction( Shell::SECCOMP );
127 $extraSeccomp = [];
128
129 if ( $this->hasRestriction( Shell::NO_EXECVE ) ) {
130 $extraSeccomp[] = 'execve';
131 // Normally firejail will run commands in a bash shell,
132 // but that won't work if we ban the execve syscall, so
133 // run the command without a shell.
134 $cmd[] = '--shell=none';
135 }
136
137 if ( $useSeccomp ) {
138 $seccomp = '--seccomp';
139 if ( $extraSeccomp ) {
140 // The "@default" seccomp group will always be enabled
141 $seccomp .= '=' . implode( ',', $extraSeccomp );
142 }
143 $cmd[] = $seccomp;
144 }
145
146 if ( $this->hasRestriction( Shell::PRIVATE_DEV ) ) {
147 $cmd[] = '--private-dev';
148 }
149
150 if ( $this->hasRestriction( Shell::NO_NETWORK ) ) {
151 $cmd[] = '--net=none';
152 }
153
154 $builtCmd = implode( ' ', $cmd );
155
156 // Prefix the firejail command in front of the wanted command
157 return parent::buildFinalCommand( "$builtCmd -- {$command}" );
158 }
159
160}
Class used for executing shell commands.
Definition Command.php:35
hasRestriction( $restriction)
Bitfield helper on whether a specific restriction is enabled.
Definition Command.php:264
Restricts execution of shell commands using firejail.
buildFinalCommand( $command)
@inheritDoc
whitelistPaths(array $paths)
@inheritDoc
string $firejail
Path to firejail.
const NO_EXECVE
Deny execve syscall with seccomp.
Definition Shell.php:83
const SECCOMP
Use seccomp to block dangerous syscalls.
Definition Shell.php:60
const NO_NETWORK
Restrict the request to have no network access.
Definition Shell.php:75
const PRIVATE_DEV
Create a private /dev.
Definition Shell.php:67
const NO_ROOT
Disallow any root access.
Definition Shell.php:52
const NO_LOCALSETTINGS
Deny access to LocalSettings.php (MW_CONFIG_FILE)
Definition Shell.php:90
$IP
Definition update.php:3
The wiki should then use memcached to cache various data To use multiple just add more items to the array To increase the weight of a make its entry a array("192.168.0.1:11211", 2))
Copyright (C) 2017 Kunal Mehta legoktm@member.fsf.org
Definition Command.php:21