Hacker News new | past | comments | ask | show | jobs | submit login
Ask HN: (CloudFlare bug) - Why does write() in C allow negative length?
3 points by winteriscoming on Feb 25, 2017 | hide | past | favorite | 4 comments
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




I've written a gist that somewhat explains this:

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.


I 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/p...


I'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


Hello, 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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: