598c715ed7f6e87e0c283a34ef563dce7bee727b
[lhc/web/wiklou.git] / tests / integration / includes / shell / FirejailCommandTest.php
1 <?php
2
3 use MediaWiki\Shell\FirejailCommand;
4 use MediaWiki\Shell\Shell;
5
6 /**
7 * Integration tests to ensure that firejail actually prevents execution.
8 * Meant to run on vagrant, although will probably work on other setups
9 * as long as firejail and sudo has similar config.
10 * @group Shell
11 */
12 class FirejailCommandIntegrationTest extends PHPUnit_Framework_TestCase {
13
14 public function setUp() {
15 parent::setUp();
16 if ( Shell::command( 'which', 'firejail' )->execute()->getExitCode() ) {
17 $this->markTestSkipped( 'firejail not installed' );
18 } elseif ( wfIsWindows() ) {
19 $this->markTestSkipped( 'test supports POSIX environments only' );
20 }
21 }
22
23 public function testSanity() {
24 // Make sure that firejail works at all.
25 $command = new FirejailCommand( 'firejail' );
26 $command
27 ->unsafeParams( 'ls .' )
28 ->restrict( Shell::RESTRICT_DEFAULT );
29 $result = $command->execute();
30 $this->assertSame( 0, $result->getExitCode() );
31 }
32
33 /**
34 * @coversNothing
35 * @dataProvider provideExecute
36 */
37 public function testExecute( $testCommand, $flag ) {
38 if ( preg_match( '/^sudo /', $testCommand ) ) {
39 if ( Shell::command( 'sudo', '-n', 'ls', '/' )->execute()->getExitCode() ) {
40 $this->markTestSkipped( 'need passwordless sudo' );
41 }
42 }
43
44 $command = new FirejailCommand( 'firejail' );
45 $command
46 ->unsafeParams( $testCommand )
47 // If we don't restrict at all, firejail won't be invoked,
48 // so the test will give a false positive if firejail breaks
49 // the command for some non-flag-related reason. Instead,
50 // set some flag that won't get in the way.
51 ->restrict( $flag === Shell::NO_NETWORK ? Shell::PRIVATE_DEV : Shell::NO_NETWORK );
52 $result = $command->execute();
53 $this->assertSame( 0, $result->getExitCode(), 'sanity check' );
54
55 $command = new FirejailCommand( 'firejail' );
56 $command
57 ->unsafeParams( $testCommand )
58 ->restrict( $flag );
59 $result = $command->execute();
60 $this->assertNotSame( 0, $result->getExitCode(), 'real check' );
61 }
62
63 public function provideExecute() {
64 global $IP;
65 return [
66 [ 'sudo -n ls /', Shell::NO_ROOT ],
67 [ 'sudo -n ls /', Shell::SECCOMP ], // not a great test but seems to work
68 [ 'ls /dev/cpu', Shell::PRIVATE_DEV ],
69 [ 'curl -fsSo /dev/null https://wikipedia.org/', Shell::NO_NETWORK ],
70 [ 'exec ls /', Shell::NO_EXECVE ],
71 [ "cat $IP/LocalSettings.php", Shell::NO_LOCALSETTINGS ],
72 ];
73 }
74
75 }