[packages/dovecot] Rel 2; handle /proc/self/status from newer kernels

arekm arekm at pld-linux.org
Wed Oct 18 11:31:09 CEST 2023


commit 11ff587d4ec1df193267e500e7d97d5b6a61bbb8
Author: Arkadiusz Miśkiewicz <arekm at maven.pl>
Date:   Wed Oct 18 11:30:59 2023 +0200

    Rel 2; handle /proc/self/status from newer kernels

 dovecot.spec      |   6 +-
 proc-status.patch | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 239 insertions(+), 3 deletions(-)
---
diff --git a/dovecot.spec b/dovecot.spec
index 42ed6b9..50def89 100644
--- a/dovecot.spec
+++ b/dovecot.spec
@@ -13,7 +13,7 @@ Summary:	IMAP and POP3 server written with security primarily in mind
 Summary(pl.UTF-8):	Serwer IMAP i POP3 pisany głównie z myślą o bezpieczeństwie
 Name:		dovecot
 Version:	2.3.21
-Release:	1
+Release:	2
 Epoch:		1
 License:	MIT (libraries), LGPL v2.1 (the rest)
 Group:		Networking/Daemons
@@ -26,7 +26,7 @@ Source4:	%{name}.tmpfiles
 Patch0:		%{name}-config.patch
 Patch1:		%{name}-rpath.patch
 Patch2:		%{name}-shebang.patch
-
+Patch3:         proc-status.patch
 Patch4:		openssl3.patch
 URL:		http://dovecot.org/
 BuildRequires:	autoconf
@@ -168,7 +168,7 @@ Pakiet programistyczny do tworzenia wtyczek dla Dovecota.
 %patch0 -p1
 %patch1 -p1
 %patch2 -p1
