9 ms·
Acropalypse: Windows Save File API is defective by design
- Sakos 4y agoThis is the craziest shit I've read all month. How did this make it into production?
- favaq 4y ago"How did this make it into production" is what I've felt every time I've had to use metro apps since Windows 8 was released.
- baal80spam 4y agoPeople say it's NOT unique to Windows Snipping Tool but other tools that use this workflow for pngs as well.
- creshal 4y agoOnly if they use UWP, which is still somewhat rare, due to Win32 having loads more features and less bugs.
- creshal 4y agoThe entire UWP API was a fractal mess of poor decisions implemented sloppily, I can't say I'm surprised. There's so many footguns and glaring oversights that most people probably just gave up on it before they got this far.
- andix 4y agoMicrosoft can do a lot of things right (asp.net core and sql server are awesome products). But they really suck at creating UI toolkits and platforms. The last sane UI toolkit was Winforms, but it didn’t really evolve for 20 over years now.
- creshal 4y agoYeah, WinForms has been deprecated since 2014. Microsoft spent the last 30 years inventing and deprecating and reinventing and deprecating more UI frameworks than the entire rest of the industry combined (excluding JS frameworks).
- dist-epoch 4y agoThe same way it made it into production on POSIX? O_TRUNC is not default: https://man7.org/linux/man-pages/man2/openat.2.html https://man7.org/linux/man-pages/man2/openat.2.html
- sjm217 4y agoI feel this is a bit different. At least O_TRUNC is an option that is shown in documentation right next to the open() function so the programmer has the opportunity to spot it. With the FileSavePicker, there is no such option available and they have to add a line to manually truncate the stream. Also, open() is a low-level call, whereas FileSavePicker is the supposedly easy-to-use high level feature. I would say it is closer to fopen(), which does truncate by default.
- eviks 4y agoThese are very minor points. The main one is the same across platforms : bad defaults are common
- chrismorgan 4y agoNotwithstanding the lowest-level function open() working that way (and it’s honestly a somewhat different situation due to what it is and what the flags all are), fopen(), the more user-friendly interface with its mode strings, has "w" equivalent to including O_TRUNC in open() flags: https://man7.org/linux/man-pages/man3/fopen.3.html https://man7.org/linux/man-pages/man3/fopen.3.html
- donmcronald 4y agoI only have a very basic understanding of it, but skimming it makes me think that, in addition to leaving non-truncated files full of garbage around, that kind of open, overwrite, close pattern could be problematic on BTRFS. I wonder if that's one of the scenarios where BTRFS can end up with a bunch of extents that are full of mostly un-referenced blocks, but can't reclaim space because some of the blocks in the extent are (or BTRFS thinks they are) still in use.
- 4y ago
- electroly 4y agoIt's a pretty clear sign of how unpopular and rarely used UWP is: they can ship horrible bugs and nobody notices. A similar bug in Win32 would surely have been caught instantly just based on how widely it is used, both inside and outside of Microsoft.
- dblohm7 4y agoOver the past decade there has been a lot of half-baked Windows stuff that made it into production before needing a rethink. /me glares at "per-monitor v2" API awareness. I hate spreading rumours, but the one I heard about this was that nobody within Microsoft itself had tried converting any of their first-party GUI apps to per-monitor DPI. Once they started to do so, they finally realized how bad their offering was and came up with v2.
- ticviking 4y agoBecause our industry and modern society in general dare not slow down long enough to let good work be done, or trust a craftsperson when they say, "This isn't done yet"
- causi 4y agoI feel like somewhere around the release of Windows 8 Microsoft's OS division completely lost the plot and they've been coasting on profits from their other divisions ever since.
- WillAdams 4y agoThat, and allowing other players to dictate things --- in particular, the dumbing down of active styluses in Fall Creators Update so as to match the behaviour of Android for the sake of the Surface Duo is bizarre. I had to turn of Windows Ink so that Macromedia Freehand/MX would work. I need to find a web browser where the stylus selects text, as it has since Windows for Pen Computing, rather than scroll (why is this desirable? Can't one just scroll w/ touch?).
- hsdropout 4y agoI'm still traumatized by Windows Server 2012 which removed the start menu in lieu of a touch interface. For an enterprise server platform...
- sebazzz 4y agoThey've outsourced a lot development and QA, which may or may not have contributed to that feeling.
- nolok 4y agoOn the same line of "did no one ever bother to actually use it ?", you get a brand new computer or laptop, you want something to run over night so you go to settings and you set "sleep after" to "never", and it still goes down. You think you go crazy, you check every single option, and nope, everything is properly set. Then you go into the details of your power plan, through the old control panel they plan to remove, and you see that the hibernation settings is set to 120 minutes, and is not exposed in any way in the settings menu. What is even the point of allowing me to disable sleep ? I know sleep and hibernate are two different things on a technical and power usage level, but the end user really doesn't care, what he means is "don't turn the computer off". There are so many things in that same vein that have gone wrong after windows 7, and by the way the windows 11 start menu and right click contextual menu are as bad as people describe them, thank god third party tools easily exists to remove them. Microsoft lost the phone battle so now they want my laptop to behave like a phone, this is ridiculous.
- cesarb 4y ago> However, the new “more secure” Universal Windows Platform (UWP) sandboxes the file picker in a separate process, allowing neat features like capability-based access control. It returns a file handle which, if the selected file exists, will not overwrite the existing content! That got me a bit worried, since desktop Linux is going somewhat in the same direction with sandboxed applications. So I did a quick search for the file chooser portal API, and if I understood what I found correctly (https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.FileChooser https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.free... and https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Documents https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.free...), it does not return an already opened file handle; instead, the file is made available in a FUSE mountpoint within the sandbox (/run/user/$UID/doc/), and the call returns a URI pointing to that file. So, if I understood it correctly, developers can keep using the same traditional POSIX APIs they're already used to, with the same semantics they always had outside the sandbox.
- kirbyfan64sos 4y agoIndeed, and the document portal seems to have built-in support for atomic writes by first writing to a temporary file and then renaming it (https://github.com/flatpak/xdg-desktop-portal/blob/main/document-portal/document-portal-fuse.c#L2636 https://github.com/flatpak/xdg-desktop-portal/blob/main/docu...), so it should be possible to avoid this scenario altogether.
- asveikau 4y agoBasically what Microsoft has been doing since Windows 8 in 2012 is the equivalent of deprecating open(2). The people writing the new APIs have no idea how to design them, they think something like having a flag to overwrite the existing file is useless, confusing, legacy cruft. I doubt people working in the Linux space would be so brazen.
- bacchusracine 4y ago>I doubt people working in the Linux space would be so brazen. Have you heard about this little project called Gnome yet?
- deleted 4y ago[deleted]
- tommiegannert 4y agoI think the claim really should be that the defaults are "defective." Reading the thread, it seems the API does support truncating the opened file. Interesting gotcha nevertheless.
- raverbashing 4y agoYeah even if it didn't, I mean, you could still save to a temp file, delete the old one then move. Not atomic, but it's safer than just doing what they were doing (or just pad the rest with zeros worse case)
- wongarsu 4y agoIf you really want to, you can make it atomic by using the Transactional NTFS API [1]. Though I suppose you need a non-atomic fallback in case the file is not on an NTFS volume. [1] https://learn.microsoft.com/en-us/windows/win32/fileio/when-to-use-transactional-ntfs https://learn.microsoft.com/en-us/windows/win32/fileio/when-...
- Rimintil 4y agoTxF is deprecated: https://learn.microsoft.com/en-us/windows/win32/fileio/about-transactional-ntfs https://learn.microsoft.com/en-us/windows/win32/fileio/about...
- wongarsu 4y agoTechnically it isn't deprecated, just discouraged. Note how the page you linked doesn't contain the word "deprecated", and the "alternatives" page linked from that notice states in the introduction that they are considering deprecating it in a future version of Windows. Given that this notice seems to exist since at least 2012, and neither Windows 10 nor 11 deprecated it, the TxF API will probably outlive whatever software you're writing today.
- deleted 4y ago
- mastax 4y agoI had this same issue in a .NET program. "Whoops, forgot to SetLength(0)" But now in hindsight I probably used the wrong FileMode, since FileMode.Create is supposed to create or truncate.
- jasomill 4y agoAlso notable, per the docs[1], If you try to show the file picker while your app is snapped the file picker will not be shown and an exception will be thrown. You can avoid this by making sure your app is not snapped or by unsnapping it before you call the file picker. The code examples in FileSavePicker and the File picker sample show you how. The example on the linked FileSavePicker[2] page "shows you how" by presenting a sample excerpt that calls an "EnsureUnsnapped" method that is neither a part of any documented API nor defined in any version of the sample I can find in GitHub. Wasting considerable time, I managed to dig up an older version of the sample[3], ca. March 2013, that matches the doc excerpt. As it turns out, "EnsureUnsnapped" is defined in terms of a "TryUnsnap" method[4] that is deprecated because "window snapping" in the sense used here apparently only applies to store apps running on Windows 8.1 and earlier — notably, this includes the still-supported Windows Server 2012 R2 — and must not be confused with the current feature also officially known as window snapping. From this I assume this warning only applies to apps that need to work correctly on obsolete or nearly-obsolete versions of Windows, and it only took me the better part of an hour to figure this out. One of my biggest gripes with Microsoft is their somewhat recent tendency to memory-hole online-exclusive documentation and related materials for older versions of Windows that some of us, by hook or crook, are required to at least occasionally support, because telling an important customer to fuck off because their otherwise functional, fully security-patched OS is no longer under "mainstream" Microsoft support is a great way to lose said customer. Is either providing offline documentation or maintaining an online archive of older documentation really too much to ask? Given the time and effort Microsoft has clearly invested in redesigning their developer documentation site every few years, the effort required to do the latter seems like a drop in the bucket. To provide an illustrative counterexample: I can still find pinouts for the ports on my 128K Macintosh[5] or helpful tips to ensure my desk accessory is compatible with Font/DA Mover[6] if I need them, even if the relevant pages haven't been restyled since the late '90s. [1] https://learn.microsoft.com/en-us/uwp/api/windows.storage.pickers.filesavepicker.picksavefileasync https://learn.microsoft.com/en-us/uwp/api/windows.storage.pi... [2] https://learn.microsoft.com/en-us/uwp/api/windows.storage.pickers.filesavepicker https://learn.microsoft.com/en-us/uwp/api/windows.storage.pi... [3] https://web.archive.org/web/20130403000823/http://code.msdn.microsoft.com/windowsapps/File-picker-sample-9f294cba/file/43705/23/File%20picker%20sample.zip https://web.archive.org/web/20130403000823/http://code.msdn.... [4] https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewmanagement.applicationview.tryunsnap https://learn.microsoft.com/en-us/uwp/api/windows.ui.viewman... [5] https://developer.apple.com/library/archive/technotes/hw/hw_19.html#//apple_ref/doc/uid/DTS10002488 https://developer.apple.com/library/archive/technotes/hw/hw_... [6] https://developer.apple.com/library/archive/technotes/pt/pt_19.html#//apple_ref/doc/uid/DTS10002673 https://developer.apple.com/library/archive/technotes/pt/pt_...
- albert_e 4y agoso this is very similar to the Acropalypse vulnerability recently published about Google Pixel Pro phones? https://www.da.vidbuchanan.co.uk/blog/exploiting-acropalypse.html https://www.da.vidbuchanan.co.uk/blog/exploiting-acropalypse...
- operator-name 4y agoYes. If you follow the linked thread: - https://twitter.com/David3141593/status/1638222624084951040 https://twitter.com/David3141593/status/1638222624084951040 - https://twitter.com/ProgramMax/status/1638217206180741121 https://twitter.com/ProgramMax/status/1638217206180741121
- deleted 4y ago[deleted]
- kuroguro 4y agoHuh.. wh-.. no I did a bit of digging (first)! [0] Could be a coincidence. Either way the explanation here is way better and more detailed ^^; [0] https://news.ycombinator.com/item?id=35253970 https://news.ycombinator.com/item?id=35253970
- mentalpiracy 4y agoThis same thing happens with windows 10 video editor if you export a file with the same name.
- mtVessel 4y agoThis thread confuses me, possibly because I'm not a UWP dev. OP keeps talking about the FileSavePicker being defective, but isn't that just a control? Isn't the actual writing being done by the FileIO classes? And doesn't it just boil down to someone using them wrong? In the System.IO namespace we can explicitly specify a FileMode to indicate whether we're appending or overwriting. If the UWP equivalent doesn't exist (and you need to explicitly set the file length to 0 to truncate), why would anyone just assume it does one or the other? "The API is crap" is still not an excuse for using it wrong. Am I missing something?
- mvandermeulen 4y agoI was also wondering along the same lines as an everything except for windows developer so it’s not just you. It would be good if someone could clarify.
- muststopmyths 4y agoyeah it's horseshit. The picker just let's you pick a file path. The Win32 API also requires you to specify that you want to truncate the existing files. How the fuck else would it work ? An additional OpenFileButTruncateExisting() API ? A SaveFileAndOverwriteExisting() API ? You can argue for those, but this thread is idiotic. He tries to furiously backpedal towards the end, but if he doesn't know the difference between a picker dialog and actually writing a file, I am not sure why I'd pay him any attention.
- Arnavion 4y agoNot only is the API called `FileSavePicker.PickSaveFileAsync` which any reasonable person would assume would give you a truncated file, but even Microsoft agrees that it should give you a truncated file. https://news.ycombinator.com/item?id=35277561 https://news.ycombinator.com/item?id=35277561
- JonChesterfield 4y ago`FileSavePicker.PickSaveFileAsync` manages to be redundant and ambiguous at the same time. Definitely wouldn't want to guess what that might do.
- Arnavion 4y ago>The documentation for FileSavePicker doesn’t mention the problem or truncate files in the example code. It is no surprise that the default behaviour of not truncating existing files is, therefore commonplace, despite being not what most people want. 5/9 The example in the link in the tweet uses .PickSaveFileAsync(). The documentation for that function is https://learn.microsoft.com/en-us/uwp/api/windows.storage.pickers.filesavepicker.picksavefileasync?view=winrt-22621 https://learn.microsoft.com/en-us/uwp/api/windows.storage.pi... which says: >The file name, extension, and location of this storageFile match those specified by the user, but the file has no content. (Emphasis mine.) And it's not a recent change. It was written in 2017. https://github.com/MicrosoftDocs/winrt-api/blame/docs/windows.storage.pickers/filesavepicker_picksavefileasync_1000266802.md#L16 https://github.com/MicrosoftDocs/winrt-api/blame/docs/window... So it may just be a bug rather than the intention. Though given that the SO question is from 2016, it seems nobody verified the intention was actually implemented since the very beginning.
- heisenbit 4y agoNot just the Api but also Microsoft‘s screenshot tool. Which is a tool worse imho. than its predecessor and that was already weak. MFT maybe just fix it by starting from scratch here and do it right this time.
- thecosmicfrog 4y agoI've found that Snip & Sketch occasionally just doesn't save my screenshots. I'll click Save, it'll open the file dialog, I'll choose the directory and click Save. But, every now and again, nothing. The file just doesn't save.