Page MenuHomeFreeBSD

During F_SETFL, don't change file flags on error
ClosedPublic

Authored by asomers on Jul 9 2023, 9:13 PM.
Tags
None
Referenced Files
F102363385: D40955.id124420.diff
Mon, Nov 11, 6:11 AM
Unknown Object (File)
Sun, Nov 10, 9:37 PM
Unknown Object (File)
Sun, Nov 10, 8:11 PM
Unknown Object (File)
Sun, Nov 10, 7:15 PM
Unknown Object (File)
Thu, Nov 7, 2:25 AM
Unknown Object (File)
Wed, Nov 6, 2:53 PM
Unknown Object (File)
Fri, Nov 1, 10:44 PM
Unknown Object (File)
Oct 6 2024, 2:24 AM
Subscribers

Details

Summary

Previously, event if the FIONBIO or FIOASYNC ioctl failed, the file's
f_flags variable would still be changed. Now, kern_fcntl will restore
the original flags if the ioctl fails.

PR: 265736
Reported by: Yuval Pavel Zholkover <paulzhol@gmail.com>
MFC after: 2 weeks

Test Plan

Test case is in Bugzilla

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 52532
Build 49423: arc lint + arc unit

Event Timeline

May be, set the flags after fo_ioctls ops? Then you do not need to revert.

This would also slightly reduce a window where e.g. two threads do setflags, one ioctl fails, and the thread reverts flags set by the successful thread.

In D40955#932173, @kib wrote:

May be, set the flags after fo_ioctls ops? Then you do not need to revert.

I thought about that. However, the fp->f_flag is accessed by fo_ioctls. For example, in vn_ioctl. So the flag has to be set before.

This would also slightly reduce a window where e.g. two threads do setflags, one ioctl fails, and the thread reverts flags set by the successful thread.

I think we should be ok in this case, because the revert_f_setfl block will only revert those flags that were actually changed above. Atomic instructions make it possible for us to know which flags were changed.

In D40955#932173, @kib wrote:

This would also slightly reduce a window where e.g. two threads do setflags, one ioctl fails, and the thread reverts flags set by the successful thread.

I think we should be ok in this case, because the revert_f_setfl block will only revert those flags that were actually changed above. Atomic instructions make it possible for us to know which flags were changed.

Other thread might see that the needed flag is set, and then it is reverted.

This revision is now accepted and ready to land.Jul 10 2023, 2:52 AM
sys/kern/kern_descrip.c
590

BTW @kib do you know why this line is here? It seems to be "if FIOASYNC fails, then turn off non-blocking mode". Why would that be? This logic has been in place ever since 1991. https://svnweb.freebsd.org/csrg/sys/kern/kern_descrip.c?r1=48028&r2=48029&

sys/kern/kern_descrip.c
590

I suspect it is a too rough attempt to revert the action. Perhaps more fine-grained unwind on error would be applicable, as you noted.