commit df48be20758eca03667a8d9268e5812e3f2b0229
parent 85d8345b2606a7670d65f133d9fe4e677d8c8b76
Author: leitner <leitner>
Date: Tue, 24 May 2022 09:47:06 +0000
modernize codebase a bit, fix bug when params didn't end in newline
Diffstat:
8 files changed, 103 insertions(+), 37 deletions(-)
diff --git a/Makefile b/Makefile
@@ -7,7 +7,7 @@ PIE=
CFLAGS=-Wall -W -pipe -fomit-frame-pointer -Os $(PIE)
CROSS=
#CROSS=arm-linux-
-LDFLAGS=-s
+LDFLAGS=-s $(PIE)
MANDIR=/usr/man
path = $(subst :, ,$(PATH))
@@ -50,7 +50,7 @@ endif
minit: minit.o split.o openreadclose.o opendevconsole.o
msvc: msvc.o
ftrigger: ftrigger.o
-minit-update: minit-update.o split.o openreadclose.o
+minit-update: minit-update.o
serdo: serdo.o
waitinterface: waitinterface.o
waitport: waitport.o
diff --git a/ftrigger.c b/ftrigger.c
@@ -112,7 +112,10 @@ again:
continue;
case 1: break;
};
- read(in,buf,sizeof(buf));
+ if (read(in,buf,sizeof(buf)) < (ssize_t)sizeof(*ie)) {
+ buffer_putmflush(buffer_2,"error reading inotify notification: ",strerror(errno),"\n");
+ exit(111);
+ }
#if 0
buffer_puts(buffer_1,"got event for wd ");
@@ -212,8 +215,7 @@ goodevent:
if (v)
buffer_putmflush(buffer_1,"file \"",root[i].filename,"\" changed, running command \"",root[i].command,"\"\n");
if (vfork()==0) {
- system(root[i].command);
- exit(0);
+ exit(system(root[i].command));
}
}
}
diff --git a/minit-update.c b/minit-update.c
@@ -25,9 +25,6 @@ static char buf[BUFLEN+1];
static unsigned int verbose;
static int do_update;
-int openreadclose(char *fn, char **buf, unsigned long *len);
-char **split(char *buf,int c,int *len,int plus,int ofs);
-
void feed_struct_to_minit(struct process *data);
ssize_t read_outfd(void *buf, size_t count);
diff --git a/minit.c b/minit.c
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <alloca.h>
#include <sys/reboot.h>
+#include <write12.h>
#include <libowfat/fmt.h>
#include <libowfat/str.h>
@@ -80,8 +81,8 @@ static int doupdate;
static int i_am_init;
-extern int openreadclose(char *fn, char **buf, unsigned long *len);
-extern char **split(char *buf,int c,int *len,int plus,int ofs);
+extern int openreadclose(char *fn, char **buf, size_t *len);
+extern char **split(char *buf,int c,size_t* len,size_t plus,size_t ofs);
extern char **environ;
@@ -223,10 +224,10 @@ pid_t forkandexec(int pause,int service) {
int count=0;
pid_t p;
int fd;
- unsigned long len;
+ size_t len;
int islink;
char *s=0;
- int argc;
+ size_t argc;
char *argv0=0;
again:
switch (p=fork()) {
@@ -239,10 +240,26 @@ again:
if (i_am_init) {
ioctl(0, TIOCNOTTY, 0);
- setsid();
+ if (setsid() == -1) {
+ __write2("setsid failed unexpectedly.\n");
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
opendevconsole();
/* ioctl(0, TIOCSCTTY, 1); */
- tcsetpgrp(0, getpgrp());
+ int r = tcsetpgrp(0, getpgrp());
+ if (r == -1 && errno!=ENOTTY) { // will get this error for log services
+ __write2("tcsetpgrp failed unexpectedly: ");
+ switch (errno) {
+ case EBADF: __write2("EBADF\n"); break;
+ case EINVAL: __write2("EINVAL\n"); break;
+// case ENOTTY: __write2("ENOTTY\n"); break;
+ case EPERM: __write2("EPERM\n"); break;
+ default: __write2("unhandled\n");
+ }
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
}
if (pause) {
@@ -252,12 +269,19 @@ again:
nanosleep(&req,0);
}
if ((fd=open("in",O_RDONLY))!=-1) {
- dup2(fd,0);
+ if (dup2(fd,0) != 0) {
+ __write2("dup2 failed unexpectedly.\n");
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
fcntl(0,F_SETFD,0);
}
if ((fd=open("out",O_WRONLY))!=-1) {
- dup2(fd,1);
- dup2(fd,2);
+ if (dup2(fd,1) != 1 || dup2(fd,2) != 2) {
+ __write2("dup2 failed unexpectedly.\n");
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
fcntl(1,F_SETFD,0);
fcntl(2,F_SETFD,0);
}
@@ -271,7 +295,8 @@ again:
}
if (!openreadclose("params",&s,&len)) {
argv=split(s,'\n',&argc,2,1);
- if (argv[argc-1]) argv[argc-1]=0; else argv[argc]=0;
+ if (argc && argv[argc-1][0]==0) --argc; // if params ended on newline, don't pass empty last arg
+ argv[argc]=0;
} else {
argv=(char**)alloca(2*sizeof(char*));
argv[1]=0;
@@ -314,12 +339,19 @@ again:
argv0=c;
}
if (root[service].__stdin != 0) {
- dup2(root[service].__stdin,0);
+ if (dup2(root[service].__stdin,0) != 0) {
+ __write2("dup2 failed unexpectedly.\n");
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
fcntl(0,F_SETFD,0);
}
if (root[service].__stdout != 1) {
- dup2(root[service].__stdout,1);
- dup2(root[service].__stdout,2);
+ if (dup2(root[service].__stdout,1) != 1 || dup2(root[service].__stdout,2) != 2) {
+ __write2("dup2 failed unexpectedly.\n");
+ // This should never fail. init is run as root.
+ // If it does fail, don't exit for fear of bricking the system
+ }
fcntl(1,F_SETFD,0);
fcntl(2,F_SETFD,0);
}
@@ -380,7 +412,7 @@ int startservice(int service,int pause,int father) {
// Need to free(s) independent of openreadclose return value
if (!openreadclose("depends",&s,&len)) {
char **deps=0;
- int depc,i;
+ size_t depc,i;
deps=split(s,'\n',&depc,0,0);
for (i=0; i<depc; i++) {
int Service,blacklisted,j;
@@ -605,7 +637,10 @@ error:
write(outfd,"1",1);
if (1==poll(&pfd,nfds,5000)) {
struct process tmp;
- read(infd,&tmp,sizeof tmp);
+ if (read(infd,&tmp,sizeof tmp) != sizeof(tmp)) {
+ __write2("update failed, struct size mismatch.\n");
+ goto ok;
+ }
tmp.name=strdup(buf+1);
addprocess(&tmp);
}
diff --git a/opendevconsole.c b/opendevconsole.c
@@ -1,12 +1,17 @@
#include <fcntl.h>
#include <unistd.h>
+#include <write12.h>
+#include <stdlib.h>
void opendevconsole() {
int fd;
if ((fd=open("/dev/console",O_RDWR|O_NOCTTY))>=0) {
- dup2(fd,0);
- dup2(fd,1);
- dup2(fd,2);
+ if (dup2(fd,0) != 0 ||
+ dup2(fd,1) != 1 ||
+ dup2(fd,2) != 2) {
+ __write2("dup2 failed unexpectedly.\n");
+ exit(111);
+ }
if (fd>2) close(fd);
}
}
diff --git a/openreadclose.c b/openreadclose.c
@@ -1,23 +1,28 @@
#ifndef EMBEDDED
+#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#endif
-int openreadclose(char *fn, char **buf, unsigned long *len) {
+int openreadclose(char *fn, char **buf, size_t *len) {
int fd=open(fn,O_RDONLY);
if (fd<0) return -1;
if (!*buf) {
- *len=lseek(fd,0,SEEK_END);
- lseek(fd,0,SEEK_SET);
+ off_t o = lseek(fd, 0, SEEK_END);
+ if (o < 0 || o > 0x7fffffff) goto error; // impose sanity limits
+ *len = o;
*buf=(char*)malloc(*len+1);
if (!*buf) {
+error:
close(fd);
return -1;
}
}
- *len=read(fd,*buf,*len);
- if (*len != (unsigned long)-1)
+ *len=pread(fd,*buf,*len,0);
+ if (*len == (unsigned long)-1)
+ (*buf)[0]=0;
+ else
(*buf)[*len]=0;
return close(fd);
}
diff --git a/shutdown.c b/shutdown.c
@@ -48,8 +48,8 @@ static inline int __write2(const char*s) { return write(2,s,str_len(s)); }
extern void opendevconsole();
extern char **environ;
-extern int openreadclose(char *fn, char **buf, unsigned long *len);
-extern char **split(char *buf,int c,int *len,int plus,int ofs);
+extern int openreadclose(char *fn, char **buf, size_t *len);
+extern char **split(char *buf,int c,size_t* len,size_t plus,size_t ofs);
extern char *optarg;
void wall(char *buf) {
@@ -93,7 +93,7 @@ int minit_serviceDown(char *service) {
if (!openreadclose("depends", &s, &len)) {
char **deps;
- int depc, i;
+ size_t depc, i;
deps=split(s, '\n', &depc, 0, 0);
for (i=0; i<depc; i++) {
if (deps[i][0] == '#') continue;
@@ -118,7 +118,8 @@ int minit_serviceDown(char *service) {
strncpy(buf+1, service, 1400);
buf[1400]=0;
write(infd, buf, str_len(buf));
- read(outfd, buf, 1500);
+ if (read(outfd, buf, 1500) < 1)
+ __write2("\t(status read failed)");
i=kill(pid, SIGTERM);
if (i == 0) __write2("\t\tdone\n");
else __write2("\t\tfailed\n");
@@ -168,7 +169,10 @@ int main(int argc, char *const argv[]) {
int cfg_sulogin = 0;
#ifdef ALLOW_SUID
- setuid(geteuid());
+ if (setuid(geteuid()) == -1) {
+ __write2("setuid(geteuid()) failed.\n");
+ return 111;
+ }
#endif
if (getuid() != 0) {
__write2("you are not root, go away!\n");
diff --git a/split.c b/split.c
@@ -2,7 +2,7 @@
/* split buf into n strings that are separated by c. return n as *len.
* Allocate plus more slots and leave the first ofs of them alone. */
-char **split(char *buf,int c,int *len,int plus,int ofs) {
+char **split(char *buf,int c,size_t* len,size_t plus,size_t ofs) {
int n=1;
char **v=0;
char **w;
@@ -25,3 +25,21 @@ char **split(char *buf,int c,int *len,int plus,int ofs) {
*len=w-v;
return v;
}
+
+#ifdef UNITTEST
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+
+int main() {
+ char inp[]="foo\nbar\nbaz";
+ size_t len;
+ char** x=split(inp, '\n', &len, 2, 1);
+ assert(len==4 && !strcmp(x[1],"foo") && !strcmp(x[2],"bar") && !strcmp(x[3],"baz") && x[4]==NULL);
+ free(x);
+ char inp2[]="fnord";
+ x=split(inp2, '\n', &len, 2, 1);
+ assert(len==2 && !strcmp(x[1],"fnord") && x[2]==NULL);
+ return 0;
+}
+#endif