4 ms·
Ask HN: (CloudFlare bug) - Why does write() in C allow negative length?
In context of the CloudFare fiasco, the bug report[1] states this
>> My current theory is that they had some code in their "ScrapeShield" feature that did something like this:
>> int Length = ObfuscateEmailAddressesInHtml(&OutputBuffer, CachedPage);
>> write(fd, OutputBuffer, Length);
>> But they weren't checking if the obfuscation parsers returned a negative value because of malformed HTML. This would explain the data I'm seeing.
I haven't used C in my professional career (I mainly use Java), so the fact that this function allowed a negative value, for "num bytes to write", to be passed to it and then even went on to write data without throwing an error for passing a negative value baffles me. I'm genuinely curious why this function doesn't throw an error for negative "num bytes to write". Is there any use case which I'm missing where it would be valid to send a negative value and expect it to write negative number of bytes?
[1] https://bugs.chromium.org/p/project-zero/issues/detail?id=1139
- technion 10y agoI've written a gist that somewhat explains this: https://gist.github.com/technion/a16095fa6e3a027d6bc938ad6f9bdc50 https://gist.github.com/technion/a16095fa6e3a027d6bc938ad6f9... write() doesn't "print a negative number", as per the man page, write(2) takes a size_t for an argument. And what that means is explained if you run that gist: We have a count of 18446744073709551611 and will write that many characters In short, you're looking at a signed, negative integer, cast to a very large positive integer. clang will only print a warning if you compile with -Wconversion and whilst I like to do that in my own code, most people find that too noisy. Edit: Personally, I feel this "email obfuscation feature" should never have been written in the first place. There are a myriad of options for people to do this in their own website without something this obviously complex being built into an nginx module of a CDN.
- winteriscoming 10y agoI see what you are saying. So that function actually accepts a size_t which is a unsigned type. I now understand why this call to the function went through without any exceptions. When I posted my question, I was referring to this page[1] which claims the type for the "numBytes" to be a signed integer. [1] https://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/write.html https://www.lix.polytechnique.fr/~liberti/public/computing/p...
- technion 10y agoI'm going to assume this is an age thing, because the example linked on that page has a date of 1996. This is more accurate for every platform I've actually worked with: http://man7.org/linux/man-pages/man2/write.2.html http://man7.org/linux/man-pages/man2/write.2.html
- LastSeagull 10y agoHello, I understand your example, but when putting write(fd, buf, count); inside your my_write function... it doesn't work. Is there something more? Thank you.