Loading cmds/cmd/cmd.cpp +43 −10 Original line number Diff line number Diff line Loading @@ -61,7 +61,8 @@ class MyShellCallback : public BnShellCallback public: bool mActive = true; virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) { String8 path8(path); char cwd[256]; getcwd(cwd, 256); Loading @@ -71,7 +72,26 @@ public: aerr << "Open attempt after active for: " << fullPath << endl; return -EPERM; } int fd = open(fullPath.string(), O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG); int flags = 0; bool checkRead = false; bool checkWrite = false; if (mode == String16("w")) { flags = O_WRONLY|O_CREAT|O_TRUNC; checkWrite = true; } else if (mode == String16("w+")) { flags = O_RDWR|O_CREAT|O_TRUNC; checkRead = checkWrite = true; } else if (mode == String16("r")) { flags = O_RDONLY; checkRead = true; } else if (mode == String16("r+")) { flags = O_RDWR; checkRead = checkWrite = true; } else { aerr << "Invalid mode requested: " << mode.string() << endl; return -EINVAL; } int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG); if (fd < 0) { return fd; } Loading @@ -80,16 +100,29 @@ public: security_context_t tmp = NULL; int ret = getfilecon(fullPath.string(), &tmp); Unique_SecurityContext context(tmp); if (checkWrite) { int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), "file", "write", NULL); if (accessGranted != 0) { close(fd); aerr << "System server has no access to file context " << context.get() aerr << "System server has no access to write file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } if (checkRead) { int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), "file", "read", NULL); if (accessGranted != 0) { close(fd); aerr << "System server has no access to read file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } } return fd; } }; Loading libs/binder/IShellCallback.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -39,11 +39,13 @@ public: { } virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) { Parcel data, reply; data.writeInterfaceToken(IShellCallback::getInterfaceDescriptor()); data.writeString16(path); data.writeString16(seLinuxContext); data.writeString16(mode); remote()->transact(OP_OPEN_OUTPUT_FILE, data, &reply, 0); reply.readExceptionCode(); int fd = reply.readParcelFileDescriptor(); Loading @@ -64,7 +66,8 @@ status_t BnShellCallback::onTransact( CHECK_INTERFACE(IShellCallback, data, reply); String16 path(data.readString16()); String16 seLinuxContext(data.readString16()); int fd = openOutputFile(path, seLinuxContext); String16 mode(data.readString16()); int fd = openFile(path, seLinuxContext, mode); if (reply != NULL) { reply->writeNoException(); if (fd >= 0) { Loading libs/binder/include/binder/IShellCallback.h +2 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ class IShellCallback : public IInterface public: DECLARE_META_INTERFACE(ShellCallback); virtual int openOutputFile(const String16& path, const String16& seLinuxContext) = 0; virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) = 0; enum { OP_OPEN_OUTPUT_FILE = IBinder::FIRST_CALL_TRANSACTION Loading Loading
cmds/cmd/cmd.cpp +43 −10 Original line number Diff line number Diff line Loading @@ -61,7 +61,8 @@ class MyShellCallback : public BnShellCallback public: bool mActive = true; virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) { String8 path8(path); char cwd[256]; getcwd(cwd, 256); Loading @@ -71,7 +72,26 @@ public: aerr << "Open attempt after active for: " << fullPath << endl; return -EPERM; } int fd = open(fullPath.string(), O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG); int flags = 0; bool checkRead = false; bool checkWrite = false; if (mode == String16("w")) { flags = O_WRONLY|O_CREAT|O_TRUNC; checkWrite = true; } else if (mode == String16("w+")) { flags = O_RDWR|O_CREAT|O_TRUNC; checkRead = checkWrite = true; } else if (mode == String16("r")) { flags = O_RDONLY; checkRead = true; } else if (mode == String16("r+")) { flags = O_RDWR; checkRead = checkWrite = true; } else { aerr << "Invalid mode requested: " << mode.string() << endl; return -EINVAL; } int fd = open(fullPath.string(), flags, S_IRWXU|S_IRWXG); if (fd < 0) { return fd; } Loading @@ -80,16 +100,29 @@ public: security_context_t tmp = NULL; int ret = getfilecon(fullPath.string(), &tmp); Unique_SecurityContext context(tmp); if (checkWrite) { int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), "file", "write", NULL); if (accessGranted != 0) { close(fd); aerr << "System server has no access to file context " << context.get() aerr << "System server has no access to write file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } if (checkRead) { int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), "file", "read", NULL); if (accessGranted != 0) { close(fd); aerr << "System server has no access to read file context " << context.get() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } } return fd; } }; Loading
libs/binder/IShellCallback.cpp +5 −2 Original line number Diff line number Diff line Loading @@ -39,11 +39,13 @@ public: { } virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) { Parcel data, reply; data.writeInterfaceToken(IShellCallback::getInterfaceDescriptor()); data.writeString16(path); data.writeString16(seLinuxContext); data.writeString16(mode); remote()->transact(OP_OPEN_OUTPUT_FILE, data, &reply, 0); reply.readExceptionCode(); int fd = reply.readParcelFileDescriptor(); Loading @@ -64,7 +66,8 @@ status_t BnShellCallback::onTransact( CHECK_INTERFACE(IShellCallback, data, reply); String16 path(data.readString16()); String16 seLinuxContext(data.readString16()); int fd = openOutputFile(path, seLinuxContext); String16 mode(data.readString16()); int fd = openFile(path, seLinuxContext, mode); if (reply != NULL) { reply->writeNoException(); if (fd >= 0) { Loading
libs/binder/include/binder/IShellCallback.h +2 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,8 @@ class IShellCallback : public IInterface public: DECLARE_META_INTERFACE(ShellCallback); virtual int openOutputFile(const String16& path, const String16& seLinuxContext) = 0; virtual int openFile(const String16& path, const String16& seLinuxContext, const String16& mode) = 0; enum { OP_OPEN_OUTPUT_FILE = IBinder::FIRST_CALL_TRANSACTION Loading