Use realpath() safely (#764369)

realpath(3) manual page says:

    BUGS
        The POSIX.1-2001 standard version of this function is broken by
        design, since it is impossible to determine a suitable size for
        the output buffer, resolved_path.  According to POSIX.1-2001 a
        buffer of size PATH_MAX suffices, but PATH_MAX need not be a
        defined constant, and may have to be obtained using pathconf(3).
        And asking pathconf(3) does not really help, since, on the one
        hand POSIX warns that the result of pathconf(3) may be huge and
        unsuitable for mallocing memory, and on the other hand
        pathconf(3) may return -1 to signify that PATH_MAX is not
        bounded.  The resolved_path == NULL feature, not standardized in
        POSIX.1-2001, but standardized in POSIX.1-2008, allows this
        design problem to be avoided.

The resolved_path == NULL feature of realpath() has existed as a Glibc
extension since realpath() was first added to Glibc 1.90, released in
June 1996.  Therefore it can be used unconditionally.

    https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fa0bc87c32d02cd81ec4d0ae00e0d943c683e6e1

Bug 764369 - Use realpath() safely
This commit is contained in:
Mike Fleetwood 2016-03-18 16:30:41 +00:00 committed by Curtis Gedak
parent a681f9f637
commit d04826cc27
3 changed files with 26 additions and 17 deletions

View File

@ -17,6 +17,7 @@
#include "../include/DMRaid.h" #include "../include/DMRaid.h"
#include "../include/Partition.h" #include "../include/Partition.h"
#include <limits.h>
#include <stdlib.h> //atoi function #include <stdlib.h> //atoi function
namespace GParted namespace GParted
@ -126,11 +127,11 @@ bool DMRaid::is_dmraid_device( const Glib::ustring & dev_path )
if ( ! device_found && file_test( dev_path, Glib::FILE_TEST_IS_SYMLINK ) ) if ( ! device_found && file_test( dev_path, Glib::FILE_TEST_IS_SYMLINK ) )
{ {
//Path is a symbolic link so find real path //Path is a symbolic link so find real path
char c_str[4096+1] ; char * rpath = realpath( dev_path.c_str(), NULL );
//FIXME: it seems realpath is very unsafe to use (manpage)... if ( rpath != NULL )
if ( realpath( dev_path .c_str(), c_str ) != NULL )
{ {
Glib::ustring tmp_path = c_str ; Glib::ustring tmp_path = rpath;
free( rpath );
if ( tmp_path .length() > 0 ) if ( tmp_path .length() > 0 )
for ( unsigned int k=0; k < dmraid_devices .size(); k++ ) for ( unsigned int k=0; k < dmraid_devices .size(); k++ )
if ( tmp_path .find( dmraid_devices[k] ) != Glib::ustring::npos ) if ( tmp_path .find( dmraid_devices[k] ) != Glib::ustring::npos )
@ -196,11 +197,11 @@ Glib::ustring DMRaid::get_dmraid_name( const Glib::ustring & dev_path )
if ( dmraid_name .empty() && file_test( dev_path, Glib::FILE_TEST_IS_SYMLINK ) ) if ( dmraid_name .empty() && file_test( dev_path, Glib::FILE_TEST_IS_SYMLINK ) )
{ {
//Path is a symbolic link so find real path //Path is a symbolic link so find real path
char c_str[4096+1] ; char * rpath = realpath( dev_path.c_str(), NULL );
//FIXME: it seems realpath is very unsafe to use (manpage)... if ( rpath != NULL )
if( realpath( dev_path .c_str(), c_str ) != NULL )
{ {
Glib::ustring tmp_path = c_str ; Glib::ustring tmp_path = rpath;
free( rpath );
if ( tmp_path .length() > 0 ) if ( tmp_path .length() > 0 )
for ( unsigned int k=0; k < dmraid_devices .size(); k++ ) for ( unsigned int k=0; k < dmraid_devices .size(); k++ )
if ( tmp_path .find( dmraid_devices[k] ) != Glib::ustring::npos ) if ( tmp_path .find( dmraid_devices[k] ) != Glib::ustring::npos )

View File

@ -47,11 +47,14 @@
#include "../include/reiser4.h" #include "../include/reiser4.h"
#include "../include/ufs.h" #include "../include/ufs.h"
#include "../include/Copy_Blocks.h" #include "../include/Copy_Blocks.h"
#include <set> #include <set>
#include <cerrno> #include <cerrno>
#include <cstring> #include <cstring>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <dirent.h> #include <dirent.h>
#include <mntent.h> #include <mntent.h>
@ -1091,10 +1094,12 @@ void GParted_Core::add_node_and_mountpoint(
// then find real path and add entry too // then find real path and add entry too
if ( file_test( node, Glib::FILE_TEST_IS_SYMLINK ) ) if ( file_test( node, Glib::FILE_TEST_IS_SYMLINK ) )
{ {
char c_str[4096+1] ; char * rpath = realpath( node.c_str(), NULL );
//FIXME: it seems realpath is very unsafe to use (manpage)... if ( rpath != NULL )
if ( realpath( node .c_str(), c_str ) != NULL ) {
map[ c_str ] .push_back( mountpoint ) ; map[rpath].push_back( mountpoint );
free( rpath );
}
} }
} }
} }

View File

@ -17,6 +17,8 @@
#include "../include/Proc_Partitions_Info.h" #include "../include/Proc_Partitions_Info.h"
#include <fstream> #include <fstream>
#include <limits.h>
#include <stdlib.h>
namespace GParted namespace GParted
{ {
@ -131,16 +133,17 @@ void Proc_Partitions_Info::load_proc_partitions_info_cache()
line = "/dev/" ; line = "/dev/" ;
line += c_str ; line += c_str ;
//FIXME: it seems realpath is very unsafe to use (manpage)... char * rpath = NULL;
if ( file_test( line, Glib::FILE_TEST_EXISTS ) if ( file_test( line, Glib::FILE_TEST_EXISTS )
&& realpath( line .c_str(), c_str ) && ( ( rpath = realpath( line.c_str(), NULL ) ) != NULL )
//&& line != c_str //&& line != c_str
) )
{ {
//Because we can make no assumption about which path libparted will //Because we can make no assumption about which path libparted will
//detect, we add all combinations. //detect, we add all combinations.
alternate_paths_cache[ c_str ] = line ; alternate_paths_cache[rpath] = line;
alternate_paths_cache[ line ] = c_str ; alternate_paths_cache[line] = rpath;
free( rpath );
} }
} }