mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-02-17 22:05:18 -05:00
ucm: fix TOCTOU race condition
Separately checking the state of a file before operating on it may allow an attacker to modify the file between the two operations. Fix by calling readlink first. If that fails, then path should not be a symbolic link and we call open() followed by fstat(). open() with O_NOFOLLOW will return an error if the file is a symlink. Signed-off-by: Mingjie Shen <shen497@purdue.edu>
This commit is contained in:
parent
ed6b07084b
commit
9184bb0db0
1 changed files with 16 additions and 14 deletions
|
|
@ -518,30 +518,32 @@ static char *rval_sysfs(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED, const char
|
||||||
if (id[0] == '/')
|
if (id[0] == '/')
|
||||||
id++;
|
id++;
|
||||||
snprintf(path, sizeof(path), "%s/%s", e, id);
|
snprintf(path, sizeof(path), "%s/%s", e, id);
|
||||||
if (lstat64(path, &sb) != 0)
|
len = readlink(path, link, sizeof(link) - 1);
|
||||||
return NULL;
|
if (len > 0) {
|
||||||
if (S_ISLNK(sb.st_mode)) {
|
|
||||||
len = readlink(path, link, sizeof(link) - 1);
|
|
||||||
if (len <= 0) {
|
|
||||||
uc_error("sysfs: cannot read link '%s' (%d)", path, errno);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
link[len] = '\0';
|
link[len] = '\0';
|
||||||
e = strrchr(link, '/');
|
e = strrchr(link, '/');
|
||||||
if (e)
|
if (e)
|
||||||
return strdup(e + 1);
|
return strdup(e + 1);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (S_ISDIR(sb.st_mode))
|
fd = open(path, O_RDONLY | O_NOFOLLOW);
|
||||||
return NULL;
|
|
||||||
if ((sb.st_mode & S_IRUSR) == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
fd = open(path, O_RDONLY);
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
uc_error("sysfs open failed for '%s' (%d)", path, errno);
|
uc_error("sysfs open failed for '%s' (%d)", path, errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
if (fstat64(fd, &sb) != 0) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (S_ISDIR(sb.st_mode)) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ((sb.st_mode & S_IRUSR) == 0) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
len = read(fd, path, sizeof(path)-1);
|
len = read(fd, path, sizeof(path)-1);
|
||||||
close(fd);
|
close(fd);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue