mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Close security holes and restore suid bit
Restore writting cat's functionality
This commit is contained in:
parent
0e47b59f75
commit
b08645daa4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=16573
@ -1,5 +1,7 @@
|
||||
PROG= man
|
||||
SRCS= man.c manpath.c glob.c
|
||||
BINOWN= man
|
||||
BINMODE=4555
|
||||
|
||||
.if exists(${.CURDIR}/../lib/obj)
|
||||
LDADD= -L${.CURDIR}/../lib/obj -lman
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <signal.h>
|
||||
@ -131,6 +132,7 @@ main (argc, argv)
|
||||
|
||||
prognam = mkprogname (argv[0]);
|
||||
|
||||
unsetenv("IFS");
|
||||
man_getopt (argc, argv);
|
||||
|
||||
if (optind == argc)
|
||||
@ -981,7 +983,7 @@ make_roff_command (file)
|
||||
fprintf (stderr, "using default preprocessor sequence\n");
|
||||
|
||||
if ((cp = get_expander(file)) == NULL)
|
||||
cp = "cat";
|
||||
cp = "/bin/cat";
|
||||
sprintf(buf, "%s %s | ", cp, file);
|
||||
#ifdef HAS_TROFF
|
||||
if (troff)
|
||||
@ -1020,6 +1022,33 @@ make_roff_command (file)
|
||||
return buf;
|
||||
}
|
||||
|
||||
sig_t ohup, oint, oquit, oterm;
|
||||
static char temp[FILENAME_MAX];
|
||||
|
||||
void cleantmp()
|
||||
{
|
||||
unlink(temp);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
set_sigs()
|
||||
{
|
||||
ohup = signal(SIGHUP, cleantmp);
|
||||
oint = signal(SIGINT, cleantmp);
|
||||
oquit = signal(SIGQUIT, cleantmp);
|
||||
oterm = signal(SIGTERM, cleantmp);
|
||||
}
|
||||
|
||||
void
|
||||
restore_sigs()
|
||||
{
|
||||
signal(SIGHUP, ohup);
|
||||
signal(SIGINT, oint);
|
||||
signal(SIGQUIT, oquit);
|
||||
signal(SIGTERM, oterm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to format the man page and create a new formatted file. Return
|
||||
* 1 for success and 0 for failure.
|
||||
@ -1030,73 +1059,121 @@ make_cat_file (path, man_file, cat_file)
|
||||
register char *man_file;
|
||||
register char *cat_file;
|
||||
{
|
||||
int status;
|
||||
int mode;
|
||||
FILE *fp;
|
||||
int s, f;
|
||||
FILE *fp, *pp;
|
||||
char *roff_command;
|
||||
char command[FILENAME_MAX];
|
||||
char temp[FILENAME_MAX];
|
||||
|
||||
sprintf(temp, "%s.tmp", cat_file);
|
||||
if ((fp = fopen (temp, "w")) != NULL)
|
||||
roff_command = make_roff_command (man_file);
|
||||
if (roff_command == NULL)
|
||||
return 0;
|
||||
|
||||
sprintf(temp, "%s.tmpXXXXXX", cat_file);
|
||||
if ((f = mkstemp(temp)) >= 0 && (fp = fdopen(f, "w")) != NULL)
|
||||
{
|
||||
fclose (fp);
|
||||
unlink (temp);
|
||||
set_sigs();
|
||||
|
||||
roff_command = make_roff_command (man_file);
|
||||
if (roff_command == NULL)
|
||||
if (fchmod (f, CATMODE) < 0) {
|
||||
perror("fchmod");
|
||||
unlink(temp);
|
||||
restore_sigs();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
else
|
||||
} else if (debug)
|
||||
fprintf (stderr, "mode of %s is now %o\n", temp, CATMODE);
|
||||
|
||||
#ifdef DO_COMPRESS
|
||||
sprintf (command, "(cd %s ; %s | %s > %s)", path,
|
||||
roff_command, COMPRESSOR, temp);
|
||||
sprintf (command, "(cd %s ; %s | %s)", path,
|
||||
roff_command, COMPRESSOR);
|
||||
#else
|
||||
sprintf (command, "(cd %s ; %s > %s)", path,
|
||||
roff_command, temp);
|
||||
sprintf (command, "(cd %s ; %s)", path,
|
||||
roff_command);
|
||||
#endif
|
||||
/*
|
||||
* Don't let the user interrupt the system () call and screw up
|
||||
* the formatted man page if we're not done yet.
|
||||
*/
|
||||
fprintf (stderr, "Formatting page, please wait...");
|
||||
fflush(stderr);
|
||||
|
||||
status = do_system_command (command);
|
||||
|
||||
if (status <= 0) {
|
||||
fprintf(stderr, "Failed.\n");
|
||||
unlink(temp);
|
||||
return(0);
|
||||
}
|
||||
if (debug)
|
||||
fprintf (stderr, "\ntrying command: %s\n", command);
|
||||
else {
|
||||
if (rename(temp, cat_file) == -1) {
|
||||
/* FS might be sticky */
|
||||
sprintf(command, "cp %s %s", temp, cat_file);
|
||||
if (system(command))
|
||||
fprintf(stderr,
|
||||
"\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n",
|
||||
temp, cat_file);
|
||||
unlink(temp);
|
||||
return 0;
|
||||
|
||||
if ((pp = popen(command, "r")) == NULL) {
|
||||
s = errno;
|
||||
fprintf(stderr, "Failed.\n");
|
||||
errno = s;
|
||||
perror("popen");
|
||||
unlink(temp);
|
||||
restore_sigs();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while ((s = getc(pp)) != EOF)
|
||||
putc(s, fp);
|
||||
|
||||
if ((s = pclose(pp)) == -1) {
|
||||
s = errno;
|
||||
fprintf(stderr, "Failed.\n");
|
||||
errno = s;
|
||||
perror("pclose");
|
||||
unlink(temp);
|
||||
restore_sigs();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s != 0) {
|
||||
fprintf(stderr, "Failed.\n");
|
||||
gripe_system_command(s);
|
||||
unlink(temp);
|
||||
restore_sigs();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rename(temp, cat_file) == -1) {
|
||||
s = errno;
|
||||
fprintf(stderr,
|
||||
"\nHmm! Can't seem to rename %s to %s, check permissions on man dir!\n",
|
||||
temp, cat_file);
|
||||
errno = s;
|
||||
perror("rename");
|
||||
unlink(temp);
|
||||
restore_sigs();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
restore_sigs();
|
||||
|
||||
if (fclose(fp)) {
|
||||
s = errno;
|
||||
unlink(cat_file);
|
||||
fprintf(stderr, "Failed.\n");
|
||||
errno = s;
|
||||
perror("fclose");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Done.\n");
|
||||
if (status == 1)
|
||||
{
|
||||
mode = CATMODE;
|
||||
chmod (cat_file, mode);
|
||||
|
||||
if (debug)
|
||||
fprintf (stderr, "mode of %s is now %o\n", cat_file, mode);
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (debug)
|
||||
fprintf (stderr, "Couldn't open %s for writing.\n", cat_file);
|
||||
if (f >= 0) {
|
||||
s = errno;
|
||||
unlink(temp);
|
||||
errno = s;
|
||||
}
|
||||
if (debug) {
|
||||
s = errno;
|
||||
fprintf (stderr, "Couldn't open %s for writing.\n", temp);
|
||||
errno = s;
|
||||
}
|
||||
if (f >= 0) {
|
||||
perror("fdopen");
|
||||
close(f);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user