From 08ae2487b202ff92b1c6393f18630895f39460bf Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Mon, 6 Jan 2025 21:25:00 +0900
Subject: [PATCH] tomoyo: automatically use patterns for several situations in
 learning mode

The "file_pattern" keyword was used for automatically recording patternized
pathnames when using the learning mode. This keyword was removed in TOMOYO
2.4 because it is impossible to predefine all possible pathname patterns.

However, since the numeric part of proc:/$PID/ , pipe:[$INO] and
socket:[$INO] has no meaning except $PID == 1, automatically replacing
the numeric part with \$ pattern helps reducing frequency of restarting
the learning mode due to hitting the quota.

Since replacing one digit with \$ pattern requires enlarging string buffer,
and several programs access only $PID == 1, replace only two or more digits
with \$ pattern.

Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 security/tomoyo/common.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/security/tomoyo/common.c b/security/tomoyo/common.c
index 972664962e8f6..d9fa696321475 100644
--- a/security/tomoyo/common.c
+++ b/security/tomoyo/common.c
@@ -2024,6 +2024,36 @@ static void tomoyo_add_entry(struct tomoyo_domain_info *domain, char *header)
 	if (!buffer)
 		return;
 	snprintf(buffer, len - 1, "%s", cp);
+	if (*cp == 'f' && strchr(buffer, ':')) {
+		/* Automatically replace 2 or more digits with \$ pattern. */
+		char *cp2;
+
+		/* e.g. file read proc:/$PID/stat */
+		cp = strstr(buffer, " proc:/");
+		if (cp && simple_strtoul(cp + 7, &cp2, 10) >= 10 && *cp2 == '/') {
+			*(cp + 7) = '\\';
+			*(cp + 8) = '$';
+			memmove(cp + 9, cp2, strlen(cp2) + 1);
+			goto ok;
+		}
+		/* e.g. file ioctl pipe:[$INO] $CMD */
+		cp = strstr(buffer, " pipe:[");
+		if (cp && simple_strtoul(cp + 7, &cp2, 10) >= 10 && *cp2 == ']') {
+			*(cp + 7) = '\\';
+			*(cp + 8) = '$';
+			memmove(cp + 9, cp2, strlen(cp2) + 1);
+			goto ok;
+		}
+		/* e.g. file ioctl socket:[$INO] $CMD */
+		cp = strstr(buffer, " socket:[");
+		if (cp && simple_strtoul(cp + 9, &cp2, 10) >= 10 && *cp2 == ']') {
+			*(cp + 9) = '\\';
+			*(cp + 10) = '$';
+			memmove(cp + 11, cp2, strlen(cp2) + 1);
+			goto ok;
+		}
+	}
+ok:
 	if (realpath)
 		tomoyo_addprintf(buffer, len, " exec.%s", realpath);
 	if (argv0)
-- 
GitLab