Can't attach child process in release build (Android) - android

I try to fork and then trace my child by calling ptrace(PTRACE_ATTACH, iChildPid, 0, 0) on Android:
- and get success when working with a debug build
- and get failure with a release build (Operation not permitted (1))
Where I'm wrong?

Okay :(
This is an Android feature. If the application is not marked as debuggable (manifest: android:debuggable = false), PTRACE_ATTACH does not works in both directions (parent2child and child2parent). Only root can do this.

According to the source of Android framework, you indeed can enable ptrace-able by yourself in app release build. (Just dont forget to call this function before your fork child process and ptrace parent)
frameworks/base/core/jni/com_android_internal_os_Zygote.cpp
static void EnableDebugger() {
// To let a non-privileged gdbserver attach to this
// process, we must set our dumpable flag.
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) == -1) {
ALOGE("prctl(PR_SET_DUMPABLE) failed");
}
// A non-privileged native debugger should be able to attach to the debuggable app, even if Yama
// is enabled (see kernel/Documentation/security/Yama.txt).
if (prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0) == -1) {
// if Yama is off prctl(PR_SET_PTRACER) returns EINVAL - don't log in this
// case since it's expected behaviour.
if (errno != EINVAL) {
ALOGE("prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY) failed");
}
}
// Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh).
if (!GetBoolProperty("persist.zygote.core_dump", false)) {
// Set the soft limit on core dump size to 0 without changing the hard limit.
rlimit rl;
if (getrlimit(RLIMIT_CORE, &rl) == -1) {
ALOGE("getrlimit(RLIMIT_CORE) failed");
} else {
rl.rlim_cur = 0;
if (setrlimit(RLIMIT_CORE, &rl) == -1) {
ALOGE("setrlimit(RLIMIT_CORE) failed");
}
}
}
}

Related

How to fix ExoPlayer error 'native window cannot handle protected buffers'

I keep getting an error when pausing ExoPlayer and putting my app in the background. The stream contains Widevine protected content and ads that are inserted on the server side.
I suspect this mixture of protected and unprotected content to be causing the error but have no idea where to start. Putting the app in the background and resuming it actually works once during the unprotected preroll ad but fails when trying it a second time in the main content.
SurfaceUtils logs the following message: native window cannot handle protected buffers: the consumer should either be a hardware composer or support hardware protection.
Does someone know what this actually means? Unfortunately I am not too familiar with the inner workings of ExoPlayer.
The code in SurfaceUtils.cpp that returns the error might be helpful here:
// Make sure to check whether either Stagefright or the video decoder
// requested protected buffers.
if (usage & GRALLOC_USAGE_PROTECTED) {
// Check if the ANativeWindow sends images directly to SurfaceFlinger.
int queuesToNativeWindow = 0;
err = nativeWindow->query(
nativeWindow, NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, &queuesToNativeWindow);
if (err != NO_ERROR) {
ALOGE("error authenticating native window: %s (%d)", strerror(-err), -err);
return err;
}
// Check if the consumer end of the ANativeWindow can handle protected content.
int isConsumerProtected = 0;
err = nativeWindow->query(
nativeWindow, NATIVE_WINDOW_CONSUMER_IS_PROTECTED, &isConsumerProtected);
if (err != NO_ERROR) {
ALOGE("error query native window: %s (%d)", strerror(-err), -err);
return err;
}
// Deny queuing into native window if neither condition is satisfied.
if (queuesToNativeWindow != 1 && isConsumerProtected != 1) {
ALOGE("native window cannot handle protected buffers: the consumer should either be a hardware composer or support hardware protection");
return PERMISSION_DENIED;
}
}

Is there a way to disable HWC in AOSP and execute everything in GLES?

