1
/* Sometimes libparted operates on device mapper files, with a path of
2
/dev/mapper/foo. With newer lvm versions /dev/mapper/foo is a symlink to
3
/dev/dm-#. However some storage administration programs (anaconda for
4
example) may do the following:
5
1) Create a ped_device for /dev/mapper/foo
6
2) ped_get_device resolves the symlink to /dev/dm-#, and the path
7
in the PedDevice struct points to /dev/dm-#
8
3) The program does some things to lvm, causing the symlink to
9
point to a different /dev/dm-# node
10
4) The program does something with the PedDevice, which results
11
in an operation on the wrong device
13
Newer libparted versions do not suffer from this problem, as they
14
do not canonicalize device names under /dev/mapper. This test checks
22
#include <parted/parted.h>
27
static char *temporary_disk;
32
temporary_disk = _create_disk (4096 * 1024);
33
fail_if (temporary_disk == NULL, "Failed to create temporary disk");
39
unlink (temporary_disk);
40
free (temporary_disk);
43
START_TEST (test_symlink)
45
char cwd[256], ln[256] = "/dev/mapper/parted-test-XXXXXX";
47
if (!getcwd (cwd, sizeof cwd)) {
48
fail ("Could not get cwd");
52
/* Create a symlink under /dev/mapper to our
54
int tmp_fd = mkstemp (ln);
56
fail ("Could not create tempfile");
60
/* There is a temp file vulnerability symlink attack possibility
61
here, but as /dev/mapper is root owned this is a non issue */
64
char temp_disk_path[256];
65
snprintf (temp_disk_path, sizeof temp_disk_path, "%s/%s", cwd,
67
int res = symlink (temp_disk_path, ln);
69
fail ("could not create symlink");
73
PedDevice *dev = ped_device_get (ln);
77
/* Create a second temporary_disk */
78
char *temporary_disk2 = _create_disk (4096 * 1024);
79
if (temporary_disk2 == NULL) {
80
fail ("Failed to create 2nd temporary disk");
81
goto exit_destroy_dev;
84
/* Remove first temporary disk, and make temporary_disk point to
85
temporary_disk2 (for destroy_disk()). */
86
unlink (temporary_disk);
87
free (temporary_disk);
88
temporary_disk = temporary_disk2;
90
/* Update symlink to point to our new / second temporary disk */
92
snprintf (temp_disk_path, sizeof temp_disk_path, "%s/%s", cwd,
94
res = symlink (temp_disk_path, ln);
96
fail ("could not create 2nd symlink");
97
goto exit_destroy_dev;
100
/* Do something to our PedDevice, if the symlink was resolved,
101
instead of remembering the /dev/mapper/foo name, this will fail */
102
ped_disk_clobber (dev);
105
ped_device_destroy (dev);
112
main (int argc, char **argv)
114
set_program_name (argv[0]);
116
Suite* suite = suite_create ("Symlink");
117
TCase* tcase_symlink = tcase_create ("/dev/mapper symlink");
119
/* Fail when an exception is raised */
120
ped_exception_set_handler (_test_exception_handler);
122
tcase_add_checked_fixture (tcase_symlink, create_disk, destroy_disk);
123
tcase_add_test (tcase_symlink, test_symlink);
124
/* Disable timeout for this test */
125
tcase_set_timeout (tcase_symlink, 0);
126
suite_add_tcase (suite, tcase_symlink);
128
SRunner* srunner = srunner_create (suite);
129
srunner_run_all (srunner, CK_VERBOSE);
131
number_failed = srunner_ntests_failed (srunner);
132
srunner_free (srunner);
134
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;