From 9102f5d953fbde03e12f385b2225004edc43d202 Mon Sep 17 00:00:00 2001 From: Paul Crowley Date: Wed, 22 Apr 2015 13:36:59 +0100 Subject: [PATCH] Use mount service to create user dirs. Bug: 19704432 Change-Id: Iee037ca653482b0ee7bf59c7ba193c75411fe42f --- .../android/os/storage/IMountService.java | 34 +++++++++++++++++++ .../android/os/storage/StorageManager.java | 9 +++++ .../java/com/android/server/MountService.java | 29 ++++++++++++++++ .../java/com/android/server/pm/Settings.java | 9 +++-- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index e55ae99280426..35e535d41d4a4 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -1177,6 +1177,22 @@ public interface IMountService extends IInterface { _data.recycle(); } } + + @Override + public void createNewUserDir(int userHandle, String path) throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeInt(userHandle); + _data.writeString(path); + mRemote.transact(Stub.TRANSACTION_createNewUserDir, _data, _reply, 0); + _reply.readException(); + } finally { + _reply.recycle(); + _data.recycle(); + } + } } private static final String DESCRIPTOR = "IMountService"; @@ -1292,6 +1308,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_benchmark = IBinder.FIRST_CALL_TRANSACTION + 59; static final int TRANSACTION_setDebugFlags = IBinder.FIRST_CALL_TRANSACTION + 60; + static final int TRANSACTION_createNewUserDir = IBinder.FIRST_CALL_TRANSACTION + 61; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -1845,6 +1863,14 @@ public interface IMountService extends IInterface { reply.writeNoException(); return true; } + case TRANSACTION_createNewUserDir: { + data.enforceInterface(DESCRIPTOR); + int userHandle = data.readInt(); + String path = data.readString(); + createNewUserDir(userHandle, path); + reply.writeNoException(); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -2154,4 +2180,12 @@ public interface IMountService extends IInterface { public String getPrimaryStorageUuid() throws RemoteException; public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) throws RemoteException; + + /** + * Creates the user data directory, possibly encrypted + * @param userHandle Handle of the user whose directory we are creating + * @param path Path at which to create the directory. + */ + public void createNewUserDir(int userHandle, String path) + throws RemoteException; } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 8ff56f8cc1397..0502397195081 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -901,6 +901,15 @@ public class StorageManager { DEFAULT_FULL_THRESHOLD_BYTES); } + /** {@hide} */ + public void createNewUserDir(int userHandle, File path) { + try { + mMountService.createNewUserDir(userHandle, path.getAbsolutePath()); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + } + /** {@hide} */ public static File maybeTranslateEmulatedPathToInternal(File path) { final IMountService mountService = IMountService.Stub.asInterface( diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index d48953db8f45e..8c6c25b112b6c 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -48,6 +48,7 @@ import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.ServiceManager; @@ -2307,6 +2308,34 @@ class MountService extends IMountService.Stub } } + @Override + public void createNewUserDir(int userHandle, String path) { + if (Binder.getCallingUid() != Process.SYSTEM_UID) { + throw new SecurityException("Only SYSTEM_UID can create user directories"); + } + + waitForReady(); + + if (DEBUG_EVENTS) { + Slog.i(TAG, "Creating new user dir"); + } + + try { + NativeDaemonEvent event = mConnector.execute( + "cryptfs", "createnewuserdir", userHandle, path); + if (!"0".equals(event.getMessage())) { + String error = "createnewuserdir sent unexpected message: " + + event.getMessage(); + Slog.e(TAG, error); + // ext4enc:TODO is this the right exception? + throw new RuntimeException(error); + } + } catch (NativeDaemonConnectorException e) { + Slog.e(TAG, "createnewuserdir threw exception", e); + throw new RuntimeException("createnewuserdir threw exception", e); + } + } + @Override public int mkdirs(String callingPkg, String appPath) { final int userId = UserHandle.getUserId(Binder.getCallingUid()); diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index d2a135c9787b9..4ad7c7c0a51e5 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -37,13 +37,17 @@ import android.os.Binder; import android.os.Build; import android.os.Environment; import android.os.FileUtils; +import android.os.IBinder; import android.os.Handler; import android.os.Message; import android.os.PatternMatcher; import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; +import android.os.storage.StorageManager; import android.os.storage.VolumeInfo; import android.util.AtomicFile; import android.text.TextUtils; @@ -3493,9 +3497,8 @@ final class Settings { void createNewUserLILPw(PackageManagerService service, Installer installer, int userHandle, File path) { - path.mkdir(); - FileUtils.setPermissions(path.toString(), FileUtils.S_IRWXU | FileUtils.S_IRWXG - | FileUtils.S_IXOTH, -1, -1); + service.mContext.getSystemService(StorageManager.class) + .createNewUserDir(userHandle, path); for (PackageSetting ps : mPackages.values()) { if (ps.pkg == null || ps.pkg.applicationInfo == null) { continue;