mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
debug: fix parsing of /proc/self/stat
The code in init_log_file relies on the process name (COMM) to not contain whitespaces. This change fixes it by looking up the right-most parenthesis to safely jump past COMM. For more context see: https://www.openwall.com/lists/oss-security/2022/12/21/6 Code is only used with testing, so it should have no impact on regular users. Reported-by: Hugues Evrard <hevrard@google.com> mm
This commit is contained in:
parent
7ec97ed5f2
commit
c38b668fc3
@ -217,6 +217,45 @@ void init_log_fn(lvm2_log_fn_t log_fn)
|
|||||||
_lvm2_log_fn = log_fn;
|
_lvm2_log_fn = log_fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Read /proc/self/stat to extract pid and starttime */
|
||||||
|
static int _get_pid_starttime(int *pid, unsigned long long *starttime)
|
||||||
|
{
|
||||||
|
static const char statfile[] = "/proc/self/stat";
|
||||||
|
char buf[1024];
|
||||||
|
char *p;
|
||||||
|
int fd;
|
||||||
|
int e;
|
||||||
|
|
||||||
|
if ((fd = open(statfile, O_RDONLY)) == -1) {
|
||||||
|
log_sys_debug("open", statfile);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((e = read(fd, buf, sizeof(buf) - 1)) <= 0)
|
||||||
|
log_sys_debug("read", statfile);
|
||||||
|
|
||||||
|
if (!close(fd))
|
||||||
|
log_sys_debug("close", statfile);
|
||||||
|
|
||||||
|
if (e <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buf[e] = '\0';
|
||||||
|
if ((sscanf(buf, "%d ", pid) == 1) &&
|
||||||
|
/* Jump past COMM, don't use scanf with '%s' since COMM may contain a space. */
|
||||||
|
(p = strrchr(buf, ')')) &&
|
||||||
|
(scanf(++p, " %*c %*d %*d %*d %*d " /* tty_nr */
|
||||||
|
"%*d %*u %*u %*u %*u " /* mjflt */
|
||||||
|
"%*u %*u %*u %*d %*d " /* cstim */
|
||||||
|
"%*d %*d %*d %*d " /* itrealvalue */
|
||||||
|
"%llu", &starttime) == 1))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
log_debug("Cannot parse content of %s.", statfile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Support envvar LVM_LOG_FILE_EPOCH and allow to attach
|
* Support envvar LVM_LOG_FILE_EPOCH and allow to attach
|
||||||
* extra keyword (consist of upto 32 alpha chars) to
|
* extra keyword (consist of upto 32 alpha chars) to
|
||||||
@ -228,11 +267,9 @@ void init_log_fn(lvm2_log_fn_t log_fn)
|
|||||||
*/
|
*/
|
||||||
void init_log_file(const char *log_file, int append)
|
void init_log_file(const char *log_file, int append)
|
||||||
{
|
{
|
||||||
static const char statfile[] = "/proc/self/stat";
|
|
||||||
const char *env;
|
const char *env;
|
||||||
int pid;
|
int pid = 0;
|
||||||
unsigned long long starttime;
|
unsigned long long starttime = 0;
|
||||||
FILE *st;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
_log_file_path[0] = '\0';
|
_log_file_path[0] = '\0';
|
||||||
@ -245,15 +282,9 @@ void init_log_file(const char *log_file, int append)
|
|||||||
goto no_epoch;
|
goto no_epoch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(st = fopen(statfile, "r")))
|
if (!_get_pid_starttime(&pid, &starttime))
|
||||||
log_sys_error("fopen", statfile);
|
log_debug("Failed to obtain pid and starttime.");
|
||||||
else if (fscanf(st, "%d %*s %*c %*d %*d %*d %*d " /* tty_nr */
|
|
||||||
"%*d %*u %*u %*u %*u " /* mjflt */
|
|
||||||
"%*u %*u %*u %*d %*d " /* cstim */
|
|
||||||
"%*d %*d %*d %*d " /* itrealvalue */
|
|
||||||
"%llu", &pid, &starttime) != 2) {
|
|
||||||
log_warn("WARNING: Cannot parse content of %s.", statfile);
|
|
||||||
} else {
|
|
||||||
if (dm_snprintf(_log_file_path, sizeof(_log_file_path),
|
if (dm_snprintf(_log_file_path, sizeof(_log_file_path),
|
||||||
"%s_%s_%d_%llu", log_file, env, pid, starttime) < 0) {
|
"%s_%s_%d_%llu", log_file, env, pid, starttime) < 0) {
|
||||||
log_warn("WARNING: Debug log file path is too long for epoch.");
|
log_warn("WARNING: Debug log file path is too long for epoch.");
|
||||||
@ -262,10 +293,6 @@ void init_log_file(const char *log_file, int append)
|
|||||||
log_file = _log_file_path;
|
log_file = _log_file_path;
|
||||||
append = 1; /* force */
|
append = 1; /* force */
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (st && fclose(st))
|
|
||||||
log_sys_debug("fclose", statfile);
|
|
||||||
|
|
||||||
if ((env = getenv("LVM_LOG_FILE_MAX_LINES"))) {
|
if ((env = getenv("LVM_LOG_FILE_MAX_LINES"))) {
|
||||||
if (sscanf(env, FMTu64, &_log_file_max_lines) != 1) {
|
if (sscanf(env, FMTu64, &_log_file_max_lines) != 1) {
|
||||||
@ -896,4 +923,3 @@ uint32_t log_journal_str_to_val(const char *str)
|
|||||||
log_warn("Ignoring unrecognized journal value.");
|
log_warn("Ignoring unrecognized journal value.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user