linux/drivers/tty
Christian Brauner 1934b21261 file: reclaim 24 bytes from f_owner
We do embedd struct fown_struct into struct file letting it take up 32
bytes in total. We could tweak struct fown_struct to be more compact but
really it shouldn't even be embedded in struct file in the first place.

Instead, actual users of struct fown_struct should allocate the struct
on demand. This frees up 24 bytes in struct file.

That will have some potentially user-visible changes for the ownership
fcntl()s. Some of them can now fail due to allocation failures.
Practically, that probably will almost never happen as the allocations
are small and they only happen once per file.

The fown_struct is used during kill_fasync() which is used by e.g.,
pipes to generate a SIGIO signal. Sending of such signals is conditional
on userspace having set an owner for the file using one of the F_OWNER
fcntl()s. Such users will be unaffected if struct fown_struct is
allocated during the fcntl() call.

There are a few subsystems that call __f_setown() expecting
file->f_owner to be allocated:

(1) tun devices
    file->f_op->fasync::tun_chr_fasync()
    -> __f_setown()

    There are no callers of tun_chr_fasync().

(2) tty devices

    file->f_op->fasync::tty_fasync()
    -> __tty_fasync()
       -> __f_setown()

    tty_fasync() has no additional callers but __tty_fasync() has. Note
    that __tty_fasync() only calls __f_setown() if the @on argument is
    true. It's called from:

    file->f_op->release::tty_release()
    -> tty_release()
       -> __tty_fasync()
          -> __f_setown()

    tty_release() calls __tty_fasync() with @on false
    => __f_setown() is never called from tty_release().
       => All callers of tty_release() are safe as well.

    file->f_op->release::tty_open()
    -> tty_release()
       -> __tty_fasync()
          -> __f_setown()

    __tty_hangup() calls __tty_fasync() with @on false
    => __f_setown() is never called from tty_release().
       => All callers of __tty_hangup() are safe as well.

From the callchains it's obvious that (1) and (2) end up getting called
via file->f_op->fasync(). That can happen either through the F_SETFL
fcntl() with the FASYNC flag raised or via the FIOASYNC ioctl(). If
FASYNC is requested and the file isn't already FASYNC then
file->f_op->fasync() is called with @on true which ends up causing both
(1) and (2) to call __f_setown().

(1) and (2) are the only subsystems that call __f_setown() from the
file->f_op->fasync() handler. So both (1) and (2) have been updated to
allocate a struct fown_struct prior to calling fasync_helper() to
register with the fasync infrastructure. That's safe as they both call
fasync_helper() which also does allocations if @on is true.

The other interesting case are file leases:

(3) file leases
    lease_manager_ops->lm_setup::lease_setup()
    -> __f_setown()

    Which in turn is called from:

    generic_add_lease()
    -> lease_manager_ops->lm_setup::lease_setup()
       -> __f_setown()

So here again we can simply make generic_add_lease() allocate struct
fown_struct prior to the lease_manager_ops->lm_setup::lease_setup()
which happens under a spinlock.

With that the two remaining subsystems that call __f_setown() are:

(4) dnotify
(5) sockets

Both have their own custom ioctls to set struct fown_struct and both
have been converted to allocate a struct fown_struct on demand from
their respective ioctls.

Interactions with O_PATH are fine as well e.g., when opening a /dev/tty
as O_PATH then no file->f_op->open() happens thus no file->f_owner is
allocated. That's fine as no file operation will be set for those and
the device has never been opened. fcntl()s called on such things will
just allocate a ->f_owner on demand. Although I have zero idea why'd you
care about f_owner on an O_PATH fd.

Link: https://lore.kernel.org/r/20240813-work-f_owner-v2-1-4e9343a79f9f@kernel.org
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
2024-08-28 13:05:39 +02:00
..
hvc TTY/Serial changes for 6.10-rc1 2024-05-22 11:53:02 -07:00
ipwireless tty: ipwireless: remove unused ipw_dev::attribute_memory 2023-11-23 19:16:03 +00:00
serdev driver core: have match() callback in struct bus_type take a const * 2024-07-03 15:16:54 +02:00
serial Revert "serial: 8250_omap: Set the console genpd always on if no console suspend" 2024-08-15 07:22:10 +02:00
vt tty: vt: conmakehash: remove non-portable code printing comment header 2024-08-13 11:06:29 +02:00
amiserial.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
ehv_bytechan.c tty: ehv_bytechan: convert to u8 and size_t 2023-12-08 12:02:37 +01:00
goldfish.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
Kconfig vt: remove superfluous CONFIG_HW_CONSOLE 2024-01-27 19:03:51 -08:00
Makefile
mips_ejtag_fdc.c tty: mips_ejtag_fdc: Fix passing incompatible pointer type warning 2024-02-23 10:14:16 +01:00
moxa.c tty: moxa: convert to u8 and size_t 2023-12-08 12:02:38 +01:00
mxser.c tty: mxser: Remove __counted_by from mxser_board.ports[] 2024-06-28 08:54:56 -07:00
n_gsm.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
n_hdlc.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
n_null.c tty: ldops: unify to u8 2023-08-11 21:12:47 +02:00
n_tty.c tty: n_tty: Fix buffer offsets when lookahead is used 2024-06-04 14:07:27 +02:00
nozomi.c tty: nozomi: convert to u8 and size_t 2023-12-08 12:02:38 +01:00
pty.c tty: make tty_operations::write()'s count size_t 2023-08-11 21:12:46 +02:00
rpmsg_tty.c tty: make tty_operations::write()'s count size_t 2023-08-11 21:12:46 +02:00
synclink_gt.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
sysrq.c Devicetree fixes for 6.11, part 1 2024-07-27 12:46:16 -07:00
tty_audit.c tty: audit: unify to u8 2023-08-11 21:12:46 +02:00
tty_baudrate.c
tty_buffer.c tty: Don't include tty_buffer.h in tty.h 2024-02-18 18:59:59 +01:00
tty_io.c file: reclaim 24 bytes from f_owner 2024-08-28 13:05:39 +02:00
tty_ioctl.c tty: allow TIOCSLCKTRMIOS with CAP_CHECKPOINT_RESTORE 2023-12-15 14:20:03 +01:00
tty_jobctrl.c tty: tty_jobctrl: fix pid memleak in disassociate_ctty() 2023-09-18 11:14:43 +02:00
tty_ldisc.c tty: add the option to have a tty reject a new ldisc 2024-05-04 18:45:11 +02:00
tty_ldsem.c
tty_mutex.c
tty_port.c tty: switch tty_port::xmit_* to u8 2023-12-08 12:02:37 +01:00
tty.h tty: convert THROTTLE constants into enum 2023-10-03 14:31:16 +02:00
ttynull.c tty: add missing MODULE_DESCRIPTION() macros 2024-06-24 16:10:11 +02:00
vcc.c tty: vcc: Add check for kstrdup() in vcc_probe() 2023-09-18 11:14:42 +02:00