Skip to content

Attempt at avoiding falsely flagged buffer overruns#455

Merged
erikbern merged 3 commits intomasterfrom
annoy-v-array-length
Feb 24, 2020
Merged

Attempt at avoiding falsely flagged buffer overruns#455
erikbern merged 3 commits intomasterfrom
annoy-v-array-length

Conversation

@erikbern
Copy link
Copy Markdown
Collaborator

@erikbern erikbern commented Feb 23, 2020

Just a quick shot at addressing jlmelville/uwot#50

src/annoylib.h Outdated
const double reallocation_factor = 1.3;
S new_nodes_size = std::max(n, (S) ((_nodes_size + 1) * reallocation_factor));
void *old = _nodes;
void *new_nodes = NULL;
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops this was something that was irrelevant to this PR, let me revert

@erikbern erikbern force-pushed the annoy-v-array-length branch from 46a0ce6 to 113867c Compare February 23, 2020 22:49
Copy link
Copy Markdown
Contributor

@eddelbuettel eddelbuettel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using MAX_ARRAY_SIZE should work, and I can test it.

@eddelbuettel
Copy link
Copy Markdown
Contributor

Could we ever run over MAX_ARRAY_SIZE ?

@eddelbuettel
Copy link
Copy Markdown
Contributor

eddelbuettel commented Feb 23, 2020

Oh, gosh, I had thought MAX_ARRAY_SIZE had been defined. Woulnd't

#define MAX_ARRAY_SIZE (1<<30)

together with

T v[MAX_ARRAY_SIZE];

put massive arrays on the stack?

Confused...

@erikbern
Copy link
Copy Markdown
Collaborator Author

put massive arrays on the stack?

No because the Node object is actually never allocated if you read the code. So it should be fine!

@eddelbuettel
Copy link
Copy Markdown
Contributor

Testing now at rhub. Old code gave

   ../inst/include/annoylib.h:364:24: runtime error: index 1 out of bounds for type 'float [1]'         
   ../inst/include/annoylib.h:364:46: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:364:13: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:359:24: runtime error: index 1 out of bounds for type 'float [1]'          
   ../inst/include/annoylib.h:359:46: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:359:13: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:736:21: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:736:31: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:736:11: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:394:9: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                     
   ../inst/include/annoylib.h:740:20: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:740:31: runtime error: index 1 out of bounds for type 'float [1]'                                                                                                                    
   ../inst/include/annoylib.h:740:41: runtime error: index 1 out of bounds for type 'float [1]'   

Will know in a moment if this helps. Not a perfect test (as we don't have the exact setup CRAN uses).

@eddelbuettel
Copy link
Copy Markdown
Contributor

Part of me has the vague feeling that we once had a constant there, also got yelled at, and later went to v[1]. But that was a while back and it is all a little fuzzy...

@erikbern
Copy link
Copy Markdown
Collaborator Author

Part of me has the vague feeling that we once had a constant there, also got yelled at, and later went to v[1]. But that was a while back and it is all a little fuzzy...

I think it was zero for a long time. It's like the old saying that in computer science there's only three numbers, 0, 1, and n. And we went from 0 to 1 to now n :)

@eddelbuettel
Copy link
Copy Markdown
Contributor

Sadly it didn't yet work.

   ../inst/include/annoylib.h:368:24: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:368:46: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:368:13: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:363:24: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:363:46: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:363:13: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:740:21: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:740:31: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:740:11: runtime error: index 1 out of bounds for type 'float [1]'          
   ../inst/include/annoylib.h:398:9: runtime error: index 1 out of bounds for type 'float [1]'
   ../inst/include/annoylib.h:744:20: runtime error: index 1 out of bounds for type 'float [1]'          
   ../inst/include/annoylib.h:744:31: runtime error: index 1 out of bounds for type 'float [1]'          
   ../inst/include/annoylib.h:744:41: runtime error: index 1 out of bounds for type 'float [1]' 

@jlmelville
Copy link
Copy Markdown

Is it possible that the declaration needs to be changed in more places, e.g.:

T v[1]; // We let this one overflow intentionally. Need to allocate at least 1 to make GCC happy

@jlmelville
Copy link
Copy Markdown

If I replace all declarations of T v[1] with T [V_ARRAY_SIZE] in annoylib.h, then when running the GCC UBSAN checker via rhub::check_with_sanitizers() with the RcppAnnoy project, I no longer see the ../inst/include/annoylib.h:872:11: runtime error: index 1 out of bounds for type 'float [1]' errors. For reference in the new version of annoylib.h, that line is:

n->v[z] = w[z];

However, I now see a new runtime error:

../inst/include/annoylib.h:662:18: runtime error: load of misaligned address 0x55d2429c5424 for type 'const long unsigned int', which requires 8 byte alignment
0x55d2429c5424: note: pointer points here
  00 00 00 00 00 00 00 00  00 00 00 00 01 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00

the line referenced is:

return (y[chunk] & (static_cast<T>(1) << (n_bits - 1 - (n->v[0] % n_bits)))) != 0;

@eddelbuettel
Copy link
Copy Markdown
Contributor

Good thinking about replacing the other assignments! I was rushing things before making dinner.

@erikbern Any magic for that line 662?

@erikbern
Copy link
Copy Markdown
Collaborator Author

Turns out there's actually 4 places this had to be modified, and I had just fixed it in one of them.

Can you check if it works now? Thanks!

@jlmelville
Copy link
Copy Markdown

Sorry for any confusion @erikbern, my previous comment was for what is now change 81648fb, i.e. I had changed those four locations already.

As of 81648fb, the old error has disappeared, but a new one has appeared, related to line 662.

@erikbern
Copy link
Copy Markdown
Collaborator Author

erikbern commented Feb 24, 2020

../inst/include/annoylib.h:662:18: runtime error: load of misaligned address 0x55d2429c5424 for type 'const long unsigned int', which requires 8 byte alignment

Actually this PR won't fix that issue, and I'm not sure how to even fix it. Some thoughts:

None of these are entirely trivial, but I think the last one is reasonably simple since there's only a few places where this really happens. I'll take a look at it in the next few days.

@jlmelville
Copy link
Copy Markdown

Fair enough. I would be happy to see the current PR merged, as it does localize the UBSAN complaints to just the Hamming calculation, which is an improvement.

I'd like to open a separate issue to cover the new misalignment problem, even if there isn't an obvious fix.

@erikbern erikbern merged commit f6d7b0f into master Feb 24, 2020
@erikbern erikbern deleted the annoy-v-array-length branch February 24, 2020 03:50
@erikbern
Copy link
Copy Markdown
Collaborator Author

Cool will handle the Hamming issue in a separate PR, thanks

@jlmelville
Copy link
Copy Markdown

Thanks for your work on this @erikbern, it is much appreciated.

@eddelbuettel
Copy link
Copy Markdown
Contributor

Very much seconded. That was excellent help, and really timely :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants