twx-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
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
hippi
hyperv
ieee802154
ipa
ipvlan
mctp
mdio
netdevsim net: Add struct kernel_ethtool_ts_info 2024-07-15 08:02:26 -07:00
pcs
phy net: phy: vitesse: repair vsc73xx autonegotiation 2024-08-12 11:46:55 +01:00
plip
ppp
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
vxlan
wan net: wan: fsl_qmc_hdlc: Discard received CRC 2024-07-31 18:09:08 -07:00
wireguard
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
amt.c
bareudp.c
dummy.c
eql.c
geneve.c
gtp.c gtp: pull network headers in gtp_dev_xmit() 2024-08-09 21:56:44 -07:00
ifb.c
Kconfig
LICENSE.SRC
loopback.c
macsec.c
macvlan.c net: Add struct kernel_ethtool_ts_info 2024-07-15 08:02:26 -07:00
macvtap.c
Makefile
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
nlmon.c
ntb_netdev.c
pfcp.c
rionet.c
sb1000.c
Space.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