-
+%patch3 -p1
 %patch4 -p1
 
 %{__sed} -i 's,/usr/lib/dovecot,%{_libdir}/dovecot,g' doc/example-config/*.conf doc/example-config/conf.d/*.conf
diff --git a/proc-status.patch b/proc-status.patch
new file mode 100644
index 0000000..1b7d021
--- /dev/null
+++ b/proc-status.patch
@@ -0,0 +1,236 @@
+From f359c6ee179aad5e077711c188fc8422106cbead Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at open-xchange.com>
+Date: Tue, 21 Mar 2023 08:55:55 +0200
+Subject: [PATCH 1/3] lib: process-stat - Use buffer_append_full_istream() to
+ read files
+
+---
+ src/lib/process-stat.c | 84 ++++++++++++++++++++++--------------------
+ 1 file changed, 44 insertions(+), 40 deletions(-)
+
+diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c
+index 782503e60b..60eddbc3ec 100644
+--- a/src/lib/process-stat.c
++++ b/src/lib/process-stat.c
+@@ -1,6 +1,9 @@
+ /* Copyright (c) 2008-2021 Dovecot authors, see the included COPYING file */
+ 
+ #include "lib.h"
++#include "buffer.h"
++#include "str.h"
++#include "istream.h"
+ #include "process-stat.h"
+ #include "time-util.h"
+ #include <limits.h>
+@@ -12,8 +15,12 @@
+ #include <stdio.h>
+ 
+ #define PROC_STAT_PATH "/proc/self/stat"
++#define PROC_STAT_MAX_SIZE 1024
+ #define PROC_STATUS_PATH "/proc/self/status"
++#define PROC_STATUS_MAX_SIZE 2048
+ #define PROC_IO_PATH "/proc/self/io"
++#define PROC_IO_MAX_SIZE 1024
++#define PROC_BUFFER_INITIAL_SIZE 512
+ 
+ static const uint64_t stat_undefined = 0xFFFFFFFFFFFFFFFF;
+ 
+@@ -71,39 +78,38 @@ static int open_fd(const char *path, struct event *event)
+ }
+ 
+ static int
+-read_file(int fd, const char *path, char *buf_r, size_t buf_size, struct event *event)
++read_file_buffer(const char *path, string_t *buf, size_t max_size, struct event *event)
+ {
+-	ssize_t ret;
+-	ret = read(fd, buf_r, buf_size);
+-	if (ret <= 0) {
+-		if (ret == -1)
+-			e_error(event, "read(%s) failed: %m", path);
+-		else
+-			e_error(event, "read(%s) returned EOF", path);
+-	} else if (ret == (ssize_t)buf_size) {
+-		e_error(event, "%s is larger than expected", path);
+-		buf_r[buf_size - 1] = '\0';
+-	} else {
+-		buf_r[ret] = '\0';
++	const char *error;
++	int fd = open_fd(path, event);
++	if (fd < 0)
++		return -1;
++	struct istream *is = i_stream_create_fd_autoclose(&fd, max_size);
++	i_stream_set_name(is, path);
++	enum buffer_append_result res =
++		buffer_append_full_istream(buf, is, max_size, &error);
++	i_stream_unref(&is);
++	if (res == BUFFER_APPEND_READ_MAX_SIZE)
++		e_error(event, "%s is larger than expected (%zu)", path, max_size);
++	else if (res != BUFFER_APPEND_OK) {
++		e_error(event, "read(%s) failed: %s", path, error);
++		return -1;
+ 	}
+-	i_close_fd(&fd);
+-	return ret <= 0 ? -1 : 0;
++	return 0;
+ }
+ 
+ static int parse_key_val_file(const char *path,
++			      size_t max_size,
+ 			      struct key_val *fields,
+ 			      struct event *event)
+ {
+-	char buf[2048];
+-	int fd;
+-
+-	fd = open_fd(path, event);
+-	if (fd == -1 || read_file(fd, path, buf, sizeof(buf), event) < 0) {
++	string_t *buf = t_str_new(PROC_BUFFER_INITIAL_SIZE);
++	if (read_file_buffer(path, buf, max_size, event) < 0) {
+ 		for (; fields->key != NULL; fields++)
+ 			*fields->value = stat_undefined;
+ 		return -1;
+ 	}
+-	buffer_parse(buf, fields);
++	buffer_parse(str_c(buf), fields);
+ 	return 0;
+ }
+ 
+@@ -117,7 +123,8 @@ static int parse_proc_io(struct process_stat *stat_r, struct event *event)
+ 		{ NULL, NULL, 0 },
+ 	};
+ 	if (stat_r->proc_io_failed ||
+-	    parse_key_val_file(PROC_IO_PATH, fields, event) < 0) {
++	    parse_key_val_file(PROC_IO_PATH, PROC_IO_MAX_SIZE, fields,
++			       event) < 0) {
+ 		stat_r->proc_io_failed = TRUE;
+ 		return -1;
+ 	}
+@@ -132,7 +139,8 @@ static int parse_proc_status(struct process_stat *stat_r, struct event *event)
+ 		{ NULL, NULL, 0 },
+ 	};
+ 	if (stat_r->proc_status_failed ||
+-	    parse_key_val_file(PROC_STATUS_PATH, fields, event) < 0) {
++	    parse_key_val_file(PROC_STATUS_PATH, PROC_STATUS_MAX_SIZE,
++			       fields, event) < 0) {
+ 		stat_r->proc_status_failed = TRUE;
+ 		return -1;
+ 	}
+@@ -156,8 +164,7 @@ static int stat_get_rusage(struct process_stat *stat_r)
+ 
+ static int parse_stat_file(struct process_stat *stat_r, struct event *event)
+ {
+-	int fd = -1;
+-	char buf[1024];
++	string_t *buf = t_str_new(PROC_BUFFER_INITIAL_SIZE);
+ 	unsigned int i;
+ 	const char *const *tmp;
+ 	struct {
+@@ -171,9 +178,8 @@ static int parse_stat_file(struct process_stat *stat_r, struct event *event)
+ 		{ &stat_r->vsz, 22 },
+ 		{ &stat_r->rss, 23 },
+ 	};
+-	if (!stat_r->proc_stat_failed)
+-		fd = open_fd(PROC_STAT_PATH, event);
+-	if (fd == -1) {
++	if (stat_r->proc_stat_failed ||
++	    read_file_buffer(PROC_STAT_PATH, buf, PROC_STAT_MAX_SIZE, event) < 0) {
+ 		stat_r->proc_stat_failed = TRUE;
+ 		/* vsz and rss are not provided by getrusage(), setting to undefined */
+ 		stat_r->vsz = stat_undefined;
+@@ -187,11 +193,7 @@ static int parse_stat_file(struct process_stat *stat_r, struct event *event)
+ 		}
+ 		return 0;
+ 	}
+-	if (read_file(fd, PROC_STAT_PATH, buf, sizeof(buf), event) < 0) {
+-		stat_r->proc_stat_failed = TRUE;
+-		return -1;
+-	}
+-	tmp = t_strsplit(buf, " ");
++	tmp = t_strsplit(str_c(buf), " ");
+ 	unsigned int tmp_count = str_array_length(tmp);
+ 
+ 	for (i = 0; i < N_ELEMENTS(fields); i++) {
+@@ -208,13 +210,15 @@ static int parse_all_stats(struct process_stat *stat_r, struct event *event)
+ {
+ 	bool has_fields = FALSE;
+ 
+-	if (parse_stat_file(stat_r, event) == 0)
+-		has_fields = TRUE;
+-	if (parse_proc_io(stat_r, event) == 0)
+-		has_fields = TRUE;
+-	if ((!stat_r->proc_stat_failed || stat_r->rusage_failed) &&
+-	    parse_proc_status(stat_r, event) == 0)
+-		has_fields = TRUE;
++	T_BEGIN {
++		if (parse_stat_file(stat_r, event) == 0)
++			has_fields = TRUE;
++		if (parse_proc_io(stat_r, event) == 0)
++			has_fields = TRUE;
++		if ((!stat_r->proc_stat_failed || stat_r->rusage_failed) &&
++		    parse_proc_status(stat_r, event) == 0)
++			has_fields = TRUE;
++	} T_END;
+ 
+ 	if (has_fields)
+ 		return 0;
+
+From 218a79a48bb0e5d2be44bb46c51836fd406b0c50 Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at open-xchange.com>
+Date: Tue, 21 Mar 2023 09:05:12 +0200
+Subject: [PATCH 2/3] lib: process-stat - Increase maximum /proc/self/status
+ size
+
+Kernel 6.x has larger status file.
+---
+ src/lib/process-stat.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c
+index 60eddbc3ec..1d23c89964 100644
+--- a/src/lib/process-stat.c
++++ b/src/lib/process-stat.c
+@@ -17,7 +17,7 @@
+ #define PROC_STAT_PATH "/proc/self/stat"
+ #define PROC_STAT_MAX_SIZE 1024
+ #define PROC_STATUS_PATH "/proc/self/status"
+-#define PROC_STATUS_MAX_SIZE 2048
++#define PROC_STATUS_MAX_SIZE 4096
+ #define PROC_IO_PATH "/proc/self/io"
+ #define PROC_IO_MAX_SIZE 1024
+ #define PROC_BUFFER_INITIAL_SIZE 512
+
+From d93c31d51b05d43eaa6eeef9cdc0f7a4157f7d0e Mon Sep 17 00:00:00 2001
+From: Aki Tuomi <aki.tuomi at open-xchange.com>
+Date: Tue, 21 Mar 2023 09:13:35 +0200
+Subject: [PATCH 3/3] lib: process-stat - Use eacces_error_get() for EACCES
+ errno
+
+This tells better why the open failed.
+---
+ src/lib/process-stat.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/process-stat.c b/src/lib/process-stat.c
+index 1d23c89964..454d9335d2 100644
+--- a/src/lib/process-stat.c
++++ b/src/lib/process-stat.c
+@@ -4,6 +4,7 @@
+ #include "buffer.h"
+ #include "str.h"
+ #include "istream.h"
++#include "eacces-error.h"
+ #include "process-stat.h"
+ #include "time-util.h"
+ #include <limits.h>
+@@ -69,8 +70,10 @@ static int open_fd(const char *path, struct event *event)
+ 		errno = EACCES;
+ 	}
+ 	if (fd == -1) {
+-		if (errno == ENOENT || errno == EACCES)
++		if (errno == ENOENT)
+ 			e_debug(event, "open(%s) failed: %m", path);
++		else if (errno == EACCES)
++			e_debug(event, "%s", eacces_error_get("open", path));
+ 		else
+ 			e_error(event, "open(%s) failed: %m", path);
+ 	}
================================================================

---- gitweb:

http://git.pld-linux.org/gitweb.cgi/packages/dovecot.git/commitdiff/11ff587d4ec1df193267e500e7d97d5b6a61bbb8



More information about the pld-cvs-commit mailing list