54 lines
2.1 KiB
C
54 lines
2.1 KiB
C
// SPDX-License-Identifier: MPL-2.0
|
|
// Fixed-command local broker; camera access is confined to Android UID 1006.
|
|
#define _GNU_SOURCE
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/un.h>
|
|
#include <sys/wait.h>
|
|
#include <grp.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#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;
|
|
}
|