On 2013/03/23 19:37, patrick keshishian wrote:
> On Sat, Mar 23, 2013 at 5:15 PM, Creamy <[email protected]> wrote:
> > From the pppd man page:
> >
> > 1163:.Sh SCRIPTS
> > 1164-.Nm
> > 1165-invokes scripts at various stages in its processing which can be
> > 1166-used to perform site-specific ancillary processing.
> > 1167-These scripts are usually shell scripts, but could be executable code 
> > files
> > 1168-instead.
> > 1169-.Nm
> > 1170-does not wait for the scripts to finish.
> > 1171-The scripts are executed as root (with the real and effective user ID 
> > set to 0),
> >                  ^^^^^^^^^^^^^^^^^^^^
> >
> > No, they are not.  Which is wrong, the man page, or the behavior of pppd?
> 
> some history: http://marc.info/?l=openbsd-tech&m=123494734721801
> 
> ... from 2009. yikes :)
> 
> --patrick
> 

I think this diff is in the right direction, but that we should
check permissions on the scripts to make sure they aren't group/world
writable. Of course it doesn't stop people shooting themselves in
the foot by running a writable script from another, but stops
accidental problems.

Any OKs ?

Index: main.c
===================================================================
RCS file: /cvs/src/usr.sbin/pppd/main.c,v
retrieving revision 1.49
diff -u -p -r1.49 main.c
--- main.c      30 Apr 2011 18:49:38 -0000      1.49
+++ main.c      28 Mar 2013 15:25:56 -0000
@@ -1173,9 +1173,17 @@ run_program(prog, args, must_exist)
     char **args;
     int must_exist;
 {
+    struct stat sbuf;
     pid_t pid;
     uid_t uid;
-    gid_t gid;
+
+    if (stat(prog, &sbuf) < 0) {
+       syslog(LOG_ERR, "cannot stat program file %s: %m", prog);
+       return -1;
+    } else if ((sbuf.st_mode & (S_IWGRP | S_IWOTH)) != 0) {
+       syslog(LOG_ERR, "%s: group/world writable", prog);
+       return -1;
+    }
 
     pid = fork();
     if (pid == -1) {
@@ -1190,10 +1198,9 @@ run_program(prog, args, must_exist)
        (void) umask (S_IRWXG|S_IRWXO);
        (void) chdir ("/"); /* no current directory. */
 
-       /* revoke privs */
+       /* Execute scripts as root, to allow routing table changes etc. */
        uid = getuid();
-       gid = getgid();
-       if (setresgid(gid, gid, gid) == -1 || setresuid(uid, uid, uid) == -1) {
+       if (setreuid(0, 0) == -1) {
                syslog(LOG_ERR, "revoke privileges: %s", strerror(errno));
                _exit(1);
        }

Reply via email to