lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251103052450.1028813-2-badhri@google.com>
Date: Mon,  3 Nov 2025 05:24:50 +0000
From: Badhri Jagan Sridharan <badhri@...gle.com>
To: heikki.krogerus@...ux.intel.com, gregkh@...uxfoundation.org, 
	badhri@...gle.com
Cc: amitsd@...gle.com, kyletso@...gle.com, rdbabiera@...gle.com, 
	linux-kernel@...r.kernel.org, linux-usb@...r.kernel.org
Subject: [PATCH v2 1/1] tcpm: Wraparound tcpm log and dont clear them when read

TCPM log do not wraparound by default and gets cleared when read.
This results in logs overflowing over time and the recent logs
containing relevant context to debug get dropped. Change this behavior
to wraparound the log by default and do not clear the log when dumped.

Adding the Kconfig option, TCPM_LOG_DISABLE_WRAPAROUND,
to disable wrap around and clear the log when read. Also adding a
a debugfs file node, tcpm_log_disable_wraparound, to switch between
the two during run time.

Signed-off-by: Badhri Jagan Sridharan <badhri@...gle.com>
Reviewed-by: Kyle Tso <kyletso@...gle.com>
Reviewed-by: Amit Sunil Dhamne <amitsd@...gle.com>
---
Changes since v1:
* Make wrapping around when full as the default behavior.
* Added a Kconfig and a debugfs node option to switch between the two
  behaviors.
---
 drivers/usb/typec/tcpm/Kconfig |  8 ++++++
 drivers/usb/typec/tcpm/tcpm.c  | 51 ++++++++++++++++++++++++++++++++--
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/typec/tcpm/Kconfig b/drivers/usb/typec/tcpm/Kconfig
index 8cdd84ca5d6f..4bb69f66c7bb 100644
--- a/drivers/usb/typec/tcpm/Kconfig
+++ b/drivers/usb/typec/tcpm/Kconfig
@@ -11,6 +11,14 @@ config TYPEC_TCPM
 
 if TYPEC_TCPM
 
+config TCPM_LOG_DISABLE_WRAPAROUND
+	bool "Disable TCPM log wraparound"
+	depends on DEBUG_FS
+	help
+	  When set, TCPM log do not wraparound and clears when dumped.
+	  When not set(i.e. default), TCPM log wraps around when full and do
+	  not clear when dumped.
+
 config TYPEC_TCPCI
 	tristate "Type-C Port Controller Interface driver"
 	depends on I2C
diff --git a/drivers/usb/typec/tcpm/tcpm.c b/drivers/usb/typec/tcpm/tcpm.c
index 4ca2746ce16b..2df21e5b5dff 100644
--- a/drivers/usb/typec/tcpm/tcpm.c
+++ b/drivers/usb/typec/tcpm/tcpm.c
@@ -591,6 +591,7 @@ struct tcpm_port {
 	int logbuffer_head;
 	int logbuffer_tail;
 	u8 *logbuffer[LOG_BUFFER_ENTRIES];
+	bool log_disable_wraparound;
 #endif
 };
 
@@ -723,7 +724,7 @@ static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args)
 
 	vsnprintf(tmpbuffer, sizeof(tmpbuffer), fmt, args);
 
-	if (tcpm_log_full(port)) {
+	if (port->log_disable_wraparound && tcpm_log_full(port)) {
 		port->logbuffer_head = max(port->logbuffer_head - 1, 0);
 		strcpy(tmpbuffer, "overflow");
 	}
@@ -748,6 +749,10 @@ static void _tcpm_log(struct tcpm_port *port, const char *fmt, va_list args)
 		  tmpbuffer);
 	port->logbuffer_head = (port->logbuffer_head + 1) % LOG_BUFFER_ENTRIES;
 
+	if (!port->log_disable_wraparound && port->logbuffer_head ==
+	    port->logbuffer_tail)
+		port->logbuffer_tail =
+			(port->logbuffer_tail + 1) % LOG_BUFFER_ENTRIES;
 abort:
 	mutex_unlock(&port->logbuffer_lock);
 }
@@ -863,7 +868,7 @@ static int tcpm_debug_show(struct seq_file *s, void *v)
 		seq_printf(s, "%s\n", port->logbuffer[tail]);
 		tail = (tail + 1) % LOG_BUFFER_ENTRIES;
 	}
-	if (!seq_has_overflowed(s))
+	if (port->log_disable_wraparound && !seq_has_overflowed(s))
 		port->logbuffer_tail = tail;
 	mutex_unlock(&port->logbuffer_lock);
 
@@ -871,15 +876,57 @@ static int tcpm_debug_show(struct seq_file *s, void *v)
 }
 DEFINE_SHOW_ATTRIBUTE(tcpm_debug);
 
+static int tcpm_log_disable_wraparound_show(struct seq_file *s, void *v)
+{
+	struct tcpm_port *port = s->private;
+
+	mutex_lock(&port->logbuffer_lock);
+	seq_printf(s, "%d\n", port->log_disable_wraparound ? 1 : 0);
+	mutex_unlock(&port->logbuffer_lock);
+
+	return 0;
+}
+
+static ssize_t tcpm_log_disable_wraparound_write(struct file *file,
+						 const char __user *user_buf,
+						 size_t count, loff_t *ppos)
+{
+	struct seq_file *seq_f = file->private_data;
+	bool log_disable_wraparound;
+	struct tcpm_port *port;
+	int err;
+
+	port = seq_f->private;
+	err = kstrtobool_from_user(user_buf, count, &log_disable_wraparound);
+	if (err)
+		return err;
+
+	mutex_lock(&port->logbuffer_lock);
+	if (port->log_disable_wraparound == log_disable_wraparound)
+		goto exit;
+
+	port->logbuffer_tail = port->logbuffer_head;
+	port->log_disable_wraparound = log_disable_wraparound;
+exit:
+	mutex_unlock(&port->logbuffer_lock);
+	return count;
+}
+
+DEFINE_SHOW_STORE_ATTRIBUTE(tcpm_log_disable_wraparound);
+
 static void tcpm_debugfs_init(struct tcpm_port *port)
 {
 	char name[NAME_MAX];
 
 	mutex_init(&port->logbuffer_lock);
+	port->log_disable_wraparound =
+		IS_ENABLED(CONFIG_TCPM_LOG_DISABLE_WRAPAROUND);
 	snprintf(name, NAME_MAX, "tcpm-%s", dev_name(port->dev));
 	port->dentry = debugfs_create_dir(name, usb_debug_root);
 	debugfs_create_file("log", S_IFREG | 0444, port->dentry, port,
 			    &tcpm_debug_fops);
+	debugfs_create_file("tcpm_log_disable_wraparound", 0644, port->dentry,
+			    port, &tcpm_log_disable_wraparound_fops);
 }
 
 static void tcpm_debugfs_exit(struct tcpm_port *port)
-- 
2.51.1.930.gacf6e81ea2-goog


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