mirror of
https://github.com/AuxXxilium/kmod.git
synced 2024-11-23 23:10:53 +07:00
depmod: prevent module dependency files corruption due to parallel invocation.
Depmod does not use unique filename for temporary files. There is no guarantee the user does not attempt to run mutiple depmod processes in parallel. If that happens a temporary file might be created by depmod(1st), truncated by depmod(2nd), and renamed to final name by depmod(1st) resulting in corrupted file seen by user. Due to missing mkstempat() this is more complex than it should be. Adding PID and timestamp to the filename should be reasonably reliable. Adding O_EXCL as mkstemp does fails creating the file rather than corrupting existing file. Signed-off-by: Michal Suchanek <msuchanek@suse.de>
This commit is contained in:
parent
c2996b5fa8
commit
a06bacf500
@ -29,6 +29,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include <sys/utsname.h>
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
#include <shared/array.h>
|
#include <shared/array.h>
|
||||||
@ -2398,6 +2399,9 @@ static int depmod_output(struct depmod *depmod, FILE *out)
|
|||||||
};
|
};
|
||||||
const char *dname = depmod->cfg->dirname;
|
const char *dname = depmod->cfg->dirname;
|
||||||
int dfd, err = 0;
|
int dfd, err = 0;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
|
||||||
if (out != NULL)
|
if (out != NULL)
|
||||||
dfd = -1;
|
dfd = -1;
|
||||||
@ -2416,11 +2420,12 @@ static int depmod_output(struct depmod *depmod, FILE *out)
|
|||||||
int r, ferr;
|
int r, ferr;
|
||||||
|
|
||||||
if (fp == NULL) {
|
if (fp == NULL) {
|
||||||
int flags = O_CREAT | O_TRUNC | O_WRONLY;
|
int flags = O_CREAT | O_EXCL | O_WRONLY;
|
||||||
int mode = 0644;
|
int mode = 0644;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
snprintf(tmp, sizeof(tmp), "%s.tmp", itr->name);
|
snprintf(tmp, sizeof(tmp), "%s.%i.%li.%li", itr->name, getpid(),
|
||||||
|
tv.tv_usec, tv.tv_sec);
|
||||||
fd = openat(dfd, tmp, flags, mode);
|
fd = openat(dfd, tmp, flags, mode);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
ERR("openat(%s, %s, %o, %o): %m\n",
|
ERR("openat(%s, %s, %o, %o): %m\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user