Trying to set a file system label to (including the double quotes):
" --help "
fails. For example labelling an ext4 file system would try to run this
command:
# e2label /dev/sdb1 "" --help ""
Usage: e2label device [newlabel]
# echo $?
1
Alternatively trying to create a file system with a label of just a
double quote also fails. The Applying Pending Operations dialog waits
forever and won't cancel or force cancel. Have to use the window
manager close window button to close the dialog. Also GParted reports
this error to the console:
(gpartedbin:9648): glibmm-CRITICAL **:
unhandled exception (type Glib::Error) in signal handler:
domain: g-shell-error-quark
code : 0
what : Text ended before matching quote was found for ". (The text was 'mkfs.xfs -f -L """ /dev/sdb2')
Command strings are parsed and split into argv array by function
Glib::shell_parse_argv() which calls internal glib function
tokenize_command_line() for shell tokenization. It expects the command
string to be properly quoted and escaped and after tokenization, calls
g_shell_unquote() on every parsed argument. So to prevent constructing
incorrect commands, every non-static string needs to be properly quoted.
GParted only puts labels and mount points into double quotes, but has
not escaped special characters in those values itself. This patch
fixes all these problems by using Glib::shell_quote() on all variable
values. Labels, mount points, paths and all others too.
Probably a better solution would be to use a new function which takes
argv array instead of one string with all the, correctly quoted and
escaped, arguments concatenated together.
Bug 787203 - Correctly quote and escape arguments of external programs
passed to execute_command()
Shell fragments must be properly quoted and escaped to prevent execution
of unintended commands derived from user controllable data. For
example:
$ printf '#!/bin/sh\necho test > out\n' > script.sh
$ chmod +x script.sh
$ truncate -s 20M 'jfs;script.sh'
$ mkfs.jfs -q 'jfs;script.sh'
$ ls -l out
ls: cannot access out: No such file or directory
$ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'
$ sudo PATH=$PWD:$PATH /usr/local/bin/gparted 'jfs;script.sh'
$ ls -l out
-rw-r--r-- 1 root root 5 Sep 12 23:11 out
$ cat out
test
What is happening is that jfs::set_used_sectors() is using the device
name 'jfs;script.sh' without quoting it and passing it to the shell to
execute like this:
sh -c 'echo dm | jfs_debugfs jfs;script.sh'
which the shell duly executes as these two commands:
echo dm | jfs_debugfs jfs
script.sh
This could be a security related issue as "sh -c" is able to execute
arbitrary shell commands from the argument if if contains shell special
characters. Use Glib::shell_quote() [1] to quote and escape file names
and whole commands passed to the shell.
[1] Glib::shell_quote(const std::string & unquoted_string)
https://developer.gnome.org/glibmm/stable/group__ShellUtils.html
"Quotes a string so that the shell (/bin/sh) will interpret the
quoted string to mean unquoted_string.
If you pass a filename to the shell, for example, you should first
quote it with this function."
Bug 787203 - Correctly quote and escape arguments of external programs
passed to execute_command()
Naming a file system image file on the command line is shown by GParted
as unknown.
$ truncate -s 100M /tmp/fat.img
$ mkfs.vfat /tmp/fat.img
$ sudo ./gpartedbin /tmp/fat.img
Currently the FS_Info cache is loaded for all devices reported by
blkid (plus all whole disk devices identified from /proc/partitions even
if blkid reports nothing). However file system images named on the
command line are not queried so GParted can't identify them.
Fix by ensuring that the FS_Info blkid cache is loaded for all named
devices, including named file system image files.
Note that Mount_Info::load_cache() depends on the contents of the
FS_Info cache to lookup UUID= and LABEL= device names from /etc/fstab.
However only file systems in block devices can be mounted like this, and
never file system image files, so the fact that the cache may be
extended afterwards by FS_Info::load_cache_for_paths() does not matter.
History
Prior to version 0.22.0, when unpartitioned drive support was added,
GParted could recognise some file system image files using loop
partition handling in libparted. However libparted before version 3.2
reported the loop partition name as the whole disk device name appended
with "1" so all the query commands were provided a non-existent name to
use. Therefore no file system usage or the label was displayed.
Bug 787181 - Fix detection of file system images
Add double quote (") to the list of prohibited FAT label characters,
previously missed [1][2].
Also add single quote (') because mlabel encoded it in a way that both
Windows and blkid don't understand, although mlabel can correctly decode
it itself.
# export MTOOLS_SKIP_CHECK=1
# mlabel ::"MIKE'S" -i /dev/sdf1
# mlabel -s :: -i /dev/sdf1
Volume label is MIKE'S (abbr=MIKE_S~1???)
# blkid -o value -s LABEL /dev/sdf1
MIKE_S~1???
(8-bit characters in the above output have been replaced with
question marks (?) just to keep this commit message as 7-bit ASCII).
Finally exclude ASCII control characters below SPACE (0x00 to 0x1F) as
they also cause mlabel to ask a question and wait for input in the same
way that prohibited characters do. As discussed in the previous commit
[1] the only way to stop GParted waiting forever is to manually kill
mlabel with signal 9 (KILL).
# mlabel ::"^A" -i /dev/sdf1
Long file name "^A" contains illegal character(s).
a)utorename A)utorename-all r)ename R)ename-all
s)kip S)kip-all q)uit (aArRsSq):
[1] 584137b32b
Remove prohibited characters from FAT16/32 labels (#755608)
[2] Microsoft TechNet: Label
https://technet.microsoft.com/en-us/library/bb490925.aspx
Bug 787202 - Update list of prohibited fat label characters
So far GParted is still loading the default non-reversible encoded
labels from blkid in the initial loading of the FS_Info module cache.
This encoded label is used to match LABEL=<label> when reading
/etc/fstab, via the get_path_by_label() call, so works for ASCII only
labels. This prevents GParted enabling the "mount on >" partition menu
item when non-ASCII labels are used.
To fix this:
1) Stop reading the labels the wrong way.
Via the blkid command used to initially load the FS_Info module cache
and is subject to default non-reversible encoding of non-printable
ASCII bytes.
2) Read all the labels the right way, but only when needed.
Only when /etc/fstab file contains LABEL=<label> and
get_path_by_label() is called, read all the labels from blkid without
encoding them via run_blkid_update_cache_one_label().
3) Return label from the cache.
get_label() returns the cached label, loading it into the cache first
if needed with run_blkid_update_cache_one_label().
In the worst case scenario of having a LABEL=<label> in /etc/fstab blkid
will be run for every partition containing a recognised file system to
read the label. On my desktop with 5 hard drives, 4 SWRaid arrays and
31 recognised file systems running 'blkid -o value -s LABEL ...' 31
times took 0.074 seconds of a total scan time of 9.072 seconds. Less
that 1% of the total scanning time. When LABEL=<label> is not used in
/etc/fstab individual blkid executions are only used to read labels for
file systems where there is no file system specific tool available
reducing the impact further. Blkid itself caches the data in it's
blkid.tab cache file rather than reading all file systems on each
invocation. Also the Linux file system cache will already contain the
blkid executable file, needed libraries files and the blkid.tab cache
file itself. Hence why repeated execution of blkid is so fast.
Further to the updated comment in set_partition_label_and_uuid().
Matching LABEL=<label> from /etc/fstab uses the label obtained from
blkid run in the C locale so this kind of assumes it returns the label
correctly and it does for my limited testing on Unicode enabled
desktops. Just not sure if it would be true for all cases in all
locales compared to the FS specific command run in the users default
locale.
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
Move the code which reads the Unicode label from FS_Info::get_label()
into new function run_blkid_update_cache_one_label() which also replaces
the non-reversibly encoded copy loaded during the initial cache load.
This is mainly a bit of code refactoring ready for the following change.
It deliberately keeps the initial loaded labels so that reading
/etc/fstab and decoding LABEL=<label> to block special device names via
FS_Info::get_path_by_label() continues to works, at least for ASCII only
labels.
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
For file systems which don't provide a specific tool to read labels
(exfat, f2fs, hfs, hfsplus, udf and ufs) or when the tools aren't
installed for any other file system, reading labels falls back to using
the blkid command. Blkid encodes non-ASCII bytes in it's output [1].
For example blkid reports a short Unicode label like this:
# blkid /dev/sdb12
/dev/sdb12: LABEL="M-PM-^ZM-PM->M-QM-^HM-PM-:M-PM-0" TYPE="hfsplus"
This shows encoding using 'M-' for bytes above 127 and caret '^' for
control characters. Unfortunately neither 'M-' or '^' are encoded by
blkid so it is impossible to distinguish between the original label
containing either of these sequences or encoded non-printable bytes.
See this Bugzilla's bug 786502 entry for more details. Unfortunately
this makes the default output format from blkid unsuitable for reading
Unicode character labels.
Instead instruct blkid to print values without encoding them using the
'-o value' option. This just produces a list of new line separated
values without being able to identify which TYPE, UUID or LABEL belongs
to which device. So query just the label for each block device one at
a time. This method has the advantage of also working with all versions
of blkid, from version 1.0.0 (12-Feb-2003) in CentOS 5 to the latest
version 2.30.1 (20-Jul-2017) in Fedora 26.
# blkid -o value -s LABEL /dev/sdb12 | hexdump -C
00000000 d0 9a d0 be d1 88 d0 ba d0 b0 0a |...........|
0000000b
(Using hexdump -C just so that this commit message only contains ASCII
characters).
Therefore this commit changes FS_Info::get_label() to query blkid as
shown above. Note that GParted_Core::set_partition_label_and_uuid()
only calls get_label() when there is no file system specific tool
available (or the tool failed).
The FS_Info cache still contains copies of the labels subject to blkid
encoding, and that will be addressed in following commits.
[1] blkid.c v2.30.1 safe_print()
https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/misc-utils/blkid.c?h=v2.30.1#n111
Bug 786502 - Support reading Unicode labels when file system specific
tools aren't available
Automake build of libraries creates .dirstamp files. First added by
this commit:
81b104928b
Add building of Google Test libraries (#781978)
Mark .dirstamp as to be ignored by GIT.
GParted fails to display when run under Wayland [1][2][3]. This is
because by intentional design Wayland doesn't allow applications with
root privileges access to the display [4].
As an interim workaround make the gparted shell wrapper use xhost to
grant root access to the X11 server if root doesn't already have access,
but only when configured. Granting root access must be explicitly
enabled when building GParted like this:
./configure --enable-xhost-root
It defaults to disabled. When gpartedbin binary ends the shell wrapper
revokes root access only if it granted such access.
[1] GNOME Bug 776437 - GParted fails to run as root under Wayland
https://bugzilla.gnome.org/show_bug.cgi?id=776437
[2] Ubuntu Bug 1652282 - GParted does not work in GNOME on Wayland
https://bugs.launchpad.net/ubuntu/+source/gparted/+bug/1652282
[3] Fedora Bug 1397103 - gparted not working under Wayland
https://bugzilla.redhat.com/show_bug.cgi?id=1397103
[4] Common Fedora 25 bugs
Running graphical apps with root privileges (e.g. gparted) does not
work on Wayland
https://fedoraproject.org/wiki/Common_F25_bugs#wayland-root-apps
Bug 776437 - GParted fails to run as root under Wayland
On CentOS 6 with polkit version 0.96 pkexec fails to execute gparted
shell wrapper as root like this:
$ env | grep DISPLAY
DISPLAY=:0.0
$ sh -x /usr/local/bin/gparted
...
+ pkexec /usr/local/bin/gparted
(gpartedbin:8011): Gtk-WARNING **: cannot open display:
This is because polkit didn't support setting the DISPLAY environment
variable to allow execution of X11 applications until the introduction
of the allow_gui annotation by this commit in polkit 0.102:
https://cgit.freedesktop.org/polkit/commit/?id=7850d27017fed1834268a852350ae85381fbb110
Bug 38769 - pkexec: Support running X11 apps
Make configure only use pkexec version 0.102 or higher as the privilege
escalation program. Otherwise configure falls back to checking for the
other privilege escalation programs as it did before.
Bug 776437 - GParted fails to run as root under Wayland
Only install the GParted polkit action file when pkexec is being used as
the root privilege escalation program.
Bug 776437 - GParted fails to run as root under Wayland
An action file is always needed with polkit to describe the privileged
actions that are available to the subject (client program). For GParted
the only available action is to run the gparted shell script as root.
Note that the polkit action file will be installed into location
$(prefix)/share/polkit-1/actions. This is required by the GNU Coding
Standards [1] and to prevent 'make distcheck' from failing [2]. However
polkit only uses /usr/share/polkit-1/actions for it's action files [3].
This dilemma was discussed in this Bugzilla bug 776437 and on the
general Automake discussion email list [4]. The solution is to simply
document in the README file that a manual additional installation step
may be required.
The action file is marked as translatable with the underscore (_) of the
_description and _message tags identifying the string to be translated.
Use of INTLTOOL_POLICY_RULE in Makefile.am to merge translations into
the polkit action file necessitates increasing the minimum version of
intltool to 0.36.0 where it was first introduced in intltool.m4. This
will prevent GParted building on RedHat/CentOS 5 which only has intltool
0.35.0. But that doesn't matter because RedHat/CentOS 5 reached end of
life on 31st March 2017.
[1] GNU Coding Standards, 7.2.5 Variables for Installation Directories
https://www.gnu.org/prep/standards/standards.html#Directory-Variables
[2] Automake Manual, 27.10 Installing to Hard-Coded Locations
https://www.gnu.org/software/automake/manual/automake.html#Hard_002dCoded-Install-Paths
"My package needs to populate the installation directory of another
package at install-time. I can easily compute that installation
directory in configure, but if I install files therein,
'make distcheck' fails. How else should I do?"
[3] polkit(8), Declaring Actions
https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html#polkit-declaring-actions
"A mechanism need to declare a set of actions in order to use
polkit. Actions correspond to operations that clients can request
the mechanism to carry out and are defined in XML files that the
mechanism installs into the /usr/share/polkit-1/actions directory."
[4] Not installing to hard-coded locations vs polkit's fixed location
http://lists.gnu.org/archive/html/automake/2017-08/msg00015.html
Bug 776437 - GParted fails to run as root under Wayland
Many of the distributions (confirmed for Arch Linux, Debian, Fedora,
OpenSUSE, RedHat/CentOS and Ubuntu but likely many others too) are now
using polkit as the mechanism to authorise privileged actions, including
using it to authorise GParted to run as root in their packages of
GParted. Therefore make the GParted configure script check for the
pkexec command.
Use pkexec with the --disable-internal-agent option when available,
preventing pkexec using it's own textual authentication agent. When
running GParted from a desktop icon or menu there is no terminal with
which to interact with the textual authentication agent to it can't be
used. The desktop's graphical agent must be running. This matches how
some distributions already use polkit in their own packages of GParted.
Required actions file will be added in the next commit.
polkit(8)
https://www.freedesktop.org/software/polkit/docs/latest/polkit.8.html
pkexec(1)
https://www.freedesktop.org/software/polkit/docs/latest/pkexec.1.html
Bug 776437 - GParted fails to run as root under Wayland
Now that the gparted script is intended to be run by ordinary users, as
well as root, install it into directory $prefix/bin rather than
$prefix/sbin.
Bug 776437 - GParted fails to run as root under Wayland
Move calling of the privilege escalation program which allows a normal
user to run GParted as root from the desktop file into the gparted
wrapper script. This is in preparation for further changes needed to
grant root access to the X11 display under Wayland.
Don't introduce yet another script so that there aren't two different
names to run GParted by for normal users and root. Using the same
gparted name but placing two different scripts at /usr/bin/gparted and
/usr/sbin/gparted is not possible because on Arch Linux /usr/sbin is a
symbolic link to /usr/bin.
Frequently asked questions, Does Arch follow the FHS?
https://wiki.archlinux.org/index.php/Frequently_asked_questions#Does_Arch_follow_the_FHS.3F
"Arch Linux follows the file system hierarchy for operating systems
using the systemd service manager. See file-hierarchy(7) for an
explanation of each directory along with their designations. In
particular, /bin, /sbin, and /usr/sbin are symbolic links to
/usr/bin, and /lib (and /lib64 if applicable) are symbolic links to
/usr/lib".
Bug 776437 - GParted fails to run as root under Wayland
When udftools are not installed and the mkudffs program isn't found
GParted would report this error during startup:
# ./gpartedbin
======================
libparted : 3.1
======================
Failed to execute child process "mkudffs" (No such file or directory)
Only run mkudffs to check for an old version when the program is found.
Bug 786050 - GParted reports failed to execute child process "mkudffs"
when it is not installed