-
Notifications
You must be signed in to change notification settings - Fork 207
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f8132c2
commit ed18cc0
Showing
8 changed files
with
121 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
bugsnag-android-core/src/main/java/com/bugsnag/android/RootDetector.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.bugsnag.android | ||
|
||
import androidx.annotation.VisibleForTesting | ||
import java.io.BufferedReader | ||
import java.io.IOException | ||
|
||
/** | ||
* Attempts to detect whether the device is rooted. Root detection errs on the side of false | ||
* negatives rather than false positives. | ||
* | ||
* This class will only give a reasonable indication that a device has been rooted - as it's | ||
* possible to manipulate Java return values & native library loading, it will always be possible | ||
* for a determined application to defeat these root checks. | ||
*/ | ||
internal class RootDetector { | ||
|
||
fun isRooted() = checkSuExists() | ||
|
||
/** | ||
* Checks whether the su binary exists by running `which su`. A non-empty result | ||
* indicates that the binary is present, which is a good indicator that the device | ||
* may have been rooted. | ||
*/ | ||
fun checkSuExists(): Boolean = checkSuExists(ProcessBuilder()) | ||
|
||
@VisibleForTesting | ||
internal fun checkSuExists(processBuilder: ProcessBuilder): Boolean { | ||
processBuilder.command(listOf("which", "su")) | ||
|
||
var process: Process? = null | ||
return try { | ||
process = processBuilder.start() | ||
val output = process.inputStream.bufferedReader().use(BufferedReader::readText) | ||
output.isNotBlank() | ||
} catch (ignored: IOException) { | ||
false | ||
} finally { | ||
process?.destroy() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
bugsnag-android-core/src/test/java/com/bugsnag/android/RootDetectorTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.bugsnag.android | ||
|
||
import org.junit.Assert.assertFalse | ||
import org.junit.Assert.assertTrue | ||
import org.junit.Before | ||
import org.junit.Test | ||
import org.junit.runner.RunWith | ||
import org.mockito.Mock | ||
import org.mockito.Mockito.`when` | ||
import org.mockito.Mockito.times | ||
import org.mockito.Mockito.verify | ||
import org.mockito.junit.MockitoJUnitRunner | ||
import java.io.ByteArrayInputStream | ||
import java.io.IOException | ||
|
||
@RunWith(MockitoJUnitRunner::class) | ||
class RootDetectorTest { | ||
|
||
private val rootDetector = RootDetector() | ||
|
||
@Mock | ||
lateinit var processBuilder: ProcessBuilder | ||
|
||
@Mock | ||
lateinit var process: Process | ||
|
||
@Before | ||
fun setUp() { | ||
`when`(processBuilder.start()).thenReturn(process) | ||
} | ||
|
||
/** | ||
* IOExceptions thrown when starting the process are handled appropriately | ||
*/ | ||
@Test | ||
fun checkSuProcessStartException() { | ||
`when`(processBuilder.start()).thenThrow(IOException()) | ||
assertFalse(rootDetector.checkSuExists(processBuilder)) | ||
} | ||
|
||
/** | ||
* The method returns false if 'which su' returns an empty string | ||
*/ | ||
@Test | ||
fun checkSuNotFound() { | ||
val emptyStream = ByteArrayInputStream("".toByteArray()) | ||
`when`(process.inputStream).thenReturn(emptyStream) | ||
assertFalse(rootDetector.checkSuExists(processBuilder)) | ||
verify(processBuilder, times(1)).command(listOf("which", "su")) | ||
verify(process, times(1)).destroy() | ||
} | ||
|
||
/** | ||
* The method returns true if 'which su' returns a non-empty string | ||
*/ | ||
@Test | ||
fun checkSuFound() { | ||
val resultStream = ByteArrayInputStream("/system/bin/su".toByteArray()) | ||
`when`(process.inputStream).thenReturn(resultStream) | ||
assertTrue(rootDetector.checkSuExists(processBuilder)) | ||
} | ||
} |