// SPDX-License-Identifier: MPL-2.0 // Fixed-command local broker; camera access is confined to Android UID 1006. #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define SOCKET_DIR "/data/local/vulpes-beatles/camera-ipc" #define SOCKET_PATH SOCKET_DIR "/camera.sock" #define WORKER "/data/local/tmp/vulpes-beatles-camera-worker" static volatile sig_atomic_t stopping; static void stop_now(int signal_number) { (void)signal_number; stopping = 1; } int main(void) { if (setpgid(0,0) && errno != EACCES) return 1; struct sigaction action = {0}; action.sa_handler = stop_now; sigemptyset(&action.sa_mask); sigaction(SIGTERM,&action,NULL); sigaction(SIGINT,&action,NULL); umask(0); if (mkdir(SOCKET_DIR,0777) && errno != EEXIST) return 2; chmod(SOCKET_DIR,0777); unlink(SOCKET_PATH); int server=socket(AF_UNIX,SOCK_STREAM,0); if(server<0) return 3; struct sockaddr_un address={0}; address.sun_family=AF_UNIX; strncpy(address.sun_path,SOCKET_PATH,sizeof(address.sun_path)-1); if(bind(server,(struct sockaddr *)&address,sizeof(address)) || chmod(SOCKET_PATH,0666) || listen(server,2)) return 4; printf("camera broker ready uid=%d socket=%s\n",getuid(),SOCKET_PATH); fflush(stdout); while(!stopping) { int client=accept(server,NULL,NULL); if(client<0) { if(errno==EINTR) continue; break; } pid_t child=fork(); if(child==0) { close(server); fprintf(stderr,"camera worker accepted pid=%d\n",getpid()); fflush(stderr); gid_t groups[]={1006}; if(setgroups(1,groups) || setgid(1006) || setuid(1006)) _exit(120); if(dup2(client,STDIN_FILENO)<0 || dup2(client,STDOUT_FILENO)<0) _exit(121); if(client>STDOUT_FILENO) close(client); setenv("LD_LIBRARY_PATH","/system/lib:/data/local/tmp",1); execl(WORKER,"vulpes-beatles-camera-worker",(char *)NULL); _exit(127); } close(client); while(waitpid(-1,NULL,WNOHANG)>0) {} } close(server); unlink(SOCKET_PATH); return 0; }