3

私の問題に関する簡単な背景:

DomainTypeEnforcementの仕様をJavaSecurityManagerコードに変換するコンパイラを作成しています。一言で言えば、DTEは「タイプ」(オブジェクト)を定義し、それらのタイプにパスを割り当てます。次に、「ドメイン」(サブジェクト)を定義し、さまざまなタイプに対してドメインが持つ権限(rwxdc)を定義します。JSMでこの動作を可能な限りエミュレートする必要があります。

現在、書き込み権限に取り組んでいます。JSMのcheckWrite(String filename)メソッドを正常にオーバーライドしました。次のリストはcheckWrite(FileDescriptor filedescriptor)であり、これはより注意が必要です。DTEの定義方法により、書き込みアクションが許可されるかどうかを判断するためのパス情報が必要です。

  • FileDescriptorからパスデータを抽出することは可能ですか?いいえと思います-ドキュメントとさまざまなチュートリアルを確認しましたが、この情報を取得する方法があることを示唆するものは何も見つかりませんでした(ただし、間違って表示されることを嬉しく思います。私の仕事を簡単にします)。

  • 上記の答えが「いいえ」の場合、誰かが実行可能な回避策を提案できますか?たとえば、ネイティブコードを記述して、自分がやりたいことを実行し、これをカスタムJSMクラスに結び付ける方法はありますか?私はそのような「高度な」ことをするのは問題ありませんが、どのように始めるかについていくつかのアイデアが必要です。

  • または、基本的にFileDescriptorを使用するすべての書き込み権限を拒否する唯一のオプションですか?これは厄介な解決策なので避けたいのですが、それが現実である場合は知っておく必要があります。

お時間をいただき、誠にありがとうございます。

4

3 に答える 3

4

ファイルはそのファイルへのアクセスに使用されるパスから独立しているため(少なくとも重要なOSでは)、簡単な答えはノーです。

考えられる回避策の1つは、アスペクトフレームワークを使用してファイルを開く呼び出しをトラップし、参照されるファイル記述子をに配置することWeakHashMap<FileDescriptor,File>です。次に、書き込みを検証する必要があるときはいつでも、このマップを見るだけです。

于 2012-09-05T17:24:38.060 に答える
1

うまくいけば、リフレクションの制限によってブロックされることはありませんが、今のところ、Android Oから始めてこれを使用できます(他の答えに少し基づいたコード):

val file = File(filesDir, "ff")
file.parentFile!!.mkdirs()
val fileOutputStream = FileOutputStream(file)
val fd = fileOutputStream.fd
val method = fd.javaClass.getMethod("getInt$")
val fdId = method.invoke(fd)
val path = Paths.get("/proc/self/fd/$fdId")
val filePath = Files.readSymbolicLink(path)
Log.d("AppLog", "filePath:$filePath")

ただし、FileChannelについてはよくわかりません。その実装ファイル( "FileChannelImpl")には、 "path"(ファイルパス文字列型)とFileDescriptorである "fd"が含まれているはずですが、どちらもリフレクションによって非表示になっています。

于 2020-06-27T10:36:11.300 に答える
0

JavaでFileDescriptorからパスを取得するためのソリューション:

使い方:

ファイル記述子には、現在のプロセスで開いているファイルを見つけるための記述子IDが含まれていることがわかっています。

簡単な言葉で説明されているファイル記述子とは何ですか?

記述子IDがわかっている場合は、Javaコードに従ってファイルパスを簡単に見つけることができます。

Path path = Paths.get("/proc/self/fd/"+fd_id);
System.out.println(Files.readSymbolicLink(path)); //return file path in file descriptor

ここ:

fd_idファイル記述子ID(0,1,2 .....)

/ procそのディレクトリには、システムで実行されているすべてのプロセスが含まれています

/selfは現在JavaクラスのプロセスIDを実行しています

/fdファイル記述子ディレクトリ

//fd_idファイル記述子ID

SafeFileDescriptor.java

import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.nio.file.Path;  
public class SafeFileDescriptor {

 static {
    System.load("Documents/java native interface exmples/libSafeFileDescriptor.so");
}

private native int getFDid(FileDescriptor fd);

public static void main(String[] args) throws IOException{  
    FileOutputStream fout = new FileOutputStream("Documents/test.txt");
    FileDescriptor fd=fout.getFD();
    int fd_id = new SafeFileDescriptor().getFDid(fd);
    Path path = Paths.get("/proc/self/fd/"+fd_id);
    System.out.println(Files.readSymbolicLink(path));
}
}

getFDid()指定されたファイル記述子オブジェクトの記述子IDを取得するために使用されるネイティブメソッドです

次のコードはgetFDid()ネイティブメソッドの実装です

SafeFileDescriptor.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class SafeFileDescriptor */

#ifndef _Included_SafeFileDescriptor
#define _Included_SafeFileDescriptor
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     SafeFileDescriptor
 * Method:    getFDid
 * Signature: (Ljava/io/FileDescriptor;)I
 */
JNIEXPORT jint JNICALL Java_SafeFileDescriptor_getFDid
  (JNIEnv *, jobject, jobject);

#ifdef __cplusplus
}
#endif
#endif

JavaファイルSafeFileDescriptor.javaからSafeFileDescriptor.hを作成します

javac -h dir SafeFileDescriptor.java

「dir」をディレクトリに置き換えて、SafeFileDescriptor.hを保存します

SafeFileDescriptor.c

#include <jni.h>
#include "SafeFileDescriptor.h"

JNIEXPORT jint JNICALL Java_SafeFileDescriptor_getFDid
  (JNIEnv *env, jobject this_object, jobject fdObject) {

    jclass fileDescriptor = (*env)->GetObjectClass(env,fdObject);

    jfieldID id_fd = (*env)->GetFieldID(env, fileDescriptor, "fd", "I");

    return (*env)->GetIntField(env,fdObject,id_fd);
}

SafeFileDescriptor.cをコンパイルします

gcc -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/linux" -shared -o libSafeFileDescriptor.so SafeFileDescriptor.c

libSafeFileDescriptor.soファイルをJavaクラスファイルに追加するには

System.load("Documents/java native interface exmples/libSafeFileDescriptor.so");
于 2019-05-14T06:19:17.760 に答える