linux/drivers/net
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
..
arcnet net: arcnet: com20020-isa: add missing MODULE_DESCRIPTION() macro 2024-06-19 17:21:12 -07:00
bonding net: bonding: correctly annotate RCU in bond_should_notify_peers() 2024-07-23 15:13:12 +02:00
caif caif_virtio: use virtio_find_single_vq() for single virtqueue finding 2024-07-17 05:20:56 -04:00
can minmax: don't use max() in situations that want a C constant expression 2024-07-28 20:23:27 -07:00
dsa net: dsa: vsc73xx: allow phy resetting 2024-08-12 11:46:55 +01:00
ethernet net: hns3: use correct release function during uninitialization 2024-08-15 13:07:08 +02:00
fddi
fjes minmax: make generic MIN() and MAX() macros available everywhere 2024-07-28 15:49:18 -07:00
hamradio parport: Remove parport_driver.devmodel 2024-07-03 16:44:22 +02:00
hippi
hyperv tracing/treewide: Remove second parameter of __assign_str() 2024-05-22 20:14:47 -04:00
ieee802154
ipa
ipvlan ipvlan: Dont Use skb->sk in ipvlan_process_v{4,6}_outbound 2024-05-30 12:05:52 +02:00
mctp net: mctp-i2c: invalidate flows immediately on TX errors 2024-07-12 13:37:31 +01:00
mdio net: mdio: mscc-miim: Handle the switch reset 2024-06-21 12:12:42 +01:00
netdevsim net: Add struct kernel_ethtool_ts_info 2024-07-15 08:02:26 -07:00
pcs net: pcs: xpcs: Add fwnode-based descriptor creation method 2024-07-05 09:35:51 +01:00
phy net: phy: vitesse: repair vsc73xx autonegotiation 2024-08-12 11:46:55 +01:00
plip parport: Remove parport_driver.devmodel 2024-07-03 16:44:22 +02:00
ppp ppp: reject claimed-as-LCP but actually malformed packets 2024-07-11 11:00:08 +02:00
pse-pd pse-core: Conditionally set current limit during PI regulator registration 2024-08-15 12:51:32 +02:00
slip
team
thunderbolt
usb usbnet: ipheth: fix carrier detection in modes 1 and 4 2024-08-09 13:54:21 +01:00
vmxnet3 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2024-06-06 12:06:56 -07:00
vxlan vxlan: Pull inner IP header in vxlan_xmit_one(). 2024-06-21 17:34:15 -07:00
wan net: wan: fsl_qmc_hdlc: Discard received CRC 2024-07-31 18:09:08 -07:00
wireguard wireguard: send: annotate intentional data race in checking empty queue 2024-07-05 17:21:10 -07:00
wireless ath.git patch for v6.11 2024-08-13 12:51:21 +03:00
wwan Char/Misc and other driver changes for 6.11-rc1 2024-07-19 15:55:08 -07:00
xen-netback
Kconfig
LICENSE.SRC
Makefile
Space.c
amt.c
bareudp.c
dummy.c
eql.c
geneve.c geneve: Fix incorrect inner network header offset when innerprotoinherit is set 2024-06-10 13:18:08 +01:00
gtp.c gtp: pull network headers in gtp_dev_xmit() 2024-08-09 21:56:44 -07:00
ifb.c
loopback.c
macsec.c
macvlan.c net: Add struct kernel_ethtool_ts_info 2024-07-15 08:02:26 -07:00
macvtap.c
mdio.c
mhi_net.c
mii.c
net_failover.c
netconsole.c Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net 2024-07-15 13:19:17 -07:00
netkit.c netkit: Fix pkt_type override upon netkit pass verdict 2024-05-25 10:48:57 -07:00
nlmon.c
ntb_netdev.c net: ntb_netdev: Move ntb_netdev_rx_handler() to call netif_rx() from __netif_rx() 2024-07-02 18:56:46 -07:00
pfcp.c
rionet.c
sb1000.c
sungem_phy.c
tap.c tap: add missing verification for short frame 2024-07-25 08:07:05 -07:00
tun.c file: reclaim 24 bytes from f_owner 2024-08-28 13:05:39 +02:00
veth.c
virtio_net.c virtio-net: unbreak vq resizing when coalescing is not negotiated 2024-08-05 11:10:22 +01:00
vrf.c sysctl: treewide: constify the ctl_table argument of proc_handlers 2024-07-24 20:59:29 +02:00
vsockmon.c
xen-netfront.c