Merge "Set app.metadata file permission to 640"

This commit is contained in:
William Loh
2023-02-15 05:59:54 +00:00
committed by Android (Google) Code Review
9 changed files with 40 additions and 28 deletions

View File

@@ -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();
}

View File

@@ -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"

View File

@@ -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.

View 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);
}
/**

View File

@@ -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.

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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,

View File

@@ -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;