Skip to content

Commit 8e183ff

Browse files
committed
Use ReLinker to load os-compat library
1 parent c067690 commit 8e183ff

4 files changed

Lines changed: 53 additions & 5 deletions

File tree

SafeContentResolver-v14/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ android {
2020

2121
dependencies {
2222
compile project(':SafeContentResolver')
23+
compile 'com.getkeepsafe.relinker:relinker:1.2.1'
2324
compile 'com.android.support:support-annotations:23.2.0'
2425
}

SafeContentResolver-v14/src/main/java/de/cketti/safecontentresolver/Os.java

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,56 @@
1616
package de.cketti.safecontentresolver;
1717

1818

19+
import android.content.Context;
20+
21+
import com.getkeepsafe.relinker.MissingLibraryException;
22+
import com.getkeepsafe.relinker.ReLinker;
23+
24+
1925
class Os {
20-
static {
21-
System.loadLibrary("os-compat");
26+
private static final String LIBRARY_NAME = "os-compat";
27+
28+
private static Context context;
29+
private static boolean libraryNeedsLoading = true;
30+
private static UnsupportedOperationException loadFailedException;
31+
32+
33+
synchronized static void init(Context context) {
34+
if (context == null) {
35+
throw new NullPointerException("Argument 'context' must not be null");
36+
}
37+
38+
// Only get the context here. Load the library before doing the actual work (hopefully in a background thread).
39+
if (Os.context == null) {
40+
Os.context = context.getApplicationContext();
41+
}
42+
}
43+
44+
static int fstat(int fileDescriptor) throws ErrnoException, UnsupportedOperationException {
45+
synchronized (Os.class) {
46+
if (context == null) {
47+
throw new IllegalStateException("Call Os.init(Context) before attempting to call Os.fstat()");
48+
}
49+
50+
if (libraryNeedsLoading) {
51+
loadLibrary();
52+
} else if (loadFailedException != null) {
53+
throw loadFailedException;
54+
}
55+
}
56+
57+
return nativeFstat(fileDescriptor);
58+
}
59+
60+
private static void loadLibrary() {
61+
libraryNeedsLoading = false;
62+
try {
63+
ReLinker.loadLibrary(context, LIBRARY_NAME);
64+
} catch (MissingLibraryException | UnsatisfiedLinkError e) {
65+
loadFailedException = new UnsupportedOperationException("Failed to load native library " + LIBRARY_NAME, e);
66+
throw loadFailedException;
67+
}
2268
}
2369

24-
public static native int fstat(int fileDescriptor) throws ErrnoException;
70+
private static native int nativeFstat(int fileDescriptor) throws ErrnoException;
2571
}

SafeContentResolver-v14/src/main/java/de/cketti/safecontentresolver/SafeContentResolverApi14.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
class SafeContentResolverApi14 extends SafeContentResolver {
2828
SafeContentResolverApi14(Context context) {
2929
super(context);
30+
Os.init(context);
3031
}
3132

3233
@Override
@@ -35,7 +36,7 @@ protected int getFileUidOrThrow(@NonNull FileDescriptor fileDescriptor) throws F
3536
int systemFileDescriptor = extractSystemFileDescriptor(fileDescriptor);
3637

3738
return Os.fstat(systemFileDescriptor);
38-
} catch (ErrnoException e) {
39+
} catch (ErrnoException | UnsupportedOperationException e) {
3940
throw new FileNotFoundException(e.getMessage());
4041
}
4142
}

SafeContentResolver-v14/src/main/jni/os-compat.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030

3131
JNIEXPORT jint JNICALL
32-
Java_de_cketti_safecontentresolver_Os_fstat(JNIEnv *env, jclass type, jint fileDescriptor) {
32+
Java_de_cketti_safecontentresolver_Os_nativeFstat(JNIEnv *env, jclass type, jint fileDescriptor) {
3333
struct stat sb;
3434

3535
int rc = TEMP_FAILURE_RETRY(fstat(fileDescriptor, &sb));

0 commit comments

Comments
 (0)