Merge "Set app.metadata file permission to 640"
This commit is contained in:
@@ -93,6 +93,7 @@ import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.ParcelableException;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Process;
|
||||
@@ -126,9 +127,6 @@ import dalvik.system.VMRuntime;
|
||||
|
||||
import libcore.util.EmptyArray;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.ref.WeakReference;
|
||||
@@ -1233,25 +1231,23 @@ public class ApplicationPackageManager extends PackageManager {
|
||||
public PersistableBundle getAppMetadata(@NonNull String packageName)
|
||||
throws NameNotFoundException {
|
||||
PersistableBundle appMetadata = null;
|
||||
String path = null;
|
||||
ParcelFileDescriptor pfd = null;
|
||||
try {
|
||||
path = mPM.getAppMetadataPath(packageName, getUserId());
|
||||
pfd = mPM.getAppMetadataFd(packageName, getUserId());
|
||||
} catch (ParcelableException e) {
|
||||
e.maybeRethrow(NameNotFoundException.class);
|
||||
throw new RuntimeException(e);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
if (path != null) {
|
||||
File file = new File(path);
|
||||
try (InputStream inputStream = new FileInputStream(file)) {
|
||||
if (pfd != null) {
|
||||
try (InputStream inputStream = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
|
||||
appMetadata = PersistableBundle.readFromStream(inputStream);
|
||||
} catch (FileNotFoundException e) {
|
||||
// ignore and return empty bundle if app metadata does not exist
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return appMetadata != null ? appMetadata : new PersistableBundle();
|
||||
}
|
||||
|
||||
|
||||
@@ -159,7 +159,8 @@ interface IPackageManager {
|
||||
*/
|
||||
ParceledListSlice getInstalledPackages(long flags, in int userId);
|
||||
|
||||
String getAppMetadataPath(String packageName, int userId);
|
||||
@nullable ParcelFileDescriptor getAppMetadataFd(String packageName,
|
||||
int userId);
|
||||
|
||||
/**
|
||||
* This implements getPackagesHoldingPermissions via a "last returned row"
|
||||
|
||||
@@ -83,7 +83,7 @@ interface IIncrementalService {
|
||||
/**
|
||||
* Creates a file under a storage.
|
||||
*/
|
||||
int makeFile(int storageId, in @utf8InCpp String path, in IncrementalNewFileParams params, in @nullable byte[] content);
|
||||
int makeFile(int storageId, in @utf8InCpp String path, int mode, in IncrementalNewFileParams params, in @nullable byte[] content);
|
||||
|
||||
/**
|
||||
* Creates a file under a storage. Content of the file is from a range inside another file.
|
||||
|
||||
@@ -153,7 +153,8 @@ public final class IncrementalFileStorages {
|
||||
final String apkName = apk.name;
|
||||
final File targetFile = new File(mStageDir, apkName);
|
||||
if (!targetFile.exists()) {
|
||||
mDefaultStorage.makeFile(apkName, apk.size, null, apk.metadata, apk.signature, null);
|
||||
mDefaultStorage.makeFile(apkName, apk.size, 0777, null, apk.metadata,
|
||||
apk.signature, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,8 +177,10 @@ public final class IncrementalFileStorages {
|
||||
/**
|
||||
* Creates file in default storage and sets its content.
|
||||
*/
|
||||
public void makeFile(@NonNull String name, @NonNull byte[] content) throws IOException {
|
||||
mDefaultStorage.makeFile(name, content.length, UUID.randomUUID(), null, null, content);
|
||||
public void makeFile(@NonNull String name, @NonNull byte[] content,
|
||||
@NonNull int mode) throws IOException {
|
||||
mDefaultStorage.makeFile(name, content.length, mode, UUID.randomUUID(),
|
||||
null, null, content);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -173,11 +173,12 @@ public final class IncrementalStorage {
|
||||
*
|
||||
* @param path Relative path of the new file.
|
||||
* @param size Size of the new file in bytes.
|
||||
* @param mode File access permission mode.
|
||||
* @param metadata Metadata bytes.
|
||||
* @param v4signatureBytes Serialized V4SignatureProto.
|
||||
* @param content Optionally set file content.
|
||||
*/
|
||||
public void makeFile(@NonNull String path, long size, @Nullable UUID id,
|
||||
public void makeFile(@NonNull String path, long size, int mode, @Nullable UUID id,
|
||||
@Nullable byte[] metadata, @Nullable byte[] v4signatureBytes, @Nullable byte[] content)
|
||||
throws IOException {
|
||||
try {
|
||||
@@ -190,7 +191,7 @@ public final class IncrementalStorage {
|
||||
params.metadata = (metadata == null ? new byte[0] : metadata);
|
||||
params.fileId = idToBytes(id);
|
||||
params.signature = v4signatureBytes;
|
||||
int res = mService.makeFile(mId, path, params, content);
|
||||
int res = mService.makeFile(mId, path, mode, params, content);
|
||||
if (res != 0) {
|
||||
throw new IOException("makeFile() failed with errno " + -res);
|
||||
}
|
||||
@@ -199,7 +200,6 @@ public final class IncrementalStorage {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a file in Incremental storage. The content of the file is mapped from a range inside
|
||||
* a source file in the same storage.
|
||||
|
||||
@@ -317,6 +317,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
/** Default byte size limit for app metadata */
|
||||
private static final long DEFAULT_APP_METADATA_BYTE_SIZE_LIMIT = 32000;
|
||||
|
||||
private static final int APP_METADATA_FILE_ACCESS_MODE = 0640;
|
||||
|
||||
// TODO: enforce INSTALL_ALLOW_TEST
|
||||
// TODO: enforce INSTALL_ALLOW_DOWNGRADE
|
||||
|
||||
@@ -1663,9 +1665,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
Binder.restoreCallingIdentity(identity);
|
||||
}
|
||||
|
||||
// If file is app metadata then set permission to 0640 to deny user read access since it
|
||||
// might contain sensitive information.
|
||||
int mode = name.equals(APP_METADATA_FILE_NAME) ? APP_METADATA_FILE_ACCESS_MODE : 0644;
|
||||
ParcelFileDescriptor targetPfd = openTargetInternal(target.getAbsolutePath(),
|
||||
O_CREAT | O_WRONLY, 0644);
|
||||
Os.chmod(target.getAbsolutePath(), 0644);
|
||||
O_CREAT | O_WRONLY, mode);
|
||||
Os.chmod(target.getAbsolutePath(), mode);
|
||||
|
||||
// If caller specified a total length, allocate it for them. Free up
|
||||
// cache space to grow, if needed.
|
||||
@@ -3148,7 +3153,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
getIncrementalFileStorages();
|
||||
try {
|
||||
incrementalFileStorages.makeFile(APP_METADATA_FILE_NAME,
|
||||
Files.readAllBytes(appMetadataFile.toPath()));
|
||||
Files.readAllBytes(appMetadataFile.toPath()),
|
||||
APP_METADATA_FILE_ACCESS_MODE);
|
||||
} catch (IOException e) {
|
||||
Slog.e(TAG, "Failed to write app metadata to incremental storage", e);
|
||||
} finally {
|
||||
@@ -3416,7 +3422,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
|
||||
if (!isIncrementalInstallation() || incrementalFileStorages == null) {
|
||||
FileUtils.bytesToFile(absolutePath, bytes);
|
||||
} else {
|
||||
incrementalFileStorages.makeFile(localPath, bytes);
|
||||
incrementalFileStorages.makeFile(localPath, bytes, 0777);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -131,6 +131,7 @@ import android.os.HandlerThread;
|
||||
import android.os.IBinder;
|
||||
import android.os.Message;
|
||||
import android.os.Parcel;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.ParcelableException;
|
||||
import android.os.PersistableBundle;
|
||||
import android.os.Process;
|
||||
@@ -5148,8 +5149,8 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAppMetadataPath(String packageName, int userId) {
|
||||
mContext.enforceCallingOrSelfPermission(GET_APP_METADATA, "getAppMetadataPath");
|
||||
public ParcelFileDescriptor getAppMetadataFd(String packageName, int userId) {
|
||||
mContext.enforceCallingOrSelfPermission(GET_APP_METADATA, "getAppMetadataFd");
|
||||
final int callingUid = Binder.getCallingUid();
|
||||
final Computer snapshot = snapshotComputer();
|
||||
final PackageStateInternal ps = snapshot.getPackageStateForInstalledAndFiltered(
|
||||
@@ -5158,7 +5159,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService
|
||||
throw new ParcelableException(
|
||||
new PackageManager.NameNotFoundException(packageName));
|
||||
}
|
||||
return new File(ps.getPathString(), APP_METADATA_FILE_NAME).getAbsolutePath();
|
||||
try {
|
||||
File file = new File(ps.getPath(), APP_METADATA_FILE_NAME);
|
||||
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -223,7 +223,7 @@ static std::span<const uint8_t> toSpan(const ::std::optional<::std::vector<uint8
|
||||
}
|
||||
|
||||
binder::Status BinderIncrementalService::makeFile(
|
||||
int32_t storageId, const std::string& path,
|
||||
int32_t storageId, const std::string& path, int32_t mode,
|
||||
const ::android::os::incremental::IncrementalNewFileParams& params,
|
||||
const ::std::optional<::std::vector<uint8_t>>& content, int32_t* _aidl_return) {
|
||||
auto [err, fileId, nfp] = toMakeFileParams(params);
|
||||
@@ -232,7 +232,7 @@ binder::Status BinderIncrementalService::makeFile(
|
||||
return ok();
|
||||
}
|
||||
|
||||
*_aidl_return = mImpl.makeFile(storageId, path, 0777, fileId, nfp, toSpan(content));
|
||||
*_aidl_return = mImpl.makeFile(storageId, path, mode, fileId, nfp, toSpan(content));
|
||||
return ok();
|
||||
}
|
||||
binder::Status BinderIncrementalService::makeFileFromRange(int32_t storageId,
|
||||
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
int32_t* _aidl_return) final;
|
||||
binder::Status makeDirectories(int32_t storageId, const std::string& path,
|
||||
int32_t* _aidl_return) final;
|
||||
binder::Status makeFile(int32_t storageId, const std::string& path,
|
||||
binder::Status makeFile(int32_t storageId, const std::string& path, int32_t mode,
|
||||
const IncrementalNewFileParams& params,
|
||||
const ::std::optional<::std::vector<uint8_t>>& content,
|
||||
int32_t* _aidl_return) final;
|
||||
|
||||
Reference in New Issue
Block a user