-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restrict taking addresses of members used in member bounds #213
Labels
feature
This labels new features and enhancements.
Milestone
Comments
This was referenced May 19, 2018
dtarditi
added a commit
to checkedc/checkedc
that referenced
this issue
May 21, 2018
Checked C restricts taking the addresses of: 1. Members with member bounds declarations. 2. Members used in member bounds declarations. 3. Variables with bounds declarations. 4. Variables/variable members used in bounds declarations. This add tests of restrictions 1-3, as part of implementing checkedc/checkedc-clang#213 and checkedc/checkedc-clang#212: - Taking the address of non-array members with or used in bounds declarations is now an error. - Taking the address of non-array members with or used in bounds-safe interfaces is allowed in unchecked scopes. It is an error in checked scopes. - Taking the address of non-array variables with bounds declaration is now an error. It is OK to take the address of an array variable or member because you can't use the resulting pointer to modify the pointer that the array converts to. The trickier cases to test involve nested members. Given ``` struct NestedLen { int len; }; struct S { struct NestedLen n; _Array_ptr<int> p : count(n.len); } ``` we don't allow the addresses of `n` or `n.len` to be taken. However, if `NestedLen` is not embedded in `S`, we allow the address of a struct of type NestedLen to be taken.
dtarditi
added a commit
that referenced
this issue
May 21, 2018
…490) Checked C restricts taking the addresses of: 1. Members with member bounds declarations. 2. Members used in member bounds declarations. 3. Variables with bounds declarations. 4. Variables/variable members used in bounds declarations. This change implements restrictions 1 through 3. This addresses issue #213 and part of issue #212. - Taking the address of non-array members with or used in bounds declarations is now an error. - Taking the address of non-array members with or used in bounds-safe interfaces is allowed in unchecked scopes. It is an error in checked scopes. In unchecked scopes, we don't warn about this, even though it could go wrong. We don't want to add warnings for existing code. We could add an optional warning if we wanted to. - Taking the address of non-array variables with bounds declaration is now an error. It is OK to take the address of an array variable or member because you can't use the resulting pointer to modify the pointer that the array converts to. We recognize variations on these restrictions, such as taking the address of a parenthesized lvalue expression or taking the address of an expression where a bounds-safe interface cast has been inserted. This was more complex to implement than the specification describes because of the possible use of nested members. See the long comment describing the algorithm in CheckedCAlias.cpp. We handle a few different cases: - The simple case where a member bounds expression only uses members declared in the current structure. - A member bounds expression uses members from a nested structure of the current structure. In this case, we do not allow the address of the nested structure to be taken. Given ``` struct NestedLen { int len; }; struct S { struct NestedLen n; _Array_ptr<int> p : count(n.len); } ``` we don't allow the address of n to be taken. - A structure with bounds is embedded in another structure, and then an address of member used in member bounds is taken. We handle these cases by recognizing "paths" of member accesses and using that to recognize paths that may result in aliases to members used in bounds, and paths that won't result in aliases to members used in bounds. All of the benchmarks that we converted to Checked C compile with these restrictions in place. This is a step toward removing one of the caveats in the SecDev paper. We still need to restrict taking the address of variables and variable members used in bounds declarations to complete the aliasing restrictions. It'll be interesting to see what happens on real-world code. We could loosen some of the restrictions, for example, and allow taking the addresses involving constant-sized bounds (bounds that only involve the variable or member). I found and fixed a bug in the lexicographic comparison of declarations. We were supposed to be comparing pointers to names in declarations, and compared pointers to the declarations instead. We then tried dereferencing the pointers to names. Testing: - I've added a new file containing tests of address-of expressions in the Checked C repo. This will be subject to a separate pull request. - Passed clang tests on Linux x64. - Passed LNT tests on Linux x64. - Passed automated testing on Windows.
This feature is complete. |
dopelsunce
pushed a commit
to dopelsunce/checkedc-clang
that referenced
this issue
Sep 28, 2020
This change goes with a matching compiler change. Update the Checked C tests to match the specification.
This was referenced Jan 15, 2022
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
If a structure has a member bounds expression, we should not allow the address of any member of the structure that is involved in the member bounds expression to be taken, unless we can prove the address is never used to dereference memory. We can do this if the address is only used in a comparison or a bounds expression.
We have a proposed change to Checked C to handle this situation, but until the extension is not implemented, it is unsafe to allow the address of an individual member to taken and escape.
The text was updated successfully, but these errors were encountered: