1 /* === This file is part of Calamares - <https://calamares.io> ===
2  *
3  *   SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
4  *   SPDX-License-Identifier: GPL-3.0-or-later
5  *
6  *   Calamares is Free Software: see the License-Identifier above.
7  *
8  */
9 
10 #include "InitcpioJob.h"
11 
12 #include "utils/CalamaresUtilsSystem.h"
13 #include "utils/Logger.h"
14 #include "utils/UMask.h"
15 #include "utils/Variant.h"
16 
17 #include <QDir>
18 #include <QFile>
19 
InitcpioJob(QObject * parent)20 InitcpioJob::InitcpioJob( QObject* parent )
21     : Calamares::CppJob( parent )
22 {
23 }
24 
~InitcpioJob()25 InitcpioJob::~InitcpioJob() {}
26 
27 
28 QString
prettyName() const29 InitcpioJob::prettyName() const
30 {
31     return tr( "Creating initramfs with mkinitcpio." );
32 }
33 
34 void
fixPermissions(const QDir & d)35 fixPermissions( const QDir& d )
36 {
37     for ( const auto& fi : d.entryInfoList( { "initramfs*" }, QDir::Files ) )
38     {
39         QFile f( fi.absoluteFilePath() );
40         if ( f.exists() )
41         {
42             cDebug() << "initcpio fixing permissions for" << f.fileName();
43             f.setPermissions( QFileDevice::ReadOwner | QFileDevice::WriteOwner );
44         }
45     }
46 }
47 
48 Calamares::JobResult
exec()49 InitcpioJob::exec()
50 {
51     CalamaresUtils::UMask m( CalamaresUtils::UMask::Safe );
52 
53     if ( m_unsafe )
54     {
55         cDebug() << "Skipping mitigations for unsafe initramfs permissions.";
56     }
57     else
58     {
59         QDir d( CalamaresUtils::System::instance()->targetPath( "/boot" ) );
60         if ( d.exists() )
61         {
62             fixPermissions( d );
63         }
64     }
65 
66     cDebug() << "Updating initramfs with kernel" << m_kernel;
67     auto r = CalamaresUtils::System::instance()->targetEnvCommand(
68         { "mkinitcpio", "-p", m_kernel }, QString(), QString() /* no timeout , 0 */ );
69     return r.explainProcess( "mkinitcpio", std::chrono::seconds( 10 ) /* fake timeout */ );
70 }
71 
72 void
setConfigurationMap(const QVariantMap & configurationMap)73 InitcpioJob::setConfigurationMap( const QVariantMap& configurationMap )
74 {
75     m_kernel = CalamaresUtils::getString( configurationMap, "kernel" );
76     if ( m_kernel.isEmpty() )
77     {
78         m_kernel = QStringLiteral( "all" );
79     }
80     else if ( m_kernel == "$uname" )
81     {
82         auto r = CalamaresUtils::System::runCommand( CalamaresUtils::System::RunLocation::RunInHost,
83                                                      { "/bin/uname", "-r" },
84                                                      QString(),
85                                                      QString(),
86                                                      std::chrono::seconds( 3 ) );
87         if ( r.getExitCode() == 0 )
88         {
89             m_kernel = r.getOutput();
90             cDebug() << "*initcpio* using running kernel" << m_kernel;
91         }
92         else
93         {
94             cWarning() << "*initcpio* could not determine running kernel, using 'all'." << Logger::Continuation
95                        << r.getExitCode() << r.getOutput();
96         }
97     }
98 
99     m_unsafe = CalamaresUtils::getBool( configurationMap, "be_unsafe", false );
100 }
101 
102 CALAMARES_PLUGIN_FACTORY_DEFINITION( InitcpioJobFactory, registerPlugin< InitcpioJob >(); )
103