In Android 8 and above there are two functionalities to handle graphics. SurfaceFlinger uses GLES for some of the layers to render and pass others to handle by Hardware composer. My question is, Is there a way to make the system use only GLES to render everything So I can use the shader(GLSL) code to manipulate frame buffers properly.
The project files has HWC files everywhere. I am trying to find a way to alter each frame.
In Settings->Developer options->HARDWARE ACCELERATED RENDERING, there is a switch called Disable HW overlays. If you open it, the system will close the HWC and use OpenGLES to render layers. If you want to close it always, you can dive into the code, and find the flag it sets, and then you can set it to the value to disable HWC.
Update 1:
In DevelopmentSettings.java, below code is to send flag to SurfaceFlinger:
private void writeDisableOverlaysOption() {
try {
IBinder flinger = ServiceManager.getService("SurfaceFlinger");
if (flinger != null) {
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
final int disableOverlays = mDisableOverlays.isChecked() ? 1 : 0;
data.writeInt(disableOverlays);
flinger.transact(1008, data, null, 0);
data.recycle();
updateFlingerOptions();
}
} catch (RemoteException ex) {}
}
In SurfaceFlinger.cpp, it will save this flag to mDebugDisableHWC, and uses below code to notify Layer to use OpenGLES to render forcibly:
// build the h/w work list
if (CC_UNLIKELY(mGeometryInvalid)) {
mGeometryInvalid = false;
for (size_t dpy = 0; dpy < mDisplays.size(); dpy++) {
sp<const DisplayDevice> displayDevice(mDisplays[dpy]);
const auto hwcId = displayDevice->getHwcDisplayId();
if (hwcId >= 0) {
const Vector<sp<Layer> >& currentLayers(
displayDevice->getVisibleLayersSortedByZ());
for (size_t i = 0; i < currentLayers.size(); i++) {
const auto& layer = currentLayers[i];
if (!layer->hasHwcLayer(hwcId)) {
if (!layer->createHwcLayer(mHwc.get(), hwcId)) {
layer->forceClientComposition(hwcId);
continue;
}
}
layer->setGeometry(displayDevice, i);
if (mDebugDisableHWC || mDebugRegion) {
layer->forceClientComposition(hwcId);
}
}
}
}
}
Okay, if you want to disable it by code, you can write a method like writeDisableOverlaysOption, and disable switch in Settings to avoid user uses switch to reset the state.

How should GATT_CMD_STARTED (status=134) be interpreted?

I'm working on an android app where I need to communicate with a bluetooth LE device and in the middle of the communication I receive a callback:
onCharacteristicWrite()
...which is expected. But the status of the operation is 134 instead of 0 (=success).
This GATT status constant is not defined in the official API but here is a translation in one of many unofficial lists:
public static final int GATT_CMD_STARTED = 134;
See: https://code.google.com/r/naranjomanuel-opensource-broadcom-ble/source/browse/framework/java/src/com/broadcom/bt/service/gatt/GattConstants.java?r=983950f9b35407446bf082633d70c7655c206d22
The consequence, that I can see, in my app is that I do not get an expected callback to:
onCharacteristicChanged()
Does anybody know what GATT_CMD_STARTED means? Is it an error?
The description of the following function taken from the bludroid sources hint that something is not working correctly in your GATT server.
Commands seem to "queue up" there, as there must be pending requests or value confirmations as hinted in the comment before the if(...) clause.
It might be worth checking what exactly is going on before you do the writeCharacteristic(...) as it seems to not finish correctly or create hiccups in your server.
/*******************************************************************************
**
** Function attp_cl_send_cmd
**
** Description Send a ATT command or enqueue it.
**
** Returns GATT_SUCCESS if command sent
** GATT_CONGESTED if command sent but channel congested
** GATT_CMD_STARTED if command queue up in GATT
** GATT_ERROR if command sending failure
**
*******************************************************************************/
tGATT_STATUS attp_cl_send_cmd(tGATT_TCB *p_tcb, UINT16 clcb_idx, UINT8 cmd_code, BT_HDR *p_cmd)
{
tGATT_STATUS att_ret = GATT_SUCCESS;
if (p_tcb != NULL)
{
cmd_code &= ~GATT_AUTH_SIGN_MASK;
/* no pending request or value confirmation */
if (p_tcb->pending_cl_req == p_tcb->next_slot_inq ||
cmd_code == GATT_HANDLE_VALUE_CONF)
{
att_ret = attp_send_msg_to_l2cap(p_tcb, p_cmd);
if (att_ret == GATT_CONGESTED || att_ret == GATT_SUCCESS)
{
/* do not enq cmd if handle value confirmation or set request */
if (cmd_code != GATT_HANDLE_VALUE_CONF && cmd_code != GATT_CMD_WRITE)
{
gatt_start_rsp_timer (clcb_idx);
gatt_cmd_enq(p_tcb, clcb_idx, FALSE, cmd_code, NULL);
}
}
else
att_ret = GATT_INTERNAL_ERROR;
}
else
{
att_ret = GATT_CMD_STARTED;
gatt_cmd_enq(p_tcb, clcb_idx, TRUE, cmd_code, p_cmd);
}
}
else
att_ret = GATT_ERROR;
return att_ret;
}
Starts at line 469 in android sources.
The native GATT error and statuscodes can be found here.

