[gparted] Add ability for small writes to stdin of child processes (#795617)
- From: Curtis Gedak <gedakc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gparted] Add ability for small writes to stdin of child processes (#795617)
- Date: Mon, 30 Apr 2018 18:42:15 +0000 (UTC)
commit 8dff80edc65b2923b400ddadebacf9bcf378d09f
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date: Fri Oct 20 19:47:00 2017 +0100
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
include/Utils.h | 5 +++++
src/Utils.cc | 27 +++++++++++++++++++++++++--
2 files changed, 30 insertions(+), 2 deletions(-)
---
diff --git a/include/Utils.h b/include/Utils.h
index 0f10902..93402ae 100644
--- a/include/Utils.h
+++ b/include/Utils.h
@@ -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
diff --git a/src/Utils.cc b/src/Utils.cc
index a955f6a..b0d26cd 100644
--- a/src/Utils.cc
+++ b/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
@@ -580,7 +582,17 @@ int Utils::execute_command( const Glib::ustring & command,
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 {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]