ppp/ppp-2.4.4-fd_leak.patch
2010-02-04 08:41:10 +00:00

516 lines
16 KiB
Diff

diff -up ppp-2.4.4/pppd/auth.c.fd_leak ppp-2.4.4/pppd/auth.c
--- ppp-2.4.4/pppd/auth.c.fd_leak 2006-06-18 13:26:00.000000000 +0200
+++ ppp-2.4.4/pppd/auth.c 2009-10-08 21:22:59.789547513 +0200
@@ -428,7 +428,7 @@ setupapfile(argv)
option_error("unable to reset uid before opening %s: %m", fname);
return 0;
}
- ufile = fopen(fname, "r");
+ ufile = fopen_r(fname);
if (seteuid(euid) == -1)
fatal("unable to regain privileges: %m");
if (ufile == NULL) {
@@ -1414,7 +1414,7 @@ check_passwd(unit, auser, userlen, apass
filename = _PATH_UPAPFILE;
addrs = opts = NULL;
ret = UPAP_AUTHNAK;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL) {
error("Can't open PAP password file %s: %m", filename);
@@ -1511,7 +1511,7 @@ null_login(unit)
if (ret <= 0) {
filename = _PATH_UPAPFILE;
addrs = NULL;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL)
return 0;
check_access(f, filename);
@@ -1558,7 +1558,7 @@ get_pap_passwd(passwd)
}
filename = _PATH_UPAPFILE;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL)
return 0;
check_access(f, filename);
@@ -1596,7 +1596,7 @@ have_pap_secret(lacks_ipp)
}
filename = _PATH_UPAPFILE;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL)
return 0;
@@ -1641,7 +1641,7 @@ have_chap_secret(client, server, need_ip
}
filename = _PATH_CHAPFILE;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL)
return 0;
@@ -1683,7 +1683,7 @@ have_srp_secret(client, server, need_ip,
struct wordlist *addrs;
filename = _PATH_SRPFILE;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL)
return 0;
@@ -1739,7 +1739,7 @@ get_secret(unit, client, server, secret,
addrs = NULL;
secbuf[0] = 0;
- f = fopen(filename, "r");
+ f = fopen_r(filename);
if (f == NULL) {
error("Can't open chap secret file %s: %m", filename);
return 0;
@@ -1796,7 +1796,7 @@ get_srp_secret(unit, client, server, sec
filename = _PATH_SRPFILE;
addrs = NULL;
- fp = fopen(filename, "r");
+ fp = fopen_r(filename);
if (fp == NULL) {
error("Can't open srp secret file %s: %m", filename);
return 0;
@@ -2202,7 +2202,7 @@ scan_authfile(f, client, server, secret,
*/
if (word[0] == '@' && word[1] == '/') {
strlcpy(atfile, word+1, sizeof(atfile));
- if ((sf = fopen(atfile, "r")) == NULL) {
+ if ((sf = fopen_r(atfile)) == NULL) {
warn("can't open indirect secret file %s", atfile);
continue;
}
diff -up ppp-2.4.4/pppd/eap.c.fd_leak ppp-2.4.4/pppd/eap.c
--- ppp-2.4.4/pppd/eap.c.fd_leak 2004-11-09 23:39:25.000000000 +0100
+++ ppp-2.4.4/pppd/eap.c 2009-10-08 21:22:59.791544181 +0200
@@ -1226,7 +1226,7 @@ mode_t modebits;
if ((path = name_of_pn_file()) == NULL)
return (-1);
- fd = open(path, modebits, S_IRUSR | S_IWUSR);
+ fd = open_fd(path, modebits, S_IRUSR | S_IWUSR);
err = errno;
free(path);
errno = err;
diff -up ppp-2.4.4/pppd/main.c.fd_leak ppp-2.4.4/pppd/main.c
--- ppp-2.4.4/pppd/main.c.fd_leak 2009-10-08 21:22:59.769544859 +0200
+++ ppp-2.4.4/pppd/main.c 2009-10-08 21:30:32.356546561 +0200
@@ -201,6 +201,8 @@ int ngroups; /* How many groups valid
static struct timeval start_time; /* Time when link was started. */
+static int cloexec_works; /* controlls setting FD_CLOEXEC flag up */
+
static struct pppd_stats old_link_stats;
struct pppd_stats link_stats;
unsigned link_connect_time;
@@ -245,6 +247,7 @@ static void holdoff_end __P((void *));
static void forget_child __P((int pid, int status));
static int reap_kids __P((void));
static void childwait_end __P((void *));
+static void check_cloexec __P((int));
#ifdef USE_TDB
static void update_db_entry __P((void));
@@ -419,7 +422,7 @@ main(argc, argv)
die(0);
/* Make sure fds 0, 1, 2 are open to somewhere. */
- fd_devnull = open(_PATH_DEVNULL, O_RDWR);
+ fd_devnull = open_fd(_PATH_DEVNULL, O_RDWR);
if (fd_devnull < 0)
fatal("Couldn't open %s: %m", _PATH_DEVNULL);
while (fd_devnull <= 2) {
@@ -865,6 +866,104 @@ holdoff_end(arg)
new_phase(PHASE_DORMANT);
}
+
+/*
+ * check_cloexec - checks for FD_CLOEXEC flag and adds it if necessary
+ */
+static void
+check_cloexec(int fd)
+{
+ if (cloexec_works == 0) {
+ int fl = fcntl(fd, F_GETFD);
+ cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1;
+ }
+ if (cloexec_works > 0)
+ return;
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ return;
+}
+
+/*
+ * socket_fd - create an endpoint for communication. uses FD_CLOEXEC if supported
+ */
+int
+socket_fd(int domain, int type, int protocol)
+{
+ int fd;
+
+#ifdef SOCK_CLOEXEC
+ if (cloexec_works != -1)
+ type |= SOCK_CLOEXEC;
+#endif
+ fd = socket(domain, type, protocol);
+ if (fd == -1)
+ return -1;
+ check_cloexec(fd);
+ return fd;
+}
+
+/*
+ * open_fd - open file with FD_CLOEXEC flag
+ */
+int
+open_fd(const char *path, int flags)
+{
+ int fd;
+
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+ if (cloexec_works != -1)
+ flags |= O_CLOEXEC;
+#endif
+ fd = open(path, flags);
+ if (fd == -1)
+ return -1;
+ check_cloexec(fd);
+ return fd;
+}
+
+/*
+ * open_fd_mmode - open file with FD_CLOEXEC flag
+ */
+int
+open_fd_mode(const char *path, int flags, int mode)
+{
+ int fd;
+
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+ if (cloexec_works != -1)
+ flags |= O_CLOEXEC;
+#endif
+ fd = open(path, flags, mode);
+ if (fd == -1)
+ return -1;
+ check_cloexec(fd);
+ return fd;
+}
+
+/*
+ * fopen_r - open file with FD_CLOEXEC flag
+ */
+FILE *
+fopen_r(const char *path)
+{
+ FILE *f;
+
+#if defined(O_CLOEXEC) && defined(SOCK_CLOEXEC)
+ if (cloexec_works != -1) {
+ f = fopen(path, "re");
+ if (f != NULL) {
+ check_cloexec(fileno(f));
+ return f;
+ }
+ }
+#endif
+ f = fopen(path, "r");
+ if (f == NULL)
+ return NULL;
+ check_cloexec(fileno(f));
+ return f;
+}
+
/* List of protocol names, to make our messages a little more informative. */
struct protocol_list {
u_short proto;
@@ -1618,7 +1717,7 @@ device_script(program, in, out, dont_wai
if (log_to_fd >= 0)
errfd = log_to_fd;
else
- errfd = open(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
+ errfd = open_fd_mode(_PATH_CONNERRS, O_WRONLY | O_APPEND | O_CREAT, 0600);
++conn_running;
pid = safe_fork(in, out, errfd);
diff -up ppp-2.4.4/pppd/options.c.fd_leak ppp-2.4.4/pppd/options.c
--- ppp-2.4.4/pppd/options.c.fd_leak 2006-06-18 13:26:00.000000000 +0200
+++ ppp-2.4.4/pppd/options.c 2009-10-08 21:22:59.797544174 +0200
@@ -409,7 +409,7 @@ options_from_file(filename, must_exist,
option_error("unable to drop privileges to open %s: %m", filename);
return 0;
}
- f = fopen(filename, "r");
+ f = fopen_r(filename);
err = errno;
if (check_prot && seteuid(euid) == -1)
fatal("unable to regain privileges");
@@ -1528,9 +1528,9 @@ setlogfile(argv)
option_error("unable to drop permissions to open %s: %m", *argv);
return 0;
}
- fd = open(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644);
+ fd = open_fd_mode(*argv, O_WRONLY | O_APPEND | O_CREAT | O_EXCL, 0644);
if (fd < 0 && errno == EEXIST)
- fd = open(*argv, O_WRONLY | O_APPEND);
+ fd = open_fd(*argv, O_WRONLY | O_APPEND);
err = errno;
if (!privileged_option && seteuid(euid) == -1)
fatal("unable to regain privileges: %m");
diff -up ppp-2.4.4/pppd/pppd.h.fd_leak ppp-2.4.4/pppd/pppd.h
--- ppp-2.4.4/pppd/pppd.h.fd_leak 2005-08-26 01:59:34.000000000 +0200
+++ ppp-2.4.4/pppd/pppd.h 2009-10-08 21:22:59.800544904 +0200
@@ -494,6 +494,10 @@ int ppp_send_config __P((int, int, u_in
int ppp_recv_config __P((int, int, u_int32_t, int, int));
const char *protocol_name __P((int));
void remove_pidfiles __P((void));
+int socket_fd __P((int, int, int));
+int open_fd __P((const char *, int));
+int open_fd_mode __P((const char *, int, int));
+FILE *fopen_r __P((const char *));
void lock_db __P((void));
void unlock_db __P((void));
diff -up ppp-2.4.4/pppd/sys-linux.c.fd_leak ppp-2.4.4/pppd/sys-linux.c
--- ppp-2.4.4/pppd/sys-linux.c.fd_leak 2009-10-08 21:22:59.778544744 +0200
+++ ppp-2.4.4/pppd/sys-linux.c 2009-10-08 21:22:59.803544377 +0200
@@ -308,12 +308,12 @@ static int modify_flags(int fd, int clea
void sys_init(void)
{
/* Get an internet socket for doing socket ioctls. */
- sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ sock_fd = socket_fd(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0)
fatal("Couldn't create IP socket: %m(%d)", errno);
#ifdef INET6
- sock6_fd = socket(AF_INET6, SOCK_DGRAM, 0);
+ sock6_fd = socket_fd(AF_INET6, SOCK_DGRAM, 0);
if (sock6_fd < 0)
sock6_fd = -errno; /* save errno for later */
#endif
@@ -459,7 +459,7 @@ int generic_establish_ppp (int fd)
goto err;
}
dbglog("using channel %d", chindex);
- fd = open("/dev/ppp", O_RDWR);
+ fd = open_fd("/dev/ppp", O_RDWR);
if (fd < 0) {
error("Couldn't reopen /dev/ppp: %m");
goto err;
@@ -619,7 +619,7 @@ static int make_ppp_unit()
dbglog("in make_ppp_unit, already had /dev/ppp open?");
close(ppp_dev_fd);
}
- ppp_dev_fd = open("/dev/ppp", O_RDWR);
+ ppp_dev_fd = open_fd("/dev/ppp", O_RDWR);
if (ppp_dev_fd < 0)
fatal("Couldn't open /dev/ppp: %m");
flags = fcntl(ppp_dev_fd, F_GETFL);
@@ -693,7 +693,7 @@ int bundle_attach(int ifnum)
if (!new_style_driver)
return -1;
- master_fd = open("/dev/ppp", O_RDWR);
+ master_fd = open_fd("/dev/ppp", O_RDWR);
if (master_fd < 0)
fatal("Couldn't open /dev/ppp: %m");
if (ioctl(master_fd, PPPIOCATTACH, &ifnum) < 0) {
@@ -1412,7 +1412,7 @@ static char *path_to_procfs(const char *
/* Default the mount location of /proc */
strlcpy (proc_path, "/proc", sizeof(proc_path));
proc_path_len = 5;
- fp = fopen(MOUNTED, "r");
+ fp = fopen_r(MOUNTED);
if (fp != NULL) {
while ((mntent = getmntent(fp)) != NULL) {
if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0)
@@ -1472,7 +1472,7 @@ static int open_route_table (void)
close_route_table();
path = path_to_procfs("/net/route");
- route_fd = fopen (path, "r");
+ route_fd = fopen_r(path);
if (route_fd == NULL) {
error("can't open routing table %s: %m", path);
return 0;
@@ -1713,7 +1713,7 @@ int sifproxyarp (int unit, u_int32_t his
if (tune_kernel) {
forw_path = path_to_procfs("/sys/net/ipv4/ip_forward");
if (forw_path != 0) {
- int fd = open(forw_path, O_WRONLY);
+ int fd = open_fd(forw_path, O_WRONLY);
if (fd >= 0) {
if (write(fd, "1", 1) != 1)
error("Couldn't enable IP forwarding: %m");
@@ -1857,7 +1857,7 @@ get_if_hwaddr(u_char *addr, char *name)
struct ifreq ifreq;
int ret, sock_fd;
- sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
+ sock_fd = socket_fd(AF_INET, SOCK_DGRAM, 0);
if (sock_fd < 0)
return 0;
memset(&ifreq.ifr_hwaddr, 0, sizeof(struct sockaddr));
@@ -2030,7 +2030,7 @@ int ppp_available(void)
sscanf(utsname.release, "%d.%d.%d", &osmaj, &osmin, &ospatch);
kernel_version = KVERSION(osmaj, osmin, ospatch);
- fd = open("/dev/ppp", O_RDWR);
+ fd = open_fd("/dev/ppp", O_RDWR);
if (fd >= 0) {
new_style_driver = 1;
@@ -2068,7 +2068,7 @@ int ppp_available(void)
/*
* Open a socket for doing the ioctl operations.
*/
- s = socket(AF_INET, SOCK_DGRAM, 0);
+ s = socket_fd(AF_INET, SOCK_DGRAM, 0);
if (s < 0)
return 0;
@@ -2318,7 +2318,7 @@ int sifaddr (int unit, u_int32_t our_adr
int fd;
path = path_to_procfs("/sys/net/ipv4/ip_dynaddr");
- if (path != 0 && (fd = open(path, O_WRONLY)) >= 0) {
+ if (path != 0 && (fd = open_fd(path, O_WRONLY)) >= 0) {
if (write(fd, "1", 1) != 1)
error("Couldn't enable dynamic IP addressing: %m");
close(fd);
@@ -2494,7 +2494,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
/*
* Try the unix98 way first.
*/
- mfd = open("/dev/ptmx", O_RDWR);
+ mfd = open_fd("/dev/ptmx", O_RDWR);
if (mfd >= 0) {
int ptn;
if (ioctl(mfd, TIOCGPTN, &ptn) >= 0) {
@@ -2505,7 +2505,7 @@ get_pty(master_fdp, slave_fdp, slave_nam
if (ioctl(mfd, TIOCSPTLCK, &ptn) < 0)
warn("Couldn't unlock pty slave %s: %m", pty_name);
#endif
- if ((sfd = open(pty_name, O_RDWR | O_NOCTTY)) < 0)
+ if ((sfd = open_fd(pty_name, O_RDWR | O_NOCTTY)) < 0)
warn("Couldn't open pty slave %s: %m", pty_name);
}
}
@@ -2516,10 +2516,10 @@ get_pty(master_fdp, slave_fdp, slave_nam
for (i = 0; i < 64; ++i) {
slprintf(pty_name, sizeof(pty_name), "/dev/pty%c%x",
'p' + i / 16, i % 16);
- mfd = open(pty_name, O_RDWR, 0);
+ mfd = open_fd_mode(pty_name, O_RDWR, 0);
if (mfd >= 0) {
pty_name[5] = 't';
- sfd = open(pty_name, O_RDWR | O_NOCTTY, 0);
+ sfd = open_fd_mode(pty_name, O_RDWR | O_NOCTTY, 0);
if (sfd >= 0) {
fchown(sfd, uid, -1);
fchmod(sfd, S_IRUSR | S_IWUSR);
@@ -2784,7 +2784,7 @@ ether_to_eui64(eui64_t *p_eui64)
int skfd;
const unsigned char *ptr;
- skfd = socket(PF_INET6, SOCK_DGRAM, 0);
+ skfd = socket_fd(PF_INET6, SOCK_DGRAM, 0);
if(skfd == -1)
{
warn("could not open IPv6 socket");
diff -up ppp-2.4.4/pppd/tdb.c.fd_leak ppp-2.4.4/pppd/tdb.c
--- ppp-2.4.4/pppd/tdb.c.fd_leak 2004-11-13 08:13:07.000000000 +0100
+++ ppp-2.4.4/pppd/tdb.c 2009-10-08 21:22:59.806583590 +0200
@@ -1724,7 +1724,7 @@ TDB_CONTEXT *tdb_open_ex(const char *nam
goto internal;
}
- if ((tdb->fd = open(name, open_flags, mode)) == -1) {
+ if ((tdb->fd = open_fd_mode(name, open_flags, mode)) == -1) {
TDB_LOG((tdb, 5, "tdb_open_ex: could not open file %s: %s\n",
name, strerror(errno)));
goto fail; /* errno set by open(2) */
@@ -1967,7 +1967,7 @@ int tdb_reopen(TDB_CONTEXT *tdb)
}
if (close(tdb->fd) != 0)
TDB_LOG((tdb, 0, "tdb_reopen: WARNING closing tdb->fd failed!\n"));
- tdb->fd = open(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
+ tdb->fd = open_fd_mode(tdb->name, tdb->open_flags & ~(O_CREAT|O_TRUNC), 0);
if (tdb->fd == -1) {
TDB_LOG((tdb, 0, "tdb_reopen: open failed (%s)\n", strerror(errno)));
goto fail;
diff -up ppp-2.4.4/pppd/tty.c.fd_leak ppp-2.4.4/pppd/tty.c
--- ppp-2.4.4/pppd/tty.c.fd_leak 2006-06-04 09:04:57.000000000 +0200
+++ ppp-2.4.4/pppd/tty.c 2009-10-08 21:22:59.809544300 +0200
@@ -569,7 +569,7 @@ int connect_tty()
status = EXIT_OPEN_FAILED;
goto errret;
}
- real_ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0);
+ real_ttyfd = open_fd_mode(devnam, O_NONBLOCK | O_RDWR, 0);
err = errno;
if (prio < OPRIO_ROOT && seteuid(0) == -1)
fatal("Unable to regain privileges");
@@ -723,7 +723,7 @@ int connect_tty()
if (connector == NULL && modem && devnam[0] != 0) {
int i;
for (;;) {
- if ((i = open(devnam, O_RDWR)) >= 0)
+ if ((i = open_fd(devnam, O_RDWR)) >= 0)
break;
if (errno != EINTR) {
error("Failed to reopen %s: %m", devnam);
@@ -896,7 +896,8 @@ open_socket(dest)
*sep = ':';
/* get a socket and connect it to the other end */
- sock = socket(PF_INET, SOCK_STREAM, 0);
+ //sock = socket(PF_INET, SOCK_STREAM, 0);
+ sock = socket_fd(PF_INET, SOCK_STREAM, 0);
if (sock < 0) {
error("Can't create socket: %m");
return -1;
diff -up ppp-2.4.4/pppd/utils.c.fd_leak ppp-2.4.4/pppd/utils.c
--- ppp-2.4.4/pppd/utils.c.fd_leak 2009-10-08 21:22:59.620325739 +0200
+++ ppp-2.4.4/pppd/utils.c 2009-10-08 21:22:59.811573725 +0200
@@ -931,14 +931,14 @@ lock(dev)
slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev);
#endif
- while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
+ while ((fd = open_fd_mode(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {
if (errno != EEXIST) {
error("Can't create lock file %s: %m", lock_file);
break;
}
/* Read the lock file to find out who has the device locked. */
- fd = open(lock_file, O_RDONLY, 0);
+ fd = open_fd_mode(lock_file, O_RDONLY, 0);
if (fd < 0) {
if (errno == ENOENT) /* This is just a timing problem. */
continue;
@@ -1017,7 +1017,7 @@ relock(pid)
if (lock_file[0] == 0)
return -1;
- fd = open(lock_file, O_WRONLY, 0);
+ fd = open_fd_mode(lock_file, O_WRONLY, 0);
if (fd < 0) {
error("Couldn't reopen lock file %s: %m", lock_file);
lock_file[0] = 0;