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] [day] [month] [year] [list]
Message-ID: <yu7cnttyvq7eckgspgy7wbxvdbhk2oydbnwqex5ftquxejmywp@3wyhukdlfokj>
Date: Wed, 19 Nov 2025 09:04:12 -0800
From: Josh Poimboeuf <jpoimboe@...nel.org>
To: Peter Zijlstra <peterz@...radead.org>
Cc: Jiri Slaby <jirislaby@...nel.org>, x86@...nel.org, 
	linux-kernel@...r.kernel.org, Greg Kroah-Hartman <gregkh@...uxfoundation.org>, 
	kernel test robot <lkp@...el.com>
Subject: Re: [PATCH] serial: icom: Fix namespace collision and startup()
 section placement with -ffunction-sections

On Wed, Nov 19, 2025 at 09:44:35AM +0100, Peter Zijlstra wrote:
> On Wed, Nov 19, 2025 at 09:43:15AM +0100, Peter Zijlstra wrote:
> > On Wed, Nov 19, 2025 at 07:58:05AM +0100, Jiri Slaby wrote:
> > > On 19. 11. 25, 7:27, Josh Poimboeuf wrote:
> > > > When compiling the kernel with -ffunction-sections (e.g., for LTO,
> > > > livepatch, dead code elimination, AutoFDO, or Propeller), the startup()
> > > > function gets compiled into the .text.startup section.  In some cases it
> > > > can even be cloned into .text.startup.constprop.0 or
> > > > .text.startup.isra.0.
> > > > 
> > > > However, the .text.startup and .text.startup.* section names are already
> > > > reserved for use by the compiler for __attribute__((constructor)) code.
> > > > 
> > > > This naming conflict causes the vmlinux linker script to wrongly place
> > > > startup() function code in .init.text, which gets freed during boot.
> > > 
> > > This sounds rather error-prone. What are the patterns supposed to match
> > > actually? Can't *those* real victims™ be renamed to something less common
> > > instead?
> > 
> > Yeah, this is a terrible mess. The problem is that when linking objects
> > build with and without -ffunction-sections you can no longer uniquely
> > identify what's what :-(
> > 
> > As long as its consistently one or the other it works, but if you mix
> > them constructors and normal function like this get mixed up.
> > 
> > In another thread I've suggested this might be a toolchain bug, but even
> > if they agree and fix it, we still stuck with the old compilers. And I'm
> > not sure the toolchain people are agreeing there's anything wrong here
> > -- the argument is that you shouldn't be mixing this or somesuch.
> > 
> > Anyway, objtool has a warning for this, so new occurrences should be
> > flagged before they get introduced. But yes, we need to make the tree
> > clean first.
> 
> Also, that objtool warning only really works architectures that have
> objtool on, other archs can indeed silently create fail :-(

Yeah, that is indeed unfortunate.  Perhaps we should move this check out
of objtool and just make it some kind of script check like so?

  nm vmlinux.o | awk '$2 ~ /^[TtWw]$/ {print $3}' | grep -E '^(startup|exit|split|unlikely|hot|unknown)(\.|$)'

I've got some more renames pending (see below), will post proper patches
in a bit.

diff --git a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
index 6fc39ab95e46..6050637a0def 100644
--- a/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
+++ b/drivers/staging/media/atomisp/i2c/atomisp-gc2235.c
@@ -491,7 +491,7 @@ static int gc2235_s_power(struct v4l2_subdev *sd, int on)
 	return ret;
 }
 
-static int startup(struct v4l2_subdev *sd)
+static int gc2235_startup(struct v4l2_subdev *sd)
 {
 	struct gc2235_device *dev = to_gc2235_sensor(sd);
 	struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -556,7 +556,7 @@ static int gc2235_set_fmt(struct v4l2_subdev *sd,
 		return 0;
 	}
 
-	ret = startup(sd);
+	ret = gc2235_startup(sd);
 	if (ret) {
 		dev_err(&client->dev, "gc2235 startup err\n");
 		goto err;
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index 5af46442a792..81eaca751541 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -438,7 +438,7 @@ static irqreturn_t ser_tx_int(int irq, void *dev_id)
  * ---------------------------------------------------------------
  */
 
-static int startup(struct tty_struct *tty, struct serial_state *info)
+static int rs_startup(struct tty_struct *tty, struct serial_state *info)
 {
 	struct tty_port *port = &info->tport;
 	unsigned long flags;
@@ -513,7 +513,7 @@ static int startup(struct tty_struct *tty, struct serial_state *info)
  * This routine will shutdown a serial port; interrupts are disabled, and
  * DTR is dropped if the hangup on close termio flag is on.
  */
-static void shutdown(struct tty_struct *tty, struct serial_state *info)
+static void rs_shutdown(struct tty_struct *tty, struct serial_state *info)
 {
 	unsigned long	flags;
 
@@ -975,7 +975,7 @@ static int set_serial_info(struct tty_struct *tty, struct serial_struct *ss)
 			change_speed(tty, state, NULL);
 		}
 	} else
-		retval = startup(tty, state);
+		retval = rs_startup(tty, state);
 	tty_unlock(tty);
 	return retval;
 }
@@ -1251,9 +1251,9 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
 		 */
 		rs_wait_until_sent(tty, state->timeout);
 	}
