Changed the way the "when" variable is used internally in shutdown.c.
It starts as a NULL pointer, then might get set as a pointer to optarg, then it might get set to point to an argv parameter, then it might have a string value copied into it, over-writing the original data. We should not risk over-writing internal variables which might get used for something else (it's rude and security risk). Set up "when" as its own buffer that has data from optargs and/or argv copied into it. Minor code fixes across multiple source files to avoid buffer overflows, or uninitialized strings.
This commit is contained in:
parent
43b5c64126
commit
483dc777d2
@ -21,6 +21,17 @@ sysvinit (2.94) unreleased; urgency=low
|
|||||||
* Added logsave.c and logsave.8 manual page from e2fsprogs to make
|
* Added logsave.c and logsave.8 manual page from e2fsprogs to make
|
||||||
sure logsave is available to initscripts.
|
sure logsave is available to initscripts.
|
||||||
* Updated src/Makefile to make sure bootlogd compiles with Clang.
|
* Updated src/Makefile to make sure bootlogd compiles with Clang.
|
||||||
|
* Use defined constants for password length in sulogin. Makes
|
||||||
|
it easier to update/patch later.
|
||||||
|
* Minor code fixes across multiple source files to avoid buffer
|
||||||
|
overflows, or uninitialized strings.
|
||||||
|
* Changed the way the "when" variable is used internally in shutdown.c.
|
||||||
|
It starts as a NULL pointer, then might get set as a pointer to optarg,
|
||||||
|
then it might get set to point to an argv parameter, then it might have
|
||||||
|
a string value copied into it, over-writing the original data. We should
|
||||||
|
not risk over-writing internal variables which might get used for something
|
||||||
|
else (it's rude and security risk). Set up "when" as its own buffer
|
||||||
|
that has data from optargs and/or argv copied into it.
|
||||||
|
|
||||||
|
|
||||||
sysvinit (2.93) released; urgency=low
|
sysvinit (2.93) released; urgency=low
|
||||||
|
@ -433,7 +433,11 @@ int check4nfs(const char * path, char * real)
|
|||||||
|
|
||||||
} while (1);
|
} while (1);
|
||||||
|
|
||||||
if (real) strcpy(real, curr);
|
if (real) /* real is defined elsewhere as being PATH_MAX + 1 */
|
||||||
|
{
|
||||||
|
memset(real, '\0', PATH_MAX + 1);
|
||||||
|
strncpy(real, curr, PATH_MAX);
|
||||||
|
}
|
||||||
|
|
||||||
if (errno == EINVAL) {
|
if (errno == EINVAL) {
|
||||||
const size_t nlen = strlen(curr);
|
const size_t nlen = strlen(curr);
|
||||||
|
17
src/last.c
17
src/last.c
@ -48,6 +48,10 @@
|
|||||||
# define SHUTDOWN_TIME 254
|
# define SHUTDOWN_TIME 254
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
char *Version = "@(#) last 2.85 31-Apr-2004 miquels";
|
char *Version = "@(#) last 2.85 31-Apr-2004 miquels";
|
||||||
|
|
||||||
#define CHOP_DOMAIN 0 /* Define to chop off local domainname. */
|
#define CHOP_DOMAIN 0 /* Define to chop off local domainname. */
|
||||||
@ -253,10 +257,11 @@ int uread(FILE *fp, struct utmp *u, int *quit)
|
|||||||
#define BTMP_FILE getbtmp()
|
#define BTMP_FILE getbtmp()
|
||||||
char *getbtmp()
|
char *getbtmp()
|
||||||
{
|
{
|
||||||
static char btmp[128];
|
static char btmp[PATH_MAX + 5]; /* max path + btmp + null terminator */
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
strcpy(btmp, WTMP_FILE);
|
memset(btmp, '\0', PATH_MAX + 5);
|
||||||
|
strncpy(btmp, WTMP_FILE, PATH_MAX);
|
||||||
if ((p = strrchr(btmp, '/')) == NULL)
|
if ((p = strrchr(btmp, '/')) == NULL)
|
||||||
p = btmp;
|
p = btmp;
|
||||||
else
|
else
|
||||||
@ -841,7 +846,7 @@ int main(int argc, char **argv)
|
|||||||
switch (ut.ut_type) {
|
switch (ut.ut_type) {
|
||||||
case SHUTDOWN_TIME:
|
case SHUTDOWN_TIME:
|
||||||
if (extended) {
|
if (extended) {
|
||||||
strcpy(ut.ut_line, "system down");
|
strncpy(ut.ut_line, "system down", OLD_LINESIZE - 1);
|
||||||
quit = list(&ut, lastboot, R_NORMAL);
|
quit = list(&ut, lastboot, R_NORMAL);
|
||||||
}
|
}
|
||||||
lastdown = lastrch = ut.ut_time;
|
lastdown = lastrch = ut.ut_time;
|
||||||
@ -850,14 +855,14 @@ int main(int argc, char **argv)
|
|||||||
case OLD_TIME:
|
case OLD_TIME:
|
||||||
case NEW_TIME:
|
case NEW_TIME:
|
||||||
if (extended) {
|
if (extended) {
|
||||||
strcpy(ut.ut_line,
|
strncpy(ut.ut_line,
|
||||||
ut.ut_type == NEW_TIME ? "new time" :
|
ut.ut_type == NEW_TIME ? "new time" :
|
||||||
"old time");
|
"old time", OLD_LINESIZE - 1);
|
||||||
quit = list(&ut, lastdown, R_TIMECHANGE);
|
quit = list(&ut, lastdown, R_TIMECHANGE);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BOOT_TIME:
|
case BOOT_TIME:
|
||||||
strcpy(ut.ut_line, "system boot");
|
strncpy(ut.ut_line, "system boot", OLD_LINESIZE - 1);
|
||||||
quit = list(&ut, lastdown, R_REBOOT);
|
quit = list(&ut, lastdown, R_REBOOT);
|
||||||
lastboot = ut.ut_time;
|
lastboot = ut.ut_time;
|
||||||
down = 1;
|
down = 1;
|
||||||
|
@ -282,7 +282,7 @@ int main(int argc, char **argv)
|
|||||||
outfn = argv[optind];
|
outfn = argv[optind];
|
||||||
optind++;
|
optind++;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
argc -= optind;
|
/* argc -= optind; - this is not used */
|
||||||
|
|
||||||
outfd = open(outfn, openflags, 0644);
|
outfd = open(outfn, openflags, 0644);
|
||||||
do_stdin = !strcmp(argv[0], "-");
|
do_stdin = !strcmp(argv[0], "-");
|
||||||
|
@ -32,6 +32,10 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 2048
|
||||||
|
#endif
|
||||||
|
|
||||||
int dostat(char *path, struct stat *st, int do_lstat, int quiet)
|
int dostat(char *path, struct stat *st, int do_lstat, int quiet)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
@ -105,7 +109,7 @@ void usage(void) {
|
|||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat st, st2;
|
struct stat st, st2;
|
||||||
char buf[256];
|
char buf[PATH_MAX + 1];
|
||||||
char *path;
|
char *path;
|
||||||
int quiet = 0;
|
int quiet = 0;
|
||||||
int showdev = 0;
|
int showdev = 0;
|
||||||
@ -163,7 +167,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
strncpy(buf, path, sizeof(buf) - 4);
|
strncpy(buf, path, sizeof(buf) - 4);
|
||||||
strcat(buf, "/..");
|
strncat(buf, "/..", 3);
|
||||||
if (dostat(buf, &st2, 0, quiet) < 0)
|
if (dostat(buf, &st2, 0, quiet) < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -70,6 +70,8 @@ extern char **environ;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MESSAGELEN 256
|
#define MESSAGELEN 256
|
||||||
|
#define STATELEN 64
|
||||||
|
#define WHEN_SIZE 64
|
||||||
|
|
||||||
/* Whether we should warn system is shutting down */
|
/* Whether we should warn system is shutting down */
|
||||||
#define QUIET_FULL 2
|
#define QUIET_FULL 2
|
||||||
@ -83,7 +85,7 @@ int fastboot = 0; /* Do a 'fast' reboot */
|
|||||||
int forcefsck = 0; /* Force fsck on reboot */
|
int forcefsck = 0; /* Force fsck on reboot */
|
||||||
char message[MESSAGELEN]; /* Warning message */
|
char message[MESSAGELEN]; /* Warning message */
|
||||||
char *sltime = 0; /* Sleep time */
|
char *sltime = 0; /* Sleep time */
|
||||||
char newstate[64]; /* What are we gonna do */
|
char newstate[STATELEN]; /* What are we gonna do */
|
||||||
int doself = 0; /* Don't use init */
|
int doself = 0; /* Don't use init */
|
||||||
int got_alrm = 0;
|
int got_alrm = 0;
|
||||||
|
|
||||||
@ -232,11 +234,11 @@ int init_setenv(char *name, char *value)
|
|||||||
*/
|
*/
|
||||||
void issue_warn(int mins)
|
void issue_warn(int mins)
|
||||||
{
|
{
|
||||||
char buf[MESSAGELEN + sizeof(newstate)];
|
char buf[MESSAGELEN + sizeof(newstate) + 1];
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
strncat(buf, message, sizeof(buf) - 1);
|
strncpy(buf, message, MESSAGELEN);
|
||||||
len = strlen(buf);
|
len = strlen(buf);
|
||||||
|
|
||||||
if (mins == 0)
|
if (mins == 0)
|
||||||
@ -519,7 +521,7 @@ int main(int argc, char **argv)
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
char term[UT_LINESIZE + 6];
|
char term[UT_LINESIZE + 6];
|
||||||
char *sp;
|
char *sp;
|
||||||
char *when = NULL;
|
char when[WHEN_SIZE];
|
||||||
int c, i, wt;
|
int c, i, wt;
|
||||||
int hours, mins;
|
int hours, mins;
|
||||||
int didnolog = 0;
|
int didnolog = 0;
|
||||||
@ -547,6 +549,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
strcpy(down_level, "1");
|
strcpy(down_level, "1");
|
||||||
halttype = NULL;
|
halttype = NULL;
|
||||||
|
memset(when, '\0', WHEN_SIZE);
|
||||||
|
|
||||||
/* Process the options. */
|
/* Process the options. */
|
||||||
while((c = getopt(argc, argv, "HPacqQkrhnfFyt:g:i:")) != EOF) {
|
while((c = getopt(argc, argv, "HPacqQkrhnfFyt:g:i:")) != EOF) {
|
||||||
@ -593,7 +596,7 @@ int main(int argc, char **argv)
|
|||||||
case 'y': /* Ignored for sysV compatibility */
|
case 'y': /* Ignored for sysV compatibility */
|
||||||
break;
|
break;
|
||||||
case 'g': /* sysv style to specify time. */
|
case 'g': /* sysv style to specify time. */
|
||||||
when = optarg;
|
strncpy(when, optarg, WHEN_SIZE - 1);
|
||||||
break;
|
break;
|
||||||
case 'i': /* Level to go to. */
|
case 'i': /* Level to go to. */
|
||||||
if (!strchr("0156aAbBcCsS", optarg[0])) {
|
if (!strchr("0156aAbBcCsS", optarg[0])) {
|
||||||
@ -679,7 +682,7 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Read remaining words, skip time if needed. */
|
/* Read remaining words, skip time if needed. */
|
||||||
message[0] = 0;
|
message[0] = 0;
|
||||||
for(c = optind + (!cancel && !when); c < argc; c++) {
|
for(c = optind + (!cancel && !when[0]); c < argc; c++) {
|
||||||
if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN)
|
if (strlen(message) + strlen(argv[c]) + 4 > MESSAGELEN)
|
||||||
break;
|
break;
|
||||||
strcat(message, argv[c]);
|
strcat(message, argv[c]);
|
||||||
@ -704,9 +707,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check syntax. */
|
/* Check syntax. */
|
||||||
if (when == NULL) {
|
if (when[0] == '\0') {
|
||||||
if (optind == argc) usage();
|
if (optind == argc) usage();
|
||||||
when = argv[optind++];
|
strncpy(when, argv[optind++], WHEN_SIZE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if we are already running. */
|
/* See if we are already running. */
|
||||||
@ -725,16 +728,16 @@ int main(int argc, char **argv)
|
|||||||
/* Tell users what we're gonna do. */
|
/* Tell users what we're gonna do. */
|
||||||
switch(down_level[0]) {
|
switch(down_level[0]) {
|
||||||
case '0':
|
case '0':
|
||||||
strcpy(newstate, "for system halt");
|
strncpy(newstate, "for system halt", STATELEN);
|
||||||
break;
|
break;
|
||||||
case '6':
|
case '6':
|
||||||
strcpy(newstate, "for reboot");
|
strncpy(newstate, "for reboot", STATELEN);
|
||||||
break;
|
break;
|
||||||
case '1':
|
case '1':
|
||||||
strcpy(newstate, "to maintenance mode");
|
strncpy(newstate, "to maintenance mode", STATELEN);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(newstate, "to runlevel %s", down_level);
|
snprintf(newstate, STATELEN, "to runlevel %s", down_level);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -772,10 +775,11 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Alias now and take care of old '+mins' notation. */
|
/* Alias now and take care of old '+mins' notation. */
|
||||||
if (!strcmp(when, "now")) strcpy(when, "0");
|
if (!strcmp(when, "now")) strcpy(when, "0");
|
||||||
if (when[0] == '+') when++;
|
|
||||||
|
|
||||||
|
sp = when;
|
||||||
|
if (when[0] == '+') sp++;
|
||||||
/* Decode shutdown time. */
|
/* Decode shutdown time. */
|
||||||
for (sp = when; *sp; sp++) {
|
for ( ; *sp; sp++) {
|
||||||
if (*sp != ':' && (*sp < '0' || *sp > '9'))
|
if (*sp != ':' && (*sp < '0' || *sp > '9'))
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user