Avoid deadlock between udev probing stage2 image and stage1 mounting it #1

Merged
asheplyakov merged 2 commits from fix-40687 into master 2021-08-31 15:24:04 +03:00
3 changed files with 46 additions and 1 deletions

View File

@ -31,6 +31,7 @@
#include "log.h"
#include "mount.h"
#include "modules.h"
#include "udev.h"
#include "lomount.h"
@ -98,6 +99,13 @@ set_loop (const char *device, const char *file)
close(ffd);
return 1;
}
/* Note: LOOP_SET_FD triggers change event. While processing it
* udev reads the loop device with builtin blkid. This can race
* with subsequent access by kernel due to LOOP_SET_STATUS (or
* mounting the loop device). Therefore give udev a chance to
* process the event without concurrent access to the loop device
*/
udev_settle();
if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
(void) ioctl (fd, LOOP_CLR_FD, 0);
@ -106,8 +114,21 @@ set_loop (const char *device, const char *file)
return 1;
}
/* Same here: LOOP_SET_STATUS triggers change event, give udev
* a chance to process it without concurrent access to the loop
* device. In other words, prevent the caller of this function
* from mounting the device while udev still running blkid on it
*/
udev_settle();
close(fd);
close(ffd);
/* udev might be monitoring loopback device (with fanotify) and
* will synthesize a change event on close. Give udev some time
* to process without racing with the caller of this function
* (which is going to mount the newly configured loopback device)
*/
udev_settle();
return 0;
}

View File

@ -3,7 +3,7 @@
%def_with splash
Name: propagator
Version: 20210721
Version: 20210823
Release: alt1
Summary: 'Early userspace' set of binaries
@ -39,6 +39,9 @@ including init and various helpers for hw probing and bootstrapping.
%_sbindir/propagator
%changelog
* Mon Aug 23 2021 Alexey Sheplyakov <asheplyakov@altlinux.org> 20210823-alt1
- Avoid deadlock between udev probing stage2 and stage1 mounting it (closes: #40687)
* Wed Jul 21 2021 Egor Ignatov <egori@altlinux.org> 20210721-alt1
- mkmodpack: include leading directories for firmware files
The kernel needs leading directories in the cpio archive when

21
tools.c
View File

@ -47,6 +47,7 @@
#ifdef SPAWN_SPLASH
#include "init.h"
#endif
#include "udev.h"
/* If we have more than that amount of memory (in bytes), we assume we can load the second stage as a ramdisk */
#define MEM_LIMIT_RAMDISK (256 * 1024 * 1024)
@ -650,6 +651,13 @@ int do_losetup(char * device, char * target)
close( targfd );
return -1;
}
/* Note: LOOP_SET_FD triggers change event. While processing it
* udev reads the loop device with builtin blkid. This can race
* with subsequent access by kernel due to LOOP_SET_STATUS (or
* mounting the loop device). Therefore give udev a chance to
* process the event without concurrent access to the loop device
*/
udev_settle();
memset(&loopInfo, 0, sizeof(loopInfo));
strcpy(loopInfo.lo_name, target);
@ -657,7 +665,20 @@ int do_losetup(char * device, char * target)
if ( ioctl(loopfd, LOOP_SET_STATUS, &loopInfo) < 0 )
log_message( "losetup: error setting up loopback device: %s", strerror(errno) );
/* Same here: LOOP_SET_STATUS triggers change event, give udev
* a chance to process it without concurrent access to the loop
* device. In other words, prevent the caller of this function
* from mounting the device while udev still running blkid on it
*/
udev_settle();
close( loopfd );
/* udev might be monitoring loopback device (with fanotify) and
* will synthesize a change event on close. Give udev some time
* to process without racing with the caller of this function
* (which is going to mount the newly configured loopback device)
*/
udev_settle();
close( targfd );
return 0;
}