Commit 2005aab
Al Viro
functionfs: use spinlock for FFS_DEACTIVATED/FFS_CLOSING transitions
When all files are closed, functionfs needs ffs_data_reset() to be
done before any further opens are allowed.
During that time we have ffs->state set to FFS_CLOSING; that makes
->open() fail with -EBUSY. Once ffs_data_reset() is done, it
switches state (to FFS_READ_DESCRIPTORS) indicating that opening
that thing is allowed again. There's a couple of additional twists:
* mounting with -o no_disconnect delays ffs_data_reset()
from doing that at the final ->release() to the first subsequent
open(). That's indicated by ffs->state set to FFS_DEACTIVATED;
if open() sees that, it immediately switches to FFS_CLOSING and
proceeds with doing ffs_data_reset() before returning to userland.
* a couple of usb callbacks need to force the delayed
transition; unfortunately, they are done in locking environment
that does not allow blocking and ffs_data_reset() can block.
As the result, if these callbacks see FFS_DEACTIVATED, they change
state to FFS_CLOSING and use schedule_work() to get ffs_data_reset()
executed asynchronously.
Unfortunately, the locking is rather insufficient. A fix attempted
in e5bf5ee ("functionfs: fix the open/removal races") had closed
a bunch of UAF, but it didn't do anything to the callbacks, lacked
barriers in transition from FFS_CLOSING to FFS_READ_DESCRIPTORS
_and_ it had been too heavy-handed in open()/open() serialization -
I've used ffs->mutex for that, and it's being held over actual IO on
ep0, complete with copy_from_user(), etc.
Even more unfortunately, the userland side is apparently racy enough
to have the resulting timing changes (no failures, just a delayed
return of open(2)) disrupt the things quite badly. Userland bugs
or not, it's a clear regression that needs to be dealt with.
Solution is to use a spinlock for serializing these state checks and
transitions - unlike ffs->mutex it can be taken in these callbacks
and it doesn't disrupt the timings in open().
We could introduce a new spinlock, but it's easier to use the one
that is already there (ffs->eps_lock) instead - the locking
environment is safe for it in all affected places.
Since now it is held over all places that alter or check the
open count (ffs->opened), there's no need to keep that atomic_t -
int would serve just fine and it's simpler that way.
Fixes: e5bf5ee ("functionfs: fix the open/removal races")
Fixes: 18d6b32 ("usb: gadget: f_fs: add "no_disconnect" mode") # v4.0
Tested-by: Samuel Wu <[email protected]>
Signed-off-by: Al Viro <[email protected]>1 parent 351ea48 commit 2005aab
2 files changed
Lines changed: 53 additions & 57 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
59 | 59 | | |
60 | 60 | | |
61 | 61 | | |
62 | | - | |
63 | 62 | | |
64 | 63 | | |
65 | 64 | | |
| |||
636 | 635 | | |
637 | 636 | | |
638 | 637 | | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
639 | 641 | | |
640 | 642 | | |
641 | 643 | | |
642 | | - | |
643 | 644 | | |
644 | | - | |
645 | | - | |
646 | | - | |
647 | | - | |
648 | | - | |
649 | | - | |
| 645 | + | |
650 | 646 | | |
651 | | - | |
652 | | - | |
| 647 | + | |
653 | 648 | | |
654 | 649 | | |
655 | | - | |
| 650 | + | |
| 651 | + | |
| 652 | + | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 656 | + | |
656 | 657 | | |
657 | 658 | | |
658 | 659 | | |
| |||
1202 | 1203 | | |
1203 | 1204 | | |
1204 | 1205 | | |
1205 | | - | |
1206 | | - | |
1207 | | - | |
1208 | | - | |
1209 | | - | |
1210 | | - | |
1211 | 1206 | | |
1212 | | - | |
1213 | | - | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
1214 | 1210 | | |
1215 | 1211 | | |
1216 | 1212 | | |
| |||
1220 | 1216 | | |
1221 | 1217 | | |
1222 | 1218 | | |
1223 | | - | |
1224 | | - | |
| 1219 | + | |
1225 | 1220 | | |
1226 | 1221 | | |
1227 | | - | |
| 1222 | + | |
| 1223 | + | |
1228 | 1224 | | |
1229 | 1225 | | |
1230 | 1226 | | |
| |||
2092 | 2088 | | |
2093 | 2089 | | |
2094 | 2090 | | |
2095 | | - | |
2096 | | - | |
2097 | 2091 | | |
2098 | 2092 | | |
2099 | 2093 | | |
| |||
2150 | 2144 | | |
2151 | 2145 | | |
2152 | 2146 | | |
2153 | | - | |
2154 | | - | |
2155 | | - | |
2156 | | - | |
2157 | | - | |
2158 | | - | |
2159 | | - | |
2160 | | - | |
2161 | | - | |
2162 | 2147 | | |
2163 | 2148 | | |
2164 | 2149 | | |
| |||
2176 | 2161 | | |
2177 | 2162 | | |
2178 | 2163 | | |
2179 | | - | |
2180 | | - | |
2181 | | - | |
2182 | | - | |
2183 | | - | |
2184 | | - | |
2185 | | - | |
2186 | | - | |
2187 | | - | |
2188 | | - | |
2189 | | - | |
2190 | | - | |
2191 | | - | |
2192 | | - | |
2193 | | - | |
2194 | | - | |
2195 | | - | |
2196 | | - | |
2197 | | - | |
2198 | | - | |
2199 | | - | |
2200 | | - | |
| 2164 | + | |
| 2165 | + | |
| 2166 | + | |
| 2167 | + | |
| 2168 | + | |
| 2169 | + | |
| 2170 | + | |
| 2171 | + | |
| 2172 | + | |
| 2173 | + | |
| 2174 | + | |
| 2175 | + | |
| 2176 | + | |
| 2177 | + | |
| 2178 | + | |
| 2179 | + | |
| 2180 | + | |
| 2181 | + | |
| 2182 | + | |
| 2183 | + | |
| 2184 | + | |
| 2185 | + | |
| 2186 | + | |
2201 | 2187 | | |
2202 | 2188 | | |
2203 | 2189 | | |
| |||
2214 | 2200 | | |
2215 | 2201 | | |
2216 | 2202 | | |
2217 | | - | |
| 2203 | + | |
2218 | 2204 | | |
2219 | 2205 | | |
2220 | 2206 | | |
| |||
2266 | 2252 | | |
2267 | 2253 | | |
2268 | 2254 | | |
| 2255 | + | |
2269 | 2256 | | |
2270 | 2257 | | |
2271 | 2258 | | |
| |||
2289 | 2276 | | |
2290 | 2277 | | |
2291 | 2278 | | |
| 2279 | + | |
2292 | 2280 | | |
2293 | 2281 | | |
2294 | 2282 | | |
| |||
3756 | 3744 | | |
3757 | 3745 | | |
3758 | 3746 | | |
| 3747 | + | |
3759 | 3748 | | |
3760 | 3749 | | |
3761 | 3750 | | |
| |||
3768 | 3757 | | |
3769 | 3758 | | |
3770 | 3759 | | |
| 3760 | + | |
3771 | 3761 | | |
3772 | 3762 | | |
| 3763 | + | |
3773 | 3764 | | |
3774 | 3765 | | |
3775 | 3766 | | |
3776 | 3767 | | |
| 3768 | + | |
3777 | 3769 | | |
3778 | 3770 | | |
3779 | 3771 | | |
| |||
3791 | 3783 | | |
3792 | 3784 | | |
3793 | 3785 | | |
| 3786 | + | |
3794 | 3787 | | |
3795 | 3788 | | |
3796 | 3789 | | |
3797 | 3790 | | |
| 3791 | + | |
3798 | 3792 | | |
3799 | 3793 | | |
| 3794 | + | |
3800 | 3795 | | |
3801 | 3796 | | |
3802 | 3797 | | |
3803 | 3798 | | |
| 3799 | + | |
3804 | 3800 | | |
3805 | 3801 | | |
3806 | 3802 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
176 | 176 | | |
177 | 177 | | |
178 | 178 | | |
179 | | - | |
| 179 | + | |
180 | 180 | | |
181 | 181 | | |
182 | 182 | | |
| |||
0 commit comments