-- Made REMIND disable "RUN" on files not owned by its effective UID.

-- Updated copyright year.
This commit is contained in:
dfs
1997-08-31 17:03:25 +00:00
parent ef2aa97967
commit 8eb2028cf2
6 changed files with 68 additions and 19 deletions

View File

@@ -13,12 +13,13 @@ CHANGES TO REMIND
`remind -p ...' to an HTML table. The script was contributed by
Don Schwarz <darkowl@mcs.net>
- New security features: Because of the risk of statically-allocated
buffer, REMIND now refuses to run if it is installed set-uid or set-gid.
- New security features: Because of the risks of statically-allocated
buffers, REMIND now refuses to run if it is installed set-uid or set-gid.
If REMIND is run as root, it refuses to read files not owned by root.
It also won't open group- or world-writable files, no matter who is
running it. REMIND doesn't do security checks on stdin, though, so
be careful if you run it as root in a script.
running it. Finally, if you read a file you don't own, REMIND disables
RUN and shell(). REMIND doesn't do these security checks on stdin,
though, so be careful if you run it as root in a script.
NOTE: REMIND doesn't do the world- and group-writable checks
on devices, FIFOs, etc. Otherwise "remind /dev/null" fails...

48
files.c
View File

@@ -12,7 +12,7 @@
/***************************************************************/
#include "config.h"
static char const RCSID[] = "$Id: files.c,v 1.8 1997-07-31 01:52:46 dfs Exp $";
static char const RCSID[] = "$Id: files.c,v 1.9 1997-08-31 17:03:25 dfs Exp $";
#include <stdio.h>
#ifdef HAVE_STDLIB_H
@@ -59,6 +59,9 @@ typedef struct cheader {
struct cheader *next;
char *filename;
CachedLine *cache;
#ifdef UNIX
int ownedByMe;
#endif
} CachedFile;
/* Define the structures needed by the INCLUDE file system */
@@ -69,6 +72,9 @@ typedef struct {
int NumIfs;
long offset;
CachedLine *CLine;
#ifdef UNIX
int ownedByMe;
#endif
} IncludeStruct;
static CachedFile *CachedFiles = (CachedFile *) NULL;
@@ -181,6 +187,9 @@ char *fname;
CachedFile *h = CachedFiles;
int r;
/* Assume we own the file for now */
RunDisabled &= ~RUN_NOTOWNER;
/* If it's in the cache, get it from there. */
while (h) {
@@ -188,6 +197,11 @@ char *fname;
CLine = h->cache;
STRSET(FileName, fname);
LineNo = 0;
#ifdef UNIX
if (!h->ownedByMe) {
RunDisabled |= RUN_NOTOWNER;
}
#endif
if (FileName) return OK; else return E_NO_MEM;
}
h = h->next;
@@ -254,6 +268,13 @@ char *fname;
return E_NO_MEM;
}
#ifdef UNIX
if (RunDisabled & RUN_NOTOWNER) {
cf->ownedByMe = 0;
} else {
cf->ownedByMe = 1;
}
#endif
/* Read the file */
while(fp) {
r = ReadLineFromFile();
@@ -320,6 +341,9 @@ int PopFile()
{
IncludeStruct *i;
/* Assume we own the file for now */
RunDisabled &= ~RUN_NOTOWNER;
if (!Hush && NumIfs) Eprint("%s", ErrMsg[E_MISS_ENDIF]);
if (!IStackPtr) return E_EOF;
IStackPtr--;
@@ -331,6 +355,11 @@ int PopFile()
CLine = i->CLine;
fp = NULL;
STRSET(FileName, i->filename);
#ifdef UNIX
if (!i->ownedByMe) {
RunDisabled |= RUN_NOTOWNER;
}
#endif
if (!CLine && (i->offset != -1L)) {
/* We must open the file, then seek to specified position */
if (strcmp(i->filename, "-")) {
@@ -389,6 +418,7 @@ char *fname;
{
IncludeStruct *i;
int r;
int oldRunDisabled;
if (IStackPtr+1 >= INCLUDE_NEST) return E_NESTED_INCLUDE;
i = &IStack[IStackPtr];
@@ -400,6 +430,13 @@ char *fname;
i->IfFlags = IfFlags;
i->CLine = CLine;
i->offset = -1L;
#ifdef UNIX
if (RunDisabled & RUN_NOTOWNER) {
i->ownedByMe = 0;
} else {
i->ownedByMe = 1;
}
#endif
if (fp) {
i->offset = ftell(fp);
FCLOSE(fp);
@@ -407,10 +444,12 @@ char *fname;
IStackPtr++;
oldRunDisabled = RunDisabled;
/* Try to open the new file */
if (!OpenFile(fname)) {
return OK;
}
RunDisabled = oldRunDisabled;
/* Ugh! We failed! */
if ( (r=PopFile()) ) return r;
Eprint("%s: %s", ErrMsg[E_CANT_OPEN], fname);
@@ -573,6 +612,7 @@ int TopLevel()
/* root, we refuse to open files not owned by root. */
/* We also reject group- or world-writable files, no matter */
/* who we're running as. */
/* As a side effect, if we don't own the file, we disable RUN */
/***************************************************************/
#ifdef HAVE_PROTOS
PRIVATE int CheckSafety(void)
@@ -615,6 +655,12 @@ static int CheckSafety()
fp = NULL;
return 0;
}
/* If file is not owned by me, disable RUN command */
if (statbuf.st_uid != geteuid()) {
RunDisabled |= RUN_NOTOWNER;
}
#endif
return 1;
}

View File

@@ -14,7 +14,7 @@
/* */
/***************************************************************/
/* $Id: french.h,v 1.4 1997-01-16 04:14:23 dfs Exp $ */
/* $Id: french.h,v 1.5 1997-08-31 17:03:25 dfs Exp $ */
/* The very first define in a language support file must be L_LANGNAME: */
#define L_LANGNAME "French"
@@ -361,7 +361,7 @@ PUBLIC void Usage(void)
void Usage()
#endif /* HAVE_PROTOS */
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1996 by David F. Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1997 by David F. Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

8
init.c
View File

@@ -12,7 +12,7 @@
/***************************************************************/
#include "config.h"
static char const RCSID[] = "$Id: init.c,v 1.6 1997-07-30 01:30:56 dfs Exp $";
static char const RCSID[] = "$Id: init.c,v 1.7 1997-08-31 17:03:26 dfs Exp $";
#define L_IN_INIT 1
#include <stdio.h>
@@ -180,7 +180,7 @@ char *argv[];
case 'r':
case 'R':
RunDisabled = 1;
RunDisabled = RUN_CMDLINE;
break;
case 'm':
@@ -234,7 +234,7 @@ char *argv[];
case 'u':
case 'U':
ChgUser(arg);
RunDisabled = 1;
RunDisabled = RUN_CMDLINE;
while (*arg) arg++;
break;
#endif
@@ -465,7 +465,7 @@ PUBLIC void Usage(void)
void Usage()
#endif /* HAVE_PROTOS */
{
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1996 by David F. Skoll\n", VERSION, L_LANGNAME);
fprintf(ErrFp, "\nREMIND %s (%s version) Copyright 1992-1997 by David F. Skoll\n", VERSION, L_LANGNAME);
#ifdef BETA
fprintf(ErrFp, ">>>> BETA VERSION <<<<\n");
#endif

View File

@@ -1,4 +1,4 @@
.\" $Id: remind.1,v 1.9 1997-08-01 02:28:31 dfs Exp $
.\" $Id: remind.1,v 1.10 1997-08-31 17:03:26 dfs Exp $
.TH REMIND 1 "31 July 1997"
.UC 4
.SH NAME
@@ -1206,10 +1206,11 @@ your main .reminders file, include the following lines:
RUN ON # Re-enable RUN
.fi
.PP
In addition, \fBRemind\fR contains a few other security features. It
will not read a file which is group- or world-writable. It will not
run set-uid. And if it is run as \fIroot\fR, it will only read files
owned by \fIroot\fR.
In addition, \fBRemind\fR on UNIX contains a few other security
features. It will not read a file which is group- or world-writable.
It will not run set-uid. If it reads a file you don't own, it will
disable RUN and the shell() function. And if it is run as \fIroot\fR,
it will only read files owned by \fIroot\fR.
.PP
.SH THE BANNER COMMAND
.PP

View File

@@ -9,7 +9,7 @@
/* */
/***************************************************************/
/* $Id: types.h,v 1.3 1997-01-16 04:14:33 dfs Exp $ */
/* $Id: types.h,v 1.4 1997-08-31 17:03:27 dfs Exp $ */
/* Values */
typedef struct {
@@ -164,8 +164,9 @@ typedef struct {
#define QUOTE_MARKER 1 /* Unlikely character to appear in reminder */
/* Flags for disabling run */
#define RUN_CMDLINE 1
#define RUN_SCRIPT 2
#define RUN_CMDLINE 1
#define RUN_SCRIPT 2
#define RUN_NOTOWNER 4
/* Flags for the SimpleCalendar format */
#define SC_AMPM 0 /* Time shown as 3:00am, etc. */