Jump to content

Android reboots after use 'prevent protection'


Enyby
 Share

Recommended Posts

  • Administrators

For prevent run protection we use android trick for preload libs.

Unfortunately it is broken in many firmwares.

It is lead to crash zygote before fork. It is cause reboot phone.

It is bug: https://issuetracker.google.com/issues/62179655

https://android.googlesource.com/platform/frameworks/base.git/+/master/core/jni/com_android_internal_os_Zygote.cpp

art/runtime/jni_internal.cc:492] JNI FatalError called: frameworks/base/core/jni/com_android_internal_os_Zygote.cpp:976: Unable to restat file descriptor table.

// Utility routine to fork zygote and specialize the child process.
static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids,
  
  [...]
  
  // If this is the first fork for this zygote, create the open FD table.
  // If it isn't, we just need to check whether the list of open files has
  // changed (and it shouldn't in the normal case).
  std::vector<int> fds_to_ignore;
  FillFileDescriptorVector(env, fdsToIgnore, &fds_to_ignore);
  if (gOpenFdTable == NULL) {
    gOpenFdTable = FileDescriptorTable::Create(fds_to_ignore);
    if (gOpenFdTable == NULL) {
      RuntimeAbort(env, __LINE__, "Unable to construct file descriptor table.");
    }
  } else if (!gOpenFdTable->Restat(fds_to_ignore)) {                        // <------- restat failed
    RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table."); // <------- abort here
  }
              
  pid_t pid = fork();                                                       // <------- fork here so all above in parent process not in child
  if (pid == 0) {

https://android.googlesource.com/platform/frameworks/base/+/master/core/jni/fd_utils.cpp

Unsupported st_mode 4480

bool FileDescriptorTable::Restat(const std::vector<int>& fds_to_ignore) {
  
  [...]
  
  return RestatInternal(open_fds);
}

[...]

bool FileDescriptorTable::RestatInternal(std::set<int>& open_fds) {
  
  [...]
  
        if (!same_file) {
        // The file descriptor refers to a different description. We must
        // update our entry in the table.
        delete it->second;
        it->second = FileDescriptorInfo::CreateFromFd(*element);        // <------ return NULL here
        if (it->second == NULL) {
          // The descriptor no longer no longer refers to a whitelisted file.
          // We flag an error and remove it from the list of files we're
          // tracking.
          error = true;                                                 // <------ set error
          it = open_fd_map_.erase(it);
 
          [...]
          
            if (open_fds.size() > 0) {
    // The zygote has opened new file descriptors since our last inspection.
    // We warn about this condition and add them to our table.
    //
    // TODO(narayan): This will be an error in a future android release.
    // error = true;
    // ALOGW("Zygote opened %zd new file descriptor(s).", open_fds.size());
    // TODO(narayan): This code will be removed in a future android release.
    std::set<int>::const_iterator it;
    for (it = open_fds.begin(); it != open_fds.end(); ++it) {
      const int fd = (*it);
      FileDescriptorInfo* info = FileDescriptorInfo::CreateFromFd(fd);      // <------ return NULL here
      if (info == NULL) {
        // A newly opened file is not on the whitelist. Flag an error and
        // continue.
        error = true;                                                       // <------ set error
                    
[...]
                    
  return !error;                                                            // <------ return error
}
                  
[...]

FileDescriptorInfo* FileDescriptorInfo::CreateFromFd(int fd) {
                    
[...]
                    
  // We only handle whitelisted regular files and character devices. Whitelisted
  // character devices must provide a guarantee of sensible behaviour when
  // reopened.
  //
  // S_ISDIR : Not supported. (We could if we wanted to, but it's unused).
  // S_ISLINK : Not supported.
  // S_ISBLK : Not supported.
  // S_ISFIFO : Not supported. Note that the zygote uses pipes to communicate
  // with the child process across forks but those should have been closed
  // before we got to this point.
  if (!S_ISCHR(f_stat.st_mode) && !S_ISREG(f_stat.st_mode)) {              // <------ f_stat.st_mode == 4480 here
    LOG(ERROR) << "Unsupported st_mode " << f_stat.st_mode;
    return NULL;                                                           // <------ return null
  }

st_mode 4480 is 00010600, so is S_IFIFO | S_IRUSR | S_IWUSR, so is FIFO (pipe maybe) and cause abort.

This code run before fork(), so it run in zygote process.

It is mean crash zygote. If zygote crashed - phone immediately reboot.

 

Look like before run check not all pipes closed.

 

Solution: do not use 'prevent protection' mode in GG. If you used it and phone reboot on any call this app - install and run GG at least 8.43.1.

On start daemon it clear all bad settings.

Link to comment
Share on other sites

  • 1 month later...

Has this issue been solved in current version?

I'm trying to use the tutorial given by NoFear for BlazBlue, but the game keeps crashing all the time I try to make a search, and the GG is not giving the option to reopen the game, unless if I close the game window after it crashes. Then, if I try using the functionality to hide it from the game, the tablet restarts.

I would really appreciate updates on this....

Edited by buiatti
Link to comment
Share on other sites

  • 2 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.