* Fix counting message lines in wall. Patch from Petr Lautrbach.

* Fix bad printf conversion specifier in wall. Patch from Sébastien Luttringer.
* Add patches from Openwall project. Thanks goes to Solar Designer.
This commit is contained in:
Werner Fink 2011-03-15 13:16:55 +00:00
parent 1ef9e7736c
commit d9122565a0
7 changed files with 110 additions and 33 deletions

View File

@ -1,6 +1,9 @@
sysvinit (2.89dsf) UNRELEASED; urgency=low sysvinit (2.89dsf) UNRELEASED; urgency=low
[ Werner Fink ] [ Werner Fink ]
* Fix counting message lines in wall. Patch from Petr Lautrbach.
* Fix bad printf conversion specifier in wall. Patch from Sébastien Luttringer.
* Add patches from Openwall project. Thanks goes to Solar Designer.
* Add code to detect the system consoles with the help of the * Add code to detect the system consoles with the help of the
new /proc/consoles files of linux kernel 2.6.38+ new /proc/consoles files of linux kernel 2.6.38+
* Try to make utmpdump IPv6 valid, change based on suggestion from * Try to make utmpdump IPv6 valid, change based on suggestion from

View File

@ -108,7 +108,7 @@ void handler(int sig)
/* /*
* Scan /dev and find the device name. * Scan /dev and find the device name.
*/ */
static int findtty(char *res, const char *startdir, int rlen, dev_t dev) static int findtty(char *res, const char *startdir, size_t rlen, dev_t dev)
{ {
DIR *dir; DIR *dir;
struct dirent *ent; struct dirent *ent;
@ -145,7 +145,7 @@ static int findtty(char *res, const char *startdir, int rlen, dev_t dev)
if (!S_ISCHR(st.st_mode)) if (!S_ISCHR(st.st_mode))
continue; continue;
if (st.st_rdev == dev) { if (st.st_rdev == dev) {
if ( (int) (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) { if ( (strlen(ent->d_name) + strlen(startdir) + 1) >= rlen) {
fprintf(stderr, "bootlogd: console device name too long\n"); fprintf(stderr, "bootlogd: console device name too long\n");
closedir(dir); closedir(dir);
chdir(olddir); chdir(olddir);
@ -208,7 +208,7 @@ int findpty(int *master, int *slave, char *name)
* See if a console taken from the kernel command line maps * See if a console taken from the kernel command line maps
* to a character device we know about, and if we can open it. * to a character device we know about, and if we can open it.
*/ */
int isconsole(char *s, char *res, int rlen) int isconsole(char *s, char *res, size_t rlen)
{ {
struct consdev *c; struct consdev *c;
int l, sl, i, fd; int l, sl, i, fd;
@ -238,7 +238,7 @@ int isconsole(char *s, char *res, int rlen)
* Find out the _real_ console. Assume that stdin is connected to * Find out the _real_ console. Assume that stdin is connected to
* the console device (/dev/console). * the console device (/dev/console).
*/ */
int consolename(char *res, int rlen) int consolename(char *res, size_t rlen)
{ {
#ifdef TIOCGDEV #ifdef TIOCGDEV
unsigned int kdev; unsigned int kdev;

View File

@ -239,7 +239,10 @@ int main(int argc, char **argv)
exit(1); exit(1);
} }
(void)chdir("/"); if (chdir("/")) {
fprintf(stderr, "%s: chdir(/): %m\n", progname);
exit(1);
}
if (!do_hard && !do_nothing) { if (!do_hard && !do_nothing) {
/* /*

View File

@ -89,6 +89,7 @@
/* Set a signal handler. */ /* Set a signal handler. */
#define SETSIG(sa, sig, fun, flags) \ #define SETSIG(sa, sig, fun, flags) \
do { \ do { \
memset(&sa, 0, sizeof(sa)); \
sa.sa_handler = fun; \ sa.sa_handler = fun; \
sa.sa_flags = flags; \ sa.sa_flags = flags; \
sigemptyset(&sa.sa_mask); \ sigemptyset(&sa.sa_mask); \
@ -809,6 +810,24 @@ void console_stty(void)
(void) close(fd); (void) close(fd);
} }
static ssize_t
safe_write(int fd, const char *buffer, size_t count)
{
ssize_t offset = 0;
while (count > 0) {
ssize_t block = write(fd, &buffer[offset], count);
if (block < 0 && errno == EINTR)
continue;
if (block <= 0)
return offset ? offset : block;
offset += block;
count -= block;
}
return offset;
}
/* /*
* Print to the system console * Print to the system console
*/ */
@ -817,7 +836,7 @@ void print(char *s)
int fd; int fd;
if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) { if ((fd = console_open(O_WRONLY|O_NOCTTY|O_NDELAY)) >= 0) {
write(fd, s, strlen(s)); safe_write(fd, s, strlen(s));
close(fd); close(fd);
} }
} }
@ -1669,9 +1688,9 @@ int ask_runlevel(void)
if (fd < 0) return('S'); if (fd < 0) return('S');
while(!strchr("0123456789S", lvl)) { while(!strchr("0123456789S", lvl)) {
write(fd, prompt, sizeof(prompt) - 1); safe_write(fd, prompt, sizeof(prompt) - 1);
buf[0] = 0; if (read(fd, buf, sizeof(buf)) <= 0)
read(fd, buf, sizeof(buf)); buf[0] = 0;
if (buf[0] != 0 && (buf[1] == '\r' || buf[1] == '\n')) if (buf[0] != 0 && (buf[1] == '\r' || buf[1] == '\n'))
lvl = buf[0]; lvl = buf[0];
if (islower(lvl)) lvl = toupper(lvl); if (islower(lvl)) lvl = toupper(lvl);
@ -1956,12 +1975,15 @@ int make_pipe(int fd)
{ {
int fds[2]; int fds[2];
pipe(fds); if (pipe(fds)) {
initlog(L_VB, "pipe: %m");
return -1;
}
dup2(fds[0], fd); dup2(fds[0], fd);
close(fds[0]); close(fds[0]);
fcntl(fds[1], F_SETFD, 1); fcntl(fds[1], F_SETFD, 1);
fcntl(fd, F_SETFD, 0); fcntl(fd, F_SETFD, 0);
write(fds[1], Signature, 8); safe_write(fds[1], Signature, 8);
return fds[1]; return fds[1];
} }
@ -1991,7 +2013,10 @@ void re_exec(void)
/* /*
* construct a pipe fd --> STATE_PIPE and write a signature * construct a pipe fd --> STATE_PIPE and write a signature
*/ */
fd = make_pipe(STATE_PIPE); if ((fd = make_pipe(STATE_PIPE)) < 0) {
sigprocmask(SIG_SETMASK, &oldset, NULL);
initlog(L_CO, "Attempt to re-exec failed");
}
/* /*
* It's a backup day today, so I'm pissed off. Being a BOFH, however, * It's a backup day today, so I'm pissed off. Being a BOFH, however,
@ -2033,10 +2058,10 @@ void re_exec(void)
* We shouldn't be here, something failed. * We shouldn't be here, something failed.
* Bitch, close the state pipe, unblock signals and return. * Bitch, close the state pipe, unblock signals and return.
*/ */
init_freeenv(env);
close(fd); close(fd);
close(STATE_PIPE); close(STATE_PIPE);
sigprocmask(SIG_SETMASK, &oldset, NULL); sigprocmask(SIG_SETMASK, &oldset, NULL);
init_freeenv(env);
initlog(L_CO, "Attempt to re-exec failed"); initlog(L_CO, "Attempt to re-exec failed");
} }
@ -2406,8 +2431,8 @@ void process_signals()
/* See _what_ kind of SIGPWR this is. */ /* See _what_ kind of SIGPWR this is. */
pwrstat = 0; pwrstat = 0;
if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) { if ((fd = open(PWRSTAT, O_RDONLY)) >= 0) {
c = 0; if (read(fd, &c, 1) != 1)
read(fd, &c, 1); c = 0;
pwrstat = c; pwrstat = c;
close(fd); close(fd);
unlink(PWRSTAT); unlink(PWRSTAT);
@ -2415,8 +2440,8 @@ void process_signals()
/* Path changed 2010-03-20. Look for the old path for a while. */ /* Path changed 2010-03-20. Look for the old path for a while. */
initlog(L_VB, "warning: found obsolete path %s, use %s instead", initlog(L_VB, "warning: found obsolete path %s, use %s instead",
PWRSTAT_OLD, PWRSTAT); PWRSTAT_OLD, PWRSTAT);
c = 0; if (read(fd, &c, 1) != 1)
read(fd, &c, 1); c = 0;
pwrstat = c; pwrstat = c;
close(fd); close(fd);
unlink(PWRSTAT_OLD); unlink(PWRSTAT_OLD);
@ -2533,7 +2558,7 @@ void init_main(void)
while((rc = wait(&st)) != f) while((rc = wait(&st)) != f)
if (rc < 0 && errno == ECHILD) if (rc < 0 && errno == ECHILD)
break; break;
write(1, killmsg, sizeof(killmsg) - 1); safe_write(1, killmsg, sizeof(killmsg) - 1);
while(1) pause(); while(1) pause();
} }
#endif #endif
@ -2808,7 +2833,7 @@ int main(int argc, char **argv)
p = argv[0]; p = argv[0];
/* Common umask */ /* Common umask */
umask(022); umask(umask(077) | 022);
/* Quick check */ /* Quick check */
if (geteuid() != 0) { if (geteuid() != 0) {

View File

@ -75,6 +75,7 @@ char *Version = "@(#)killall5 2.86 31-Jul-2004 miquels@cistron.nl";
/* Info about a process. */ /* Info about a process. */
typedef struct proc { typedef struct proc {
char *pathname; /* full path to executable */
char *argv0; /* Name as found out from argv[0] */ char *argv0; /* Name as found out from argv[0] */
char *argv0base; /* `basename argv[1]` */ char *argv0base; /* `basename argv[1]` */
char *argv1; /* Name as found out from argv[1] */ char *argv1; /* Name as found out from argv[1] */
@ -206,8 +207,8 @@ int mount_proc(void)
} }
if (pid == 0) { if (pid == 0) {
/* Try a few mount binaries. */ /* Try a few mount binaries. */
execv("/sbin/mount", args);
execv("/bin/mount", args); execv("/bin/mount", args);
execv("/sbin/mount", args);
/* Okay, I give up. */ /* Okay, I give up. */
nsyslog(LOG_ERR, "cannot execute mount"); nsyslog(LOG_ERR, "cannot execute mount");
@ -486,6 +487,7 @@ int readproc(int do_stat)
if (p->argv0) free(p->argv0); if (p->argv0) free(p->argv0);
if (p->argv1) free(p->argv1); if (p->argv1) free(p->argv1);
if (p->statname) free(p->statname); if (p->statname) free(p->statname);
free(p->pathname);
free(p); free(p);
} }
plist = NULL; plist = NULL;
@ -505,13 +507,21 @@ int readproc(int do_stat)
/* Read SID & statname from it. */ /* Read SID & statname from it. */
if ((fp = fopen(path, "r")) != NULL) { if ((fp = fopen(path, "r")) != NULL) {
buf[0] = 0; if (!fgets(buf, sizeof(buf), fp))
fgets(buf, sizeof(buf), fp); buf[0] = '\0';
if (buf[0] == '\0') {
nsyslog(LOG_ERR,
"can't read from %s\n", path);
fclose(fp);
free(p);
continue;
}
/* See if name starts with '(' */ /* See if name starts with '(' */
s = buf; s = buf;
while (*s != ' ') s++; while (*s && *s != ' ') s++;
s++; if (*s) s++;
if (*s == '(') { if (*s == '(') {
/* Read program name. */ /* Read program name. */
q = strrchr(buf, ')'); q = strrchr(buf, ')');
@ -520,18 +530,20 @@ int readproc(int do_stat)
nsyslog(LOG_ERR, nsyslog(LOG_ERR,
"can't get program name from /proc/%s\n", "can't get program name from /proc/%s\n",
path); path);
fclose(fp);
if (p->argv0) free(p->argv0); if (p->argv0) free(p->argv0);
if (p->argv1) free(p->argv1); if (p->argv1) free(p->argv1);
if (p->statname) free(p->statname); if (p->statname) free(p->statname);
free(p->pathname);
free(p); free(p);
continue; continue;
} }
s++; s++;
} else { } else {
q = s; q = s;
while (*q != ' ') q++; while (*q && *q != ' ') q++;
} }
*q++ = 0; if (*q) *q++ = 0;
while (*q == ' ') q++; while (*q == ' ') q++;
p->statname = (char *)xmalloc(strlen(s)+1); p->statname = (char *)xmalloc(strlen(s)+1);
strcpy(p->statname, s); strcpy(p->statname, s);
@ -546,9 +558,11 @@ int readproc(int do_stat)
p->sid = 0; p->sid = 0;
nsyslog(LOG_ERR, "can't read sid from %s\n", nsyslog(LOG_ERR, "can't read sid from %s\n",
path); path);
fclose(fp);
if (p->argv0) free(p->argv0); if (p->argv0) free(p->argv0);
if (p->argv1) free(p->argv1); if (p->argv1) free(p->argv1);
if (p->statname) free(p->statname); if (p->statname) free(p->statname);
free(p->pathname);
free(p); free(p);
continue; continue;
} }
@ -560,6 +574,7 @@ int readproc(int do_stat)
if (p->argv0) free(p->argv0); if (p->argv0) free(p->argv0);
if (p->argv1) free(p->argv1); if (p->argv1) free(p->argv1);
if (p->statname) free(p->statname); if (p->statname) free(p->statname);
free(p->pathname);
free(p); free(p);
continue; continue;
} }
@ -607,6 +622,7 @@ int readproc(int do_stat)
if (p->argv0) free(p->argv0); if (p->argv0) free(p->argv0);
if (p->argv1) free(p->argv1); if (p->argv1) free(p->argv1);
if (p->statname) free(p->statname); if (p->statname) free(p->statname);
free(p->pathname);
free(p); free(p);
continue; continue;
} }
@ -623,6 +639,16 @@ int readproc(int do_stat)
case DO_STAT: case DO_STAT:
if (stat(path, &st) != 0) if (stat(path, &st) != 0)
break; break;
else {
char buf[PATH_MAX];
f = readlink(path, buf, sizeof buf);
if (f > 0) {
p->pathname = (char *)xmalloc(f + 1);
memcpy(p->pathname, buf, f);
p->pathname[f] = '\0';
}
}
p->dev = st.st_dev; p->dev = st.st_dev;
p->ino = st.st_ino; p->ino = st.st_ino;
default: default:
@ -761,6 +787,20 @@ PIDQ_HEAD *pidof(char *prog)
/* If we didn't find a match based on dev/ino, try the name. */ /* If we didn't find a match based on dev/ino, try the name. */
if (!foundone) for (p = plist; p; p = p->next) { if (!foundone) for (p = plist; p; p = p->next) {
if (prog[0] == '/') {
if (!p->pathname)
continue;
if (strcmp(prog, p->pathname)) {
int len = strlen(prog);
if (strncmp(prog, p->pathname, len))
continue;
if (strcmp(" (deleted)", p->pathname + len))
continue;
}
add_pid_to_q(q, p);
continue;
}
ok = 0; ok = 0;
/* matching nonmatching /* matching nonmatching

View File

@ -154,7 +154,7 @@ int init_setenv(char *name, char *value)
struct init_request request; struct init_request request;
struct sigaction sa; struct sigaction sa;
int fd; int fd;
int nl, vl; size_t nl, vl;
memset(&request, 0, sizeof(request)); memset(&request, 0, sizeof(request));
request.magic = INIT_MAGIC; request.magic = INIT_MAGIC;
@ -286,7 +286,8 @@ int spawn(int noerr, char *prog, ...)
argv[i] = NULL; argv[i] = NULL;
va_end(ap); va_end(ap);
chdir("/"); if (chdir("/"))
exit(1);
environ = clean_env; environ = clean_env;
execvp(argv[0], argv); execvp(argv[0], argv);
@ -627,7 +628,8 @@ int main(int argc, char **argv)
/* Read pid of running shutdown from a file */ /* Read pid of running shutdown from a file */
if ((fp = fopen(SDPID, "r")) != NULL) { if ((fp = fopen(SDPID, "r")) != NULL) {
fscanf(fp, "%d", &pid); if (fscanf(fp, "%d", &pid) != 1)
pid = 0;
fclose(fp); fclose(fp);
} }
@ -692,6 +694,12 @@ int main(int argc, char **argv)
break; break;
} }
/* Go to the root directory */
if (chdir("/")) {
fprintf(stderr, "shutdown: chdir(/): %m\n");
exit(1);
}
/* Create a new PID file. */ /* Create a new PID file. */
unlink(SDPID); unlink(SDPID);
umask(022); umask(022);
@ -715,8 +723,6 @@ int main(int argc, char **argv)
sa.sa_handler = stopit; sa.sa_handler = stopit;
sigaction(SIGINT, &sa, NULL); sigaction(SIGINT, &sa, NULL);
/* Go to the root directory */
chdir("/");
if (fastboot) close(open(FASTBOOT, O_CREAT | O_RDWR, 0644)); if (fastboot) close(open(FASTBOOT, O_CREAT | O_RDWR, 0644));
if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644)); if (forcefsck) close(open(FORCEFSCK, O_CREAT | O_RDWR, 0644));

View File

@ -102,14 +102,14 @@ int main(int argc, char **argv)
i = 0; i = 0;
for (p = buf; *p; p++) { for (p = buf; *p; p++) {
if (*p == '\n' && i++ > MAXLINES) { if (*p == '\n' && ++i >= MAXLINES) {
*++p = 0; *++p = 0;
break; break;
} }
} }
openlog("wall", LOG_PID, LOG_USER); openlog("wall", LOG_PID, LOG_USER);
syslog(LOG_INFO, "wall: user %s broadcasted %d lines (%d chars)", syslog(LOG_INFO, "wall: user %s broadcasted %d lines (%zu chars)",
whoami, i, strlen(buf)); whoami, i, strlen(buf));
closelog(); closelog();