Title: False Negative: Guards in while loop with break fail to 'control' variable usage outside · Issue #8490 · github/codeql · GitHub
Open Graph Title: False Negative: Guards in while loop with break fail to 'control' variable usage outside · Issue #8490 · github/codeql
X Title: False Negative: Guards in while loop with break fail to 'control' variable usage outside · Issue #8490 · github/codeql
Description: Take the following two examples: static File safe11() throws IOException { File temp = null; if (temp == null) { while (true) { temp = File.createTempFile("test", "directory"); if (temp.delete() && temp.mkdir()) { break; } } } return tem...
Open Graph Description: Take the following two examples: static File safe11() throws IOException { File temp = null; if (temp == null) { while (true) { temp = File.createTempFile("test", "directory"); if (temp.delete() &&...
X Description: Take the following two examples: static File safe11() throws IOException { File temp = null; if (temp == null) { while (true) { temp = File.createTempFile("test", "directory"); ...
Opengraph URL: https://github.com/github/codeql/issues/8490
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"False Negative: Guards in while loop with break fail to 'control' variable usage outside","articleBody":"Take the following two examples:\r\n\r\n```java\r\nstatic File safe11() throws IOException {\r\n File temp = null;\r\n if (temp == null) {\r\n while (true) {\r\n temp = File.createTempFile(\"test\", \"directory\");\r\n if (temp.delete() \u0026\u0026 temp.mkdir()) {\r\n break;\r\n }\r\n }\r\n }\r\n return temp;\r\n}\r\n\r\nFile safe12temp;\r\nFile safe12() throws IOException {\r\n if (safe12temp == null) {\r\n while (true) {\r\n safe12temp = File.createTempFile(\"test\", \"directory\");\r\n if (safe12temp.delete() \u0026\u0026 safe12temp.mkdir()) {\r\n break;\r\n }\r\n }\r\n }\r\n return safe12temp;\r\n}\r\n```\r\n\r\nLet's take `File.createTempFile` as a source of taint, and `_.mkdir()` is a guard.\r\n```ql\r\n/**\r\n * All methods on the class `java.io.File` that create directories.\r\n */\r\nclass MethodFileCreatesDirs extends Method {\r\n MethodFileCreatesDirs() {\r\n getDeclaringType() instanceof TypeFile and\r\n hasName([\"mkdir\", \"mkdirs\"])\r\n }\r\n}\r\n\r\n/**\r\n * An expression that will create a directory without throwing an exception if a file/directory already exists.\r\n */\r\nprivate predicate isNonThrowingDirectoryCreationExpression(Expr expr, MethodAccess creationCall) {\r\n creationCall.getMethod() instanceof MethodFileCreatesDirs and creationCall.getQualifier() = expr\r\n}\r\n\r\nprivate class DirectoryCreationBarrierGuard extends DataFlow::BarrierGuard {\r\n DirectoryCreationBarrierGuard() { isNonThrowingDirectoryCreationExpression(_, this) }\r\n\r\n override predicate checks(Expr e, boolean branch) {\r\n this.controls(e, branch)\r\n }\r\n}\r\n```\r\n\r\nRunning a query for `DirectoryCreationBarrierGuard` will find the `safe12temp.mkdir()` and `temp.mkdir()`.\r\nHowever, when quick evaluating the `DirectoryCreationBarrierGuard::checks` method, it will not find that `safe12temp.mkdir()` is a check for ` return safe12temp` and `temp.mkdir()` is a check for `return safe12temp;`.\r\n\r\nInteresting note: as soon as the outer `null` check is removed, codeQL does correctly identify the guard controls the return. For example, this is detected as correctly guarded:\r\n```java\r\nFile safe12temp;\r\nFile safe12() throws IOException {\r\n\twhile (true) {\r\n safe12temp = File.createTempFile(\"test\", \"directory\");\r\n if (safe12temp.delete() \u0026\u0026 safe12temp.mkdir()) {\r\n break;\r\n }\r\n }\r\n return safe12temp;\r\n}\r\n```\r\n\r\nPractical example:\r\n\r\nhttps://github.com/apache/hive/blob/cba74fa91d4035aee2c39dcf929a0ae480609540/ql/src/java/org/apache/hadoop/hive/ql/exec/spark/HiveKVResultCache.java#L89-L103\r\n\r\nThe above code is flagged as a false positive result when executing this new query: #4473","author":{"url":"https://github.com/JLLeitschuh","@type":"Person","name":"JLLeitschuh"},"datePublished":"2022-03-18T17:23:54.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/8490/codeql/issues/8490"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:a90ef68a-3e5d-4828-1a08-13801ceefc84 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 9BDE:3985C:D2A3B0:11D10C8:6A4D5AF1 |
| html-safe-nonce | 1904ee3040b4d81f3a7b993e36d7c30a6dfd99c50a5a6cc57d1c3f75413a3fd1 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5QkRFOjM5ODVDOkQyQTNCMDoxMUQxMEM4OjZBNEQ1QUYxIiwidmlzaXRvcl9pZCI6Ijk1MTg2NzU5MzI3Mzk4OTg3MyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 0f41e3f1b644f12890d9604f84ffb55669d0844fc24327470609f749818dd95f |
| hovercard-subject-tag | issue:1173833760 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/github/codeql/8490/issue_layout |
| twitter:image | https://opengraph.githubassets.com/b3c5b66da618155a3f241e60374dc3cb01abbebf81d594ef8b84fd02f665c08c/github/codeql/issues/8490 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/b3c5b66da618155a3f241e60374dc3cb01abbebf81d594ef8b84fd02f665c08c/github/codeql/issues/8490 |
| og:image:alt | Take the following two examples: static File safe11() throws IOException { File temp = null; if (temp == null) { while (true) { temp = File.createTempFile("test", "directory"); if (temp.delete() &&... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | JLLeitschuh |
| hostname | github.com |
| expected-hostname | github.com |
| None | 2a1443ff9733a3016431263ea73c93d8fe00c195eb4a7670ac30e7848f045441 |
| turbo-cache-control | no-preview |
| go-import | github.com/github/codeql git https://github.com/github/codeql.git |
| octolytics-dimension-user_id | 9919 |
| octolytics-dimension-user_login | github |
| octolytics-dimension-repository_id | 143040428 |
| octolytics-dimension-repository_nwo | github/codeql |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 143040428 |
| octolytics-dimension-repository_network_root_nwo | github/codeql |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | f3bdd3157ea1f0fd738d408eceeead721acf1dc3 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width