-	shutdown(tty, state);
+	rs_shutdown(tty, state);
 	rs_flush_buffer(tty);
-		
+
 	tty_ldisc_flush(tty);
 	port->tty = NULL;
 
@@ -1325,7 +1325,7 @@ static void rs_hangup(struct tty_struct *tty)
 	struct serial_state *info = tty->driver_data;
 
 	rs_flush_buffer(tty);
-	shutdown(tty, info);
+	rs_shutdown(tty, info);
 	info->tport.count = 0;
 	tty_port_set_active(&info->tport, false);
 	info->tport.tty = NULL;
@@ -1349,7 +1349,7 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
 	port->tty = tty;
 	tty->driver_data = info;
 
-	retval = startup(tty, info);
+	retval = rs_startup(tty, info);
 	if (retval) {
 		return retval;
 	}
diff --git a/drivers/tty/synclink_gt.c b/drivers/tty/synclink_gt.c
index 3865b10d2d43..9d591fb291fd 100644
--- a/drivers/tty/synclink_gt.c
+++ b/drivers/tty/synclink_gt.c
@@ -407,9 +407,9 @@ static void  wr_reg32(struct slgt_info *info, unsigned int addr, __u32 value);
 
 static void  msc_set_vcr(struct slgt_info *info);
 
-static int  startup(struct slgt_info *info);
+static int  startup_hw(struct slgt_info *info);
 static int  block_til_ready(struct tty_struct *tty, struct file * filp,struct slgt_info *info);
-static void shutdown(struct slgt_info *info);
+static void shutdown_hw(struct slgt_info *info);
 static void program_hw(struct slgt_info *info);
 static void change_params(struct slgt_info *info);
 
@@ -622,7 +622,7 @@ static int open(struct tty_struct *tty, struct file *filp)
 
 	if (info->port.count == 1) {
 		/* 1st open on this device, init hardware */
-		retval = startup(info);
+		retval = startup_hw(info);
 		if (retval < 0) {
 			mutex_unlock(&info->port.mutex);
 			goto cleanup;
@@ -666,7 +666,7 @@ static void close(struct tty_struct *tty, struct file *filp)
 	flush_buffer(tty);
 	tty_ldisc_flush(tty);
 
-	shutdown(info);
+	shutdown_hw(info);
 	mutex_unlock(&info->port.mutex);
 
 	tty_port_close_end(&info->port, tty);
@@ -687,7 +687,7 @@ static void hangup(struct tty_struct *tty)
 	flush_buffer(tty);
 
 	mutex_lock(&info->port.mutex);
-	shutdown(info);
+	shutdown_hw(info);
 
 	spin_lock_irqsave(&info->port.lock, flags);
 	info->port.count = 0;
@@ -1445,7 +1445,7 @@ static int hdlcdev_open(struct net_device *dev)
 	spin_unlock_irqrestore(&info->netlock, flags);
 
 	/* claim resources and init adapter */
-	if ((rc = startup(info)) != 0) {
+	if ((rc = startup_hw(info)) != 0) {
 		spin_lock_irqsave(&info->netlock, flags);
 		info->netcount=0;
 		spin_unlock_irqrestore(&info->netlock, flags);
@@ -1455,7 +1455,7 @@ static int hdlcdev_open(struct net_device *dev)
 	/* generic HDLC layer open processing */
 	rc = hdlc_open(dev);
 	if (rc) {
-		shutdown(info);
+		shutdown_hw(info);
 		spin_lock_irqsave(&info->netlock, flags);
 		info->netcount = 0;
 		spin_unlock_irqrestore(&info->netlock, flags);
@@ -1499,7 +1499,7 @@ static int hdlcdev_close(struct net_device *dev)
 	netif_stop_queue(dev);
 
 	/* shutdown adapter and release resources */
-	shutdown(info);
+	shutdown_hw(info);
 
 	hdlc_close(dev);
 
@@ -2328,7 +2328,7 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static int startup(struct slgt_info *info)
+static int startup_hw(struct slgt_info *info)
 {
 	DBGINFO(("%s startup\n", info->device_name));
 
@@ -2361,7 +2361,7 @@ static int startup(struct slgt_info *info)
 /*
  *  called by close() and hangup() to shutdown hardware
  */
-static void shutdown(struct slgt_info *info)
+static void shutdown_hw(struct slgt_info *info)
 {
 	unsigned long flags;
 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