Loading cmds/cmd/Android.mk +4 −1 Original line number Original line Diff line number Diff line Loading @@ -7,8 +7,11 @@ LOCAL_SRC_FILES:= \ LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ libutils \ libutils \ liblog \ liblog \ libselinux \ libbinder libbinder LOCAL_C_INCLUDES += \ $(JNI_H_INCLUDE) ifeq ($(TARGET_OS),linux) ifeq ($(TARGET_OS),linux) LOCAL_CFLAGS += -DXP_UNIX LOCAL_CFLAGS += -DXP_UNIX Loading cmds/cmd/cmd.cpp +48 −1 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <binder/ProcessState.h> #include <binder/ProcessState.h> #include <binder/IResultReceiver.h> #include <binder/IResultReceiver.h> #include <binder/IServiceManager.h> #include <binder/IServiceManager.h> #include <binder/IShellCallback.h> #include <binder/TextOutput.h> #include <binder/TextOutput.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading @@ -29,7 +30,14 @@ #include <stdio.h> #include <stdio.h> #include <string.h> #include <string.h> #include <unistd.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <sys/time.h> #include <errno.h> #include "selinux/selinux.h" #include "selinux/android.h" #include <UniquePtr.h> using namespace android; using namespace android; Loading @@ -38,6 +46,45 @@ static int sort_func(const String16* lhs, const String16* rhs) return lhs->compare(*rhs); return lhs->compare(*rhs); } } struct SecurityContext_Delete { void operator()(security_context_t p) const { freecon(p); } }; typedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext; class MyShellCallback : public BnShellCallback { public: virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { String8 path8(path); char cwd[256]; getcwd(cwd, 256); String8 fullPath(cwd); fullPath.appendPath(path8); int fd = open(fullPath.string(), O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG); if (fd < 0) { return fd; } if (is_selinux_enabled() && seLinuxContext.size() > 0) { String8 seLinuxContext8(seLinuxContext); security_context_t tmp = NULL; int ret = getfilecon(fullPath.string(), &tmp); Unique_SecurityContext context(tmp); 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() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } return fd; } }; class MyResultReceiver : public BnResultReceiver class MyResultReceiver : public BnResultReceiver { { public: public: Loading Loading @@ -91,6 +138,6 @@ int main(int argc, char* const argv[]) // TODO: block until a result is returned to MyResultReceiver. // TODO: block until a result is returned to MyResultReceiver. IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, new MyResultReceiver()); new MyShellCallback(), new MyResultReceiver()); return 0; return 0; } } include/binder/IBinder.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ class BpBinder; class IInterface; class IInterface; class Parcel; class Parcel; class IResultReceiver; class IResultReceiver; class IShellCallback; /** /** * Base class and low-level protocol for a remotable object. * Base class and low-level protocol for a remotable object. Loading Loading @@ -82,7 +83,7 @@ public: virtual status_t pingBinder() = 0; virtual status_t pingBinder() = 0; virtual status_t dump(int fd, const Vector<String16>& args) = 0; virtual status_t dump(int fd, const Vector<String16>& args) = 0; static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err, static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err, Vector<String16>& args, Vector<String16>& args, const sp<IShellCallback>& callback, const sp<IResultReceiver>& resultReceiver); const sp<IResultReceiver>& resultReceiver); virtual status_t transact( uint32_t code, virtual status_t transact( uint32_t code, Loading include/binder/IShellCallback.h 0 → 100644 +55 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // #ifndef ANDROID_ISHELL_CALLBACK_H #define ANDROID_ISHELL_CALLBACK_H #include <binder/IInterface.h> namespace android { // ---------------------------------------------------------------------- class IShellCallback : public IInterface { public: DECLARE_META_INTERFACE(ShellCallback); virtual int openOutputFile(const String16& path, const String16& seLinuxContext) = 0; enum { OP_OPEN_OUTPUT_FILE = IBinder::FIRST_CALL_TRANSACTION }; }; // ---------------------------------------------------------------------- class BnShellCallback : public BnInterface<IShellCallback> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; // ---------------------------------------------------------------------- }; // namespace android #endif // ANDROID_ISHELL_CALLBACK_H include/binder/Parcel.h +11 −2 Original line number Original line Diff line number Diff line Loading @@ -188,6 +188,11 @@ public: // will be closed once the parcel is destroyed. // will be closed once the parcel is destroyed. status_t writeDupFileDescriptor(int fd); status_t writeDupFileDescriptor(int fd); // Place a Java "parcel file descriptor" into the parcel. The given fd must remain // valid for the lifetime of the parcel. // The Parcel does not take ownership of the given fd unless you ask it to. status_t writeParcelFileDescriptor(int fd, bool takeOwnership = false); // Place a file descriptor into the parcel. This will not affect the // Place a file descriptor into the parcel. This will not affect the // semantics of the smart file descriptor. A new descriptor will be // semantics of the smart file descriptor. A new descriptor will be // created, and will be closed when the parcel is destroyed. // created, and will be closed when the parcel is destroyed. Loading Loading @@ -334,6 +339,10 @@ public: // in the parcel, which you do not own -- use dup() to get your own copy. // in the parcel, which you do not own -- use dup() to get your own copy. int readFileDescriptor() const; int readFileDescriptor() const; // Retrieve a Java "parcel file descriptor" from the parcel. This returns the raw fd // in the parcel, which you do not own -- use dup() to get your own copy. int readParcelFileDescriptor() const; // Retrieve a smart file descriptor from the parcel. // Retrieve a smart file descriptor from the parcel. status_t readUniqueFileDescriptor( status_t readUniqueFileDescriptor( base::unique_fd* val) const; base::unique_fd* val) const; Loading Loading
cmds/cmd/Android.mk +4 −1 Original line number Original line Diff line number Diff line Loading @@ -7,8 +7,11 @@ LOCAL_SRC_FILES:= \ LOCAL_SHARED_LIBRARIES := \ LOCAL_SHARED_LIBRARIES := \ libutils \ libutils \ liblog \ liblog \ libselinux \ libbinder libbinder LOCAL_C_INCLUDES += \ $(JNI_H_INCLUDE) ifeq ($(TARGET_OS),linux) ifeq ($(TARGET_OS),linux) LOCAL_CFLAGS += -DXP_UNIX LOCAL_CFLAGS += -DXP_UNIX Loading
cmds/cmd/cmd.cpp +48 −1 Original line number Original line Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <binder/ProcessState.h> #include <binder/ProcessState.h> #include <binder/IResultReceiver.h> #include <binder/IResultReceiver.h> #include <binder/IServiceManager.h> #include <binder/IServiceManager.h> #include <binder/IShellCallback.h> #include <binder/TextOutput.h> #include <binder/TextOutput.h> #include <utils/Vector.h> #include <utils/Vector.h> Loading @@ -29,7 +30,14 @@ #include <stdio.h> #include <stdio.h> #include <string.h> #include <string.h> #include <unistd.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <sys/time.h> #include <errno.h> #include "selinux/selinux.h" #include "selinux/android.h" #include <UniquePtr.h> using namespace android; using namespace android; Loading @@ -38,6 +46,45 @@ static int sort_func(const String16* lhs, const String16* rhs) return lhs->compare(*rhs); return lhs->compare(*rhs); } } struct SecurityContext_Delete { void operator()(security_context_t p) const { freecon(p); } }; typedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext; class MyShellCallback : public BnShellCallback { public: virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { String8 path8(path); char cwd[256]; getcwd(cwd, 256); String8 fullPath(cwd); fullPath.appendPath(path8); int fd = open(fullPath.string(), O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG); if (fd < 0) { return fd; } if (is_selinux_enabled() && seLinuxContext.size() > 0) { String8 seLinuxContext8(seLinuxContext); security_context_t tmp = NULL; int ret = getfilecon(fullPath.string(), &tmp); Unique_SecurityContext context(tmp); 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() << " (from path " << fullPath.string() << ", context " << seLinuxContext8.string() << ")" << endl; return -EPERM; } } return fd; } }; class MyResultReceiver : public BnResultReceiver class MyResultReceiver : public BnResultReceiver { { public: public: Loading Loading @@ -91,6 +138,6 @@ int main(int argc, char* const argv[]) // TODO: block until a result is returned to MyResultReceiver. // TODO: block until a result is returned to MyResultReceiver. IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, new MyResultReceiver()); new MyShellCallback(), new MyResultReceiver()); return 0; return 0; } }
include/binder/IBinder.h +2 −1 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ class BpBinder; class IInterface; class IInterface; class Parcel; class Parcel; class IResultReceiver; class IResultReceiver; class IShellCallback; /** /** * Base class and low-level protocol for a remotable object. * Base class and low-level protocol for a remotable object. Loading Loading @@ -82,7 +83,7 @@ public: virtual status_t pingBinder() = 0; virtual status_t pingBinder() = 0; virtual status_t dump(int fd, const Vector<String16>& args) = 0; virtual status_t dump(int fd, const Vector<String16>& args) = 0; static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err, static status_t shellCommand(const sp<IBinder>& target, int in, int out, int err, Vector<String16>& args, Vector<String16>& args, const sp<IShellCallback>& callback, const sp<IResultReceiver>& resultReceiver); const sp<IResultReceiver>& resultReceiver); virtual status_t transact( uint32_t code, virtual status_t transact( uint32_t code, Loading
include/binder/IShellCallback.h 0 → 100644 +55 −0 Original line number Original line Diff line number Diff line /* * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // #ifndef ANDROID_ISHELL_CALLBACK_H #define ANDROID_ISHELL_CALLBACK_H #include <binder/IInterface.h> namespace android { // ---------------------------------------------------------------------- class IShellCallback : public IInterface { public: DECLARE_META_INTERFACE(ShellCallback); virtual int openOutputFile(const String16& path, const String16& seLinuxContext) = 0; enum { OP_OPEN_OUTPUT_FILE = IBinder::FIRST_CALL_TRANSACTION }; }; // ---------------------------------------------------------------------- class BnShellCallback : public BnInterface<IShellCallback> { public: virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0); }; // ---------------------------------------------------------------------- }; // namespace android #endif // ANDROID_ISHELL_CALLBACK_H
include/binder/Parcel.h +11 −2 Original line number Original line Diff line number Diff line Loading @@ -188,6 +188,11 @@ public: // will be closed once the parcel is destroyed. // will be closed once the parcel is destroyed. status_t writeDupFileDescriptor(int fd); status_t writeDupFileDescriptor(int fd); // Place a Java "parcel file descriptor" into the parcel. The given fd must remain // valid for the lifetime of the parcel. // The Parcel does not take ownership of the given fd unless you ask it to. status_t writeParcelFileDescriptor(int fd, bool takeOwnership = false); // Place a file descriptor into the parcel. This will not affect the // Place a file descriptor into the parcel. This will not affect the // semantics of the smart file descriptor. A new descriptor will be // semantics of the smart file descriptor. A new descriptor will be // created, and will be closed when the parcel is destroyed. // created, and will be closed when the parcel is destroyed. Loading Loading @@ -334,6 +339,10 @@ public: // in the parcel, which you do not own -- use dup() to get your own copy. // in the parcel, which you do not own -- use dup() to get your own copy. int readFileDescriptor() const; int readFileDescriptor() const; // Retrieve a Java "parcel file descriptor" from the parcel. This returns the raw fd // in the parcel, which you do not own -- use dup() to get your own copy. int readParcelFileDescriptor() const; // Retrieve a smart file descriptor from the parcel. // Retrieve a smart file descriptor from the parcel. status_t readUniqueFileDescriptor( status_t readUniqueFileDescriptor( base::unique_fd* val) const; base::unique_fd* val) const; Loading