init: cannot execve('/system/bin/custom.sh'): Permission denied
As evident from init source code:

...
static bool ExpandArgsAndExecv(const std::vector&lt;std::string&gt;&amp; args) {
    ...
    return execv(c_strings[0], c_strings.data()) == 0;
}
...
        if (!ExpandArgsAndExecv(args_)) {
            PLOG(ERROR) &lt;&lt; "cannot execve('" &lt;&lt; args_[0] &lt;&lt; "')";
        }


For whatever reason if init fails to execute the script custom.sh (i.e. syscall execve returns non-zero exit code), you will get cannot execve error. Permission denied (EACCES) is returned by execve in multiple situations e.g. unable to read file path, no +x permission on binary or filesystem mounted with noexec. Inability to read|open|execute script or make context transition is returned as EACCES.

Also cannot execve is logged by init but avc: denied is logged by SELinux subsystem through audit subsystem or kernel logging. You should get both errors in dmesg or logcat -b events or logcat -b kernel. If you don't, may be there is a dontaudit rule defined for source or target or both contexts.


  Please suggest what is happening here and how can I fix it?


As explained in my answer to your previous question: How to run an Android init service with superuser SELinux context? define SELinux rules to allow init read / execute custom.sh script and make transition to u:r:su:s0.