Skip to content

Fix Blob::offset upper-bound checks to be strict (< instead of <=)#7102

Open
Chessing234 wants to merge 1 commit intoBVLC:masterfrom
Chessing234:fix/blob-offset-check-upper-bounds
Open

Fix Blob::offset upper-bound checks to be strict (< instead of <=)#7102
Chessing234 wants to merge 1 commit intoBVLC:masterfrom
Chessing234:fix/blob-offset-check-upper-bounds

Conversation

@Chessing234
Copy link
Copy Markdown

Fixes #6391.

Bug

In `include/caffe/blob.hpp`, the four-argument `Blob::offset(n, c, h, w)` guards its inputs with:

```cpp
CHECK_GE(n, 0);
CHECK_LE(n, num());
CHECK_GE(channels(), 0);
CHECK_LE(c, channels());
CHECK_GE(height(), 0);
CHECK_LE(h, height());
CHECK_GE(width(), 0);
CHECK_LE(w, width());
```

Root cause

A valid index is in `[0, dim)`, so `CHECK_LE(n, num())` allows `n == num()` (and likewise for `c/h/w`) to pass. The method then computes

```cpp
((n * channels() + c) * height() + h) * width() + w
```

which at `n == num()` is exactly one past the buffer's last element. The vector overload directly below already uses the correct pattern:

```cpp
CHECK_GE(indices[i], 0);
CHECK_LT(indices[i], shape(i));
```

Fix

Switch the four legacy-accessor upper bounds to `CHECK_LT` so the valid range is `[0, dim)`, matching the vector overload. The lower-bound `CHECK_GE` lines (which #6391 does not flag) are left alone to keep the change minimal.

Blob::offset(n, c, h, w) guards the inputs with CHECK_LE(n, num()),
CHECK_LE(c, channels()), CHECK_LE(h, height()), CHECK_LE(w, width()).
A valid index is in [0, dim), so these allow n == num(), c == channels()
etc. to pass — one past the end of the buffer, producing a stale/OOB
linear offset from `((n * channels() + c) * height() + h) * width() + w`.

The vector overload of offset() already uses the correct pattern
(CHECK_LT(indices[i], shape(i))). Switch the four legacy-accessor checks
to CHECK_LT to match. Fixes BVLC#6391.
Chessing234 added a commit to Chessing234/caffe that referenced this pull request Apr 20, 2026
…ndex

Issue BVLC#6391.

The four-argument Blob::offset(n, c, h, w) has lower-bound guards of the
form:

    CHECK_GE(n, 0);
    CHECK_GE(channels(), 0);
    CHECK_GE(height(), 0);
    CHECK_GE(width(), 0);

Only the first line checks the index. The other three check the *dimensions*
of the blob (channels(), height(), width()), which for any constructed blob
are structurally non-negative -- these are vacuous asserts that fire only
if the blob itself is malformed, and never guard the index the caller passed
in. A negative c/h/w is silently accepted and then used to compute

    ((n * channels() + c) * height() + h) * width() + w

pointing outside the buffer.

The vector overload a few lines below already gets this right:

    CHECK_GE(indices[i], 0);
    CHECK_LT(indices[i], shape(i));

This change only touches the three misnamed CHECK_GE calls so the lower
bounds match the vector overload and the bounds the call actually needs.
Upper-bound hardening (CHECK_LE -> CHECK_LT) is out of scope; it is
handled separately by BVLC#7102.
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.

Incorrect checks in Blob::offset

1 participant