Accessing Android properties in C code

I've been trying to figure this out for a while. I'm trying to store a value in a custom property variable using property_set and retrieve it in another module using property_get but it's just not working. I made some changes to the property_service.c file to add permissions to the custom property but it's still not reading what's stored and there are no errors either. Are there any other files that needs to be changed to get this working?
property_service.c looks like this. I added my custom property (dm) at the end.
/* White list of permissions for setting property services. */
struct {
const char *prefix;
unsigned int uid;
unsigned int gid;
} property_perms[] = {
{ "net.rmnet0.", AID_RADIO, 0 },
...
{ "service.adb.tcp.port", AID_SHELL, 0 },
{ "persist.sys.", AID_SYSTEM, 0 },
{ "persist.service.", AID_SYSTEM, 0 },
{ "persist.security.", AID_SYSTEM, 0 },
{ "dm.", AID_SYSTEM, 0},
{ NULL, 0, 0 }
};
It can be permission problem, in general case user/group permissions (are you running as root?).
Second thing that can cause permissions denial is SELinux rules - grep logcat and dmesg logs for "avc" denials. There should be some messages about your efforts in this case. Of course this case is possible if SELinux (e.g. SEAndroid) is running in enforced mode.
Otherwise you should provide more details, like errno, retval and so on

Dropbox API Android listing contents of contents from directory

I would like to list the content of the content of a directory from Dropbox using its Android API.
I tried using dirEntry.contents() in a for loop, like this:
Entry rootDirEnt = mApi.metadata(mPath, 1000, null,
true, null);
if (!rootDirEnt.isDir || rootDirEnt.contents == null) {
// It's not a directory, or there's nothing in it
mErrorMsg = "No files available in Dropbox";
return false;
}
for (Entry childDirEnt : rootDirEnt.contents) {
// check if it still exists
if (childDirEnt.isDir && !childDirEnt.isDeleted
&& childDirEnt.contents != null) {
// childDirEnt contents is already null, even though there are files inside this directory
for (Entry fileEnt : childDirEnt.contents) {
// do smth with file
if (isCancelled()) {
return false;
} else {
publishProgress();
}
}
}
}
So I thought of usign mApi.metadata() again with the new path which works, but my question is: Can't I do it without calling medata() for every directory inside root dir ? (maybe using the contents call or smth.. )
You can call metadata again on each directory you find. Generally, Dropbox discourages calling metadata recursively like that unless driven by user action. See https://www.dropbox.com/developers/core/bestpractices.
You might instead use the delta API. The first time you call that, it will return a full list of all the content your app has access to in a user's Dropbox.

Categories

Resources