Add ability for small writes to stdin of child processes (#795617)
As discussed in "LUKS password handling, threats and preventative measures" [1] GParted must be able to pass LUKS passphrases to cryptsetup via standard input to avoid having to write passwords to the file system and deal with additional security requirements. Therefore add a way to write input into created child processes. For small amounts of input, writing up to the pipe buffer capacity won't block [2]. This is 64K on versions of Linux in any currently supported distributions. [1] LUKS password handling, threats and preventative measures https://bugzilla.gnome.org/show_bug.cgi?id=627701#c56 GParted must not become a password manage so it must never save LUKS passwords to disk across separate invocations of GParted. ... GParted should avoid writing a temporary file containing the LUKS password as it introduces extra complexity with trying to safely handle and erase file content. Instead GParted must programmatically pass the LUKS password via standard input to the cryptsetup command. [2] pipe(7) manual page: Pipe capacity A pipe has a limited capacity. If the pipe is full, then a write(2) will block or fail, depending on whether the O_NONBLOCK flag is set (see below). ... In Linux versions before 2.6.11, the capacity of a pipe was the same as the system page size (e.g., 4096 bytes on i386). Since Linux 2.6.11, the pipe capacity is 65536 bytes. Bug 795617 - Implement opening and closing of LUKS mappings
This commit is contained in:
parent
9b52666bdb
commit
8dff80edc6
|
@ -153,6 +153,11 @@ public:
|
|||
Glib::ustring & output,
|
||||
Glib::ustring & error,
|
||||
bool use_C_locale = false ) ;
|
||||
static int execute_command( const Glib::ustring & command,
|
||||
const char * input,
|
||||
Glib::ustring & output,
|
||||
Glib::ustring & error,
|
||||
bool use_C_locale = false );
|
||||
static int get_failure_status( Glib::SpawnError & e );
|
||||
static int decode_wait_status( int wait_status );
|
||||
static Glib::ustring regexp_label( const Glib::ustring & text
|
||||
|
|
27
src/Utils.cc
27
src/Utils.cc
|
@ -32,6 +32,8 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
namespace GParted
|
||||
{
|
||||
|
@ -515,7 +517,7 @@ double Utils::sector_to_unit( Sector sectors, Byte_Value sector_size, SIZE_UNIT
|
|||
int Utils::execute_command( const Glib::ustring & command )
|
||||
{
|
||||
Glib::ustring dummy ;
|
||||
return execute_command( command, dummy, dummy ) ;
|
||||
return execute_command( command, NULL, dummy, dummy );
|
||||
}
|
||||
|
||||
class CommandStatus
|
||||
|
@ -579,8 +581,18 @@ int Utils::execute_command( const Glib::ustring & command,
|
|||
Glib::ustring & output,
|
||||
Glib::ustring & error,
|
||||
bool use_C_locale )
|
||||
{
|
||||
return execute_command( command, NULL, output, error, use_C_locale );
|
||||
}
|
||||
|
||||
int Utils::execute_command( const Glib::ustring & command,
|
||||
const char * input,
|
||||
Glib::ustring & output,
|
||||
Glib::ustring & error,
|
||||
bool use_C_locale )
|
||||
{
|
||||
Glib::Pid pid;
|
||||
int in = -1;
|
||||
// set up pipes for capture
|
||||
int out, err;
|
||||
CommandStatus status;
|
||||
|
@ -595,7 +607,7 @@ int Utils::execute_command( const Glib::ustring & command,
|
|||
Glib::SPAWN_DO_NOT_REAP_CHILD | Glib::SPAWN_SEARCH_PATH,
|
||||
use_C_locale ? sigc::ptr_fun( set_locale ) : sigc::slot< void >(),
|
||||
&pid,
|
||||
0,
|
||||
( input != NULL ) ? &in : 0,
|
||||
&out,
|
||||
&err );
|
||||
} catch (Glib::SpawnError &e) {
|
||||
|
@ -616,6 +628,17 @@ int Utils::execute_command( const Glib::ustring & command,
|
|||
outputcapture.connect_signal();
|
||||
errorcapture.connect_signal();
|
||||
|
||||
if ( input != NULL && in != -1 )
|
||||
{
|
||||
// Write small amount of input to pipe to the child process. Linux will
|
||||
// always accept up 4096 bytes without blocking. See pipe(7).
|
||||
size_t len = strlen( input );
|
||||
ssize_t written = write( in, input, len );
|
||||
if ( written == -1 || (size_t)written < len )
|
||||
std::cerr << "Write to child failed: " << Glib::strerror( errno ) << std::endl;
|
||||
close( in );
|
||||
}
|
||||
|
||||
if( status.foreground)
|
||||
Gtk::Main::run();
|
||||
else {
|
||||
|
|
Loading…
Reference in New Issue