From 1fae28ce79350b03f0cf8a69ad06dd68637cd6b1 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 12 Mar 1999 06:07:24 +0000 Subject: [PATCH] use strlcpy, strlcat, slprintf everywhere add privgroup option don't allow devname, connector etc. set in privileged place to be overridden by non-privileged user use error, warn, etc. functions instead of syslog fix problem where signals were blocked for too long --- pppd/Makefile.sunos4 | 4 +- pppd/auth.c | 84 ++++++---- pppd/ccp.c | 4 +- pppd/chap.c | 5 +- pppd/fsm.c | 15 +- pppd/ipcp.c | 8 +- pppd/ipxcp.c | 28 ++-- pppd/main.c | 379 +++++++++++++++++++++++++++++++------------ pppd/options.c | 77 ++++----- pppd/patchlevel.h | 6 +- pppd/pppd.8 | 26 ++- pppd/pppd.h | 34 +++- pppd/sys-NeXT.c | 34 ++-- pppd/sys-aix4.c | 20 +-- pppd/sys-bsd.c | 28 ++-- pppd/sys-linux.c | 109 +++++-------- pppd/sys-osf.c | 30 ++-- pppd/sys-sunos4.c | 28 ++-- pppd/sys-svr4.c | 32 ++-- pppd/sys-ultrix.c | 30 ++-- 20 files changed, 587 insertions(+), 394 deletions(-) diff --git a/pppd/Makefile.sunos4 b/pppd/Makefile.sunos4 index 66be1b3..9e46ad4 100644 --- a/pppd/Makefile.sunos4 +++ b/pppd/Makefile.sunos4 @@ -1,13 +1,13 @@ # # Makefile for pppd under SunOS 4. -# $Id: Makefile.sunos4,v 1.8 1998/03/25 01:27:06 paulus Exp $ +# $Id: Makefile.sunos4,v 1.9 1999/03/12 06:07:14 paulus Exp $ # include ../sunos4/Makedefs LIBS = -CFLAGS = $(COPTS) -I../include -DSUNOS4 +CFLAGS = $(COPTS) -I../include -DSUNOS4 -DGIDSET_TYPE=int all: pppd diff --git a/pppd/auth.c b/pppd/auth.c index 4b68650..0fbc9b9 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: auth.c,v 1.44 1999/03/08 01:47:54 paulus Exp $"; +static char rcsid[] = "$Id: auth.c,v 1.45 1999/03/12 06:07:14 paulus Exp $"; #endif #include @@ -42,6 +42,7 @@ static char rcsid[] = "$Id: auth.c,v 1.44 1999/03/08 01:47:54 paulus Exp $"; #include #include #include +#include #include #include #include @@ -81,7 +82,7 @@ static char rcsid[] = "$Id: auth.c,v 1.44 1999/03/08 01:47:54 paulus Exp $"; /* Used for storing a sequence of words. Usually malloced. */ struct wordlist { struct wordlist *next; - char word[1]; + char *word; }; /* Bits in scan_authfile return value */ @@ -154,7 +155,8 @@ static int scan_authfile __P((FILE *, char *, char *, u_int32_t, char *, static void free_wordlist __P((struct wordlist *)); static void auth_script __P((char *)); static void set_allowed_addrs __P((int, struct wordlist *)); -static int setupapfile __P((char **)); +static int setupapfile __P((char **)); +static int privgroup __P((char **)); /* * Authentication-related options. @@ -195,6 +197,8 @@ option_t auth_options[] = { "PAP passwords are encrypted", 1 }, { "+ua", o_special, setupapfile, "Get PAP user and password from file" }, + { "privgroup", o_special, privgroup, + "Allow group members to use privileged options", OPT_PRIV }, { NULL } }; @@ -246,6 +250,31 @@ setupapfile(argv) } +/* + * privgroup - allow members of the group to have privileged access. + */ +static int +privgroup(argv) + char **argv; +{ + struct group *g; + int i; + + g = getgrnam(*argv); + if (g == 0) { + option_error("group %s is unknown", *argv); + return 0; + } + for (i = 0; i < ngroups; ++i) { + if (groups[i] == g->gr_gid) { + privileged = 1; + break; + } + } + return 1; +} + + /* * An Open on LCP has requested a change from Dead to Establish phase. * Do what's necessary to bring the physical layer up. @@ -618,9 +647,9 @@ auth_check_options() /* Default our_name to hostname, and user to our_name */ if (our_name[0] == 0 || usehostname) - strcpy(our_name, hostname); + strlcpy(our_name, sizeof(our_name), hostname); if (user[0] == 0) - strcpy(user, our_name); + strlcpy(user, sizeof(user), our_name); /* If authentication is required, ask peer for CHAP or PAP. */ if (auth_required) { @@ -659,20 +688,6 @@ auth_check_options() remote_name, our_name); exit(1); } - - /* - * Check whether the user tried to override certain values - * set by root. - */ - if (allow_any_ip) { - if ((connector != NULL && connector_info.priv == 0) - || (disconnector != NULL && disconnector_info.priv == 0) - || (welcomer != NULL && welcomer_info.priv == 0)) { - option_error("connect, disconnect and welcome options"); - option_error("are privileged when noauth option is used"); - exit(1); - } - } } /* @@ -1002,7 +1017,7 @@ plogin(user, passwd, msg, msglen) (void)lseek(fd, (off_t)(pw->pw_uid * sizeof(ll)), SEEK_SET); memset((void *)&ll, 0, sizeof(ll)); (void)time(&ll.ll_time); - (void)strncpy(ll.ll_line, tty, sizeof(ll.ll_line)); + (void)strlcpy(ll.ll_line, sizeof(ll.ll_line), tty); (void)write(fd, (char *)&ll, sizeof(ll)); (void)close(fd); } @@ -1099,6 +1114,7 @@ null_login(unit) * get_pap_passwd - get a password for authenticating ourselves with * our peer using PAP. Returns 1 on success, 0 if no suitable password * could be found. + * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). */ static int get_pap_passwd(passwd) @@ -1122,10 +1138,8 @@ get_pap_passwd(passwd) fclose(f); if (ret < 0) return 0; - if (passwd != NULL) { - strncpy(passwd, secret, MAXSECRETLEN); - passwd[MAXSECRETLEN-1] = 0; - } + if (passwd != NULL) + strlcpy(passwd, MAXSECRETLEN, secret); BZERO(secret, sizeof(secret)); return 1; } @@ -1423,7 +1437,8 @@ check_access(f, filename) * NONWILD_CLIENT set if the secret didn't have "*" for the client, and * NONWILD_SERVER set if the secret didn't have "*" for the server. * Any following words on the line (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. + * info) are placed in a wordlist and returned in *addrs. + * We assume secret is NULL or points to MAXWORDLEN bytes of space. */ static int scan_authfile(f, client, server, ipaddr, secret, addrs, filename) @@ -1501,23 +1516,21 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) * Special syntax: @filename means read secret from file. */ if (word[0] == '@') { - strcpy(atfile, word+1); + strlcpy(atfile, sizeof(atfile), word+1); if ((sf = fopen(atfile, "r")) == NULL) { - syslog(LOG_WARNING, "can't open indirect secret file %s", - atfile); + warn("can't open indirect secret file %s", atfile); continue; } check_access(sf, atfile); if (!getword(sf, word, &xxx, atfile)) { - syslog(LOG_WARNING, "no secret in indirect secret file %s", - atfile); + warn("no secret in indirect secret file %s", atfile); fclose(sf); continue; } fclose(sf); } if (secret != NULL) - strcpy(lsecret, word); + strlcpy(lsecret, sizeof(lsecret), word); /* * Now read address authorization info and make a wordlist. @@ -1526,12 +1539,13 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) for (;;) { if (!getword(f, word, &newline, filename) || newline) break; - ap = (struct wordlist *) malloc(sizeof(struct wordlist) - + strlen(word)); + ap = (struct wordlist *) malloc(sizeof(struct wordlist)); if (ap == NULL) novm("authorized addresses"); ap->next = NULL; - strcpy(ap->word, word); + ap->word = strdup(word); + if (ap->word == NULL) + novm("authorized address"); if (alist == NULL) alist = ap; else @@ -1557,7 +1571,7 @@ scan_authfile(f, client, server, ipaddr, secret, addrs, filename) free_wordlist(addr_list); addr_list = alist; if (secret != NULL) - strcpy(secret, lsecret); + strlcpy(secret, MAXWORDLEN, lsecret); if (!newline) break; diff --git a/pppd/ccp.c b/pppd/ccp.c index 0f0f444..c93e963 100644 --- a/pppd/ccp.c +++ b/pppd/ccp.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: ccp.c,v 1.23 1998/11/07 06:59:26 paulus Exp $"; +static char rcsid[] = "$Id: ccp.c,v 1.24 1999/03/12 06:07:14 paulus Exp $"; #endif #include @@ -1036,7 +1036,7 @@ ccp_up(f) syslog(LOG_NOTICE, "%s compression enabled", method_name(go, ho)); } else { - strcpy(method1, method_name(go, NULL)); + strlcpy(method1, sizeof(method1), method_name(go, NULL)); syslog(LOG_NOTICE, "%s / %s compression enabled", method1, method_name(ho, NULL)); } diff --git a/pppd/chap.c b/pppd/chap.c index 96348e1..6b405f1 100644 --- a/pppd/chap.c +++ b/pppd/chap.c @@ -34,7 +34,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: chap.c,v 1.17 1999/02/26 10:38:51 paulus Exp $"; +static char rcsid[] = "$Id: chap.c,v 1.18 1999/03/12 06:07:15 paulus Exp $"; #endif /* @@ -442,8 +442,7 @@ ChapReceiveChallenge(cstate, inp, id, len) /* Microsoft doesn't send their name back in the PPP packet */ if (remote_name[0] != 0 && (explicit_remote || rhostname[0] == 0)) { - strncpy(rhostname, remote_name, sizeof(rhostname)); - rhostname[sizeof(rhostname) - 1] = 0; + strlcpy(rhostname, sizeof(rhostname), remote_name); CHAPDEBUG((LOG_INFO, "ChapReceiveChallenge: using '%s' as remote name", rhostname)); } diff --git a/pppd/fsm.c b/pppd/fsm.c index 1cf073e..879a1c1 100644 --- a/pppd/fsm.c +++ b/pppd/fsm.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: fsm.c,v 1.13 1997/04/30 05:52:17 paulus Exp $"; +static char rcsid[] = "$Id: fsm.c,v 1.14 1999/03/12 06:07:16 paulus Exp $"; #endif /* @@ -260,8 +260,7 @@ fsm_timeout(arg) case ACKRCVD: case ACKSENT: if (f->retransmits <= 0) { - syslog(LOG_WARNING, "%s: timeout sending Config-Requests", - PROTO_NAME(f)); + warn("%s: timeout sending Config-Requests\n", PROTO_NAME(f)); f->state = STOPPED; if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) (*f->callbacks->finished)(f); @@ -570,8 +569,6 @@ fsm_rtermreq(f, id, p, len) u_char *p; int len; { - char str[80]; - FSMDEBUG((LOG_INFO, "fsm_rtermreq(%s): Rcvd id %d.", PROTO_NAME(f), id)); @@ -583,10 +580,9 @@ fsm_rtermreq(f, id, p, len) case OPENED: if (len > 0) { - fmtmsg(str, sizeof(str), "%0.*v", len, p); - syslog(LOG_INFO, "%s terminated by peer (%s)", PROTO_NAME(f), str); + info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); } else - syslog(LOG_INFO, "%s terminated by peer", PROTO_NAME(f)); + info("%s terminated by peer", PROTO_NAME(f)); if (f->callbacks->down) (*f->callbacks->down)(f); /* Inform upper layers */ f->retransmits = 0; @@ -654,8 +650,7 @@ fsm_rcoderej(f, inp, len) } GETCHAR(code, inp); GETCHAR(id, inp); - syslog(LOG_WARNING, "%s: Rcvd Code-Reject for code %d, id %d", - PROTO_NAME(f), code, id); + warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); if( f->state == ACKRCVD ) f->state = REQSENT; diff --git a/pppd/ipcp.c b/pppd/ipcp.c index 225e30a..db31a2f 100644 --- a/pppd/ipcp.c +++ b/pppd/ipcp.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: ipcp.c,v 1.37 1999/03/08 05:34:43 paulus Exp $"; +static char rcsid[] = "$Id: ipcp.c,v 1.38 1999/03/12 06:07:17 paulus Exp $"; #endif /* @@ -1637,9 +1637,9 @@ ipcp_script(script) char strspeed[32], strlocal[32], strremote[32]; char *argv[8]; - sprintf(strspeed, "%d", baud_rate); - strcpy(strlocal, ip_ntoa(ipcp_gotoptions[0].ouraddr)); - strcpy(strremote, ip_ntoa(ipcp_hisoptions[0].hisaddr)); + slprintf(strspeed, sizeof(strspeed), "%d", baud_rate); + slprintf(strlocal, sizeof(strlocal), "%I", ipcp_gotoptions[0].ouraddr); + slprintf(strremote, sizeof(strremote), "%I", ipcp_hisoptions[0].hisaddr); argv[0] = script; argv[1] = ifname; diff --git a/pppd/ipxcp.c b/pppd/ipxcp.c index 34ce4c9..7601063 100644 --- a/pppd/ipxcp.c +++ b/pppd/ipxcp.c @@ -19,7 +19,7 @@ #ifdef IPX_CHANGE #ifndef lint -static char rcsid[] = "$Id: ipxcp.c,v 1.8 1998/11/07 06:59:27 paulus Exp $"; +static char rcsid[] = "$Id: ipxcp.c,v 1.9 1999/03/12 06:07:17 paulus Exp $"; #endif /* @@ -1341,38 +1341,38 @@ ipxcp_script(f, script) strproto_lcl[0] = '\0'; if (go->neg_router && ((go->router & BIT(IPX_NONE)) == 0)) { if (go->router & BIT(RIP_SAP)) - strcpy (strproto_lcl, "RIP "); + strlcpy (strproto_lcl, sizeof(strproto_lcl), "RIP "); if (go->router & BIT(NLSP)) - strcat (strproto_lcl, "NLSP "); + strlcat (strproto_lcl, sizeof(strproto_lcl), "NLSP "); } if (strproto_lcl[0] == '\0') - strcpy (strproto_lcl, "NONE "); + strlcpy (strproto_lcl, sizeof(strproto_lcl), "NONE "); strproto_lcl[strlen (strproto_lcl)-1] = '\0'; strproto_rmt[0] = '\0'; if (ho->neg_router && ((ho->router & BIT(IPX_NONE)) == 0)) { if (ho->router & BIT(RIP_SAP)) - strcpy (strproto_rmt, "RIP "); + strlcpy (strproto_rmt, sizeof(strproto_rmt), "RIP "); if (ho->router & BIT(NLSP)) - strcat (strproto_rmt, "NLSP "); + strlcat (strproto_rmt, sizeof(strproto_rmt), "NLSP "); } if (strproto_rmt[0] == '\0') - strcpy (strproto_rmt, "NONE "); + strlcpy (strproto_rmt, sizeof(strproto_rmt), "NONE "); strproto_rmt[strlen (strproto_rmt)-1] = '\0'; - strcpy (strnetwork, ipx_ntoa (go->network)); + strlcpy (strnetwork, sizeof(strnetwork), ipx_ntoa (go->network)); - sprintf (strlocal, - "%02X%02X%02X%02X%02X%02X", - NODE(go->our_node)); + slprintf (strlocal, sizeof(strlocal), + "%02X%02X%02X%02X%02X%02X", + NODE(go->our_node)); - sprintf (strremote, - "%02X%02X%02X%02X%02X%02X", - NODE(ho->his_node)); + slprintf (strremote, sizeof(strremote), + "%02X%02X%02X%02X%02X%02X", + NODE(ho->his_node)); argv[0] = script; argv[1] = ifname; diff --git a/pppd/main.c b/pppd/main.c index 0921954..37ad65f 100644 --- a/pppd/main.c +++ b/pppd/main.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: main.c,v 1.57 1999/03/08 05:34:43 paulus Exp $"; +static char rcsid[] = "$Id: main.c,v 1.58 1999/03/12 06:07:18 paulus Exp $"; #endif #include @@ -93,7 +93,7 @@ int kill_link; int open_ccp_flag; static int waiting; -static jmp_buf sigjmp; +static sigjmp_buf sigjmp; char **script_env; /* Env. variable values for scripts */ int s_env_nalloc; /* # words avail at script_env */ @@ -107,6 +107,9 @@ static int locked; /* lock() has succeeded */ char *no_ppp_msg = "Sorry - this system lacks PPP kernel support\n"; +GIDSET_TYPE groups[NGROUPS_MAX];/* groups the user is in */ +int ngroups; /* How many groups valid in groups */ + /* Prototypes for procedures local to this file. */ static void create_pidfile __P((void)); @@ -181,8 +184,8 @@ main(argc, argv) phase = PHASE_INITIALIZE; p = ttyname(0); if (p) - strcpy(devnam, p); - strcpy(default_devnam, devnam); + strlcpy(devnam, sizeof(devnam), p); + strlcpy(default_devnam, sizeof(default_devnam), devnam); script_env = NULL; @@ -205,6 +208,8 @@ main(argc, argv) sprintf(numbuf, "%d", uid); script_setenv("ORIG_UID", numbuf); + ngroups = getgroups(NGROUPS_MAX, groups); + /* * Initialize to the standard option set, then parse, in order, * the system options file, the user's options file, @@ -302,13 +307,11 @@ main(argc, argv) sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGUSR2); -#define SIGNAL(s, handler) { \ +#define SIGNAL(s, handler) do { \ sa.sa_handler = handler; \ - if (sigaction(s, &sa, NULL) < 0) { \ - syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ - exit(1); \ - } \ - } + if (sigaction(s, &sa, NULL) < 0) \ + fatal("Couldn't establish signal handler (%d): %m", s); \ + } while (0) sa.sa_mask = mask; sa.sa_flags = 0; @@ -367,7 +370,6 @@ main(argc, argv) signal(SIGPIPE, SIG_IGN); waiting = 0; - sigprocmask(SIG_BLOCK, &mask, NULL); /* * If we're doing dial-on-demand, set up the interface now. @@ -398,16 +400,20 @@ main(argc, argv) /* * Don't do anything until we see some activity. */ - phase = PHASE_DORMANT; kill_link = 0; + phase = PHASE_DORMANT; demand_unblock(); for (;;) { - if (setjmp(sigjmp) == 0) { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_loop_output(timeleft(&timo)); + if (sigsetjmp(sigjmp, 1) == 0) { + sigprocmask(SIG_BLOCK, &mask, NULL); + if (kill_link) { + sigprocmask(SIG_UNBLOCK, &mask, NULL); + } else { + waiting = 1; + sigprocmask(SIG_UNBLOCK, &mask, NULL); + wait_loop_output(timeleft(&timo)); + } } - sigprocmask(SIG_BLOCK, &mask, NULL); waiting = 0; calltimeout(); if (kill_link) { @@ -419,14 +425,14 @@ main(argc, argv) break; reap_kids(); } - if (kill_link) + if (kill_link && !persist) break; /* * Now we want to bring up the link. */ demand_block(); - syslog(LOG_INFO, "Starting link"); + info("Starting link"); } /* @@ -447,7 +453,6 @@ main(argc, argv) */ hungup = 0; kill_link = 0; - sigprocmask(SIG_UNBLOCK, &mask, NULL); for (;;) { /* If the user specified the device name, become the user before opening it. */ @@ -459,23 +464,20 @@ main(argc, argv) if (ttyfd >= 0) break; if (errno != EINTR) - syslog(LOG_ERR, "Failed to open %s: %m", devnam); + error("Failed to open %s: %m", devnam); if (!persist || errno != EINTR) goto fail; } - sigprocmask(SIG_BLOCK, &mask, NULL); if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) - syslog(LOG_WARNING, - "Couldn't reset non-blocking mode on device: %m"); + warn("Couldn't reset non-blocking mode on device: %m"); /* * Do the equivalent of `mesg n' to stop broadcast messages. */ if (fstat(ttyfd, &statbuf) < 0 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { - syslog(LOG_WARNING, - "Couldn't restrict write permissions to %s: %m", devnam); + warn("Couldn't restrict write permissions to %s: %m", devnam); } else tty_mode = statbuf.st_mode; @@ -500,11 +502,11 @@ main(argc, argv) set_up_tty(ttyfd, 1); if (device_script(connector, ttyfd, ttyfd) < 0) { - syslog(LOG_ERR, "Connect script failed"); + error("Connect script failed"); goto fail; } - syslog(LOG_INFO, "Serial connection established."); + info("Serial connection established."); sleep(1); /* give it time to set up its terminal */ } @@ -522,7 +524,7 @@ main(argc, argv) if (i >= 0) break; if (errno != EINTR) - syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); + error("Failed to reopen %s: %m", devnam); if (!persist || errno != EINTR || hungup || kill_link) goto fail; } @@ -532,7 +534,7 @@ main(argc, argv) /* run welcome script, if any */ if (welcomer && welcomer[0]) { if (device_script(welcomer, ttyfd, ttyfd) < 0) - syslog(LOG_WARNING, "Welcome script failed"); + warn("Welcome script failed"); } /* set up the serial device as a ppp interface */ @@ -540,7 +542,7 @@ main(argc, argv) if (!demand) { - syslog(LOG_INFO, "Using interface ppp%d", ifunit); + info("Using interface ppp%d", ifunit); (void) sprintf(ifname, "ppp%d", ifunit); script_setenv("IFNAME", ifname); @@ -551,17 +553,23 @@ main(argc, argv) * Start opening the connection and wait for * incoming events (reply, timeout, etc.). */ + if (kill_link) + goto fail; syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); lcp_lowerup(0); lcp_open(0); /* Start protocol */ open_ccp_flag = 0; for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { - if (setjmp(sigjmp) == 0) { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_input(timeleft(&timo)); + if (sigsetjmp(sigjmp, 1) == 0) { + sigprocmask(SIG_BLOCK, &mask, NULL); + if (kill_link || open_ccp_flag) { + sigprocmask(SIG_UNBLOCK, &mask, NULL); + } else { + waiting = 1; + sigprocmask(SIG_UNBLOCK, &mask, NULL); + wait_input(timeleft(&timo)); + } } - sigprocmask(SIG_BLOCK, &mask, NULL); waiting = 0; calltimeout(); if (kill_link) { @@ -596,9 +604,9 @@ main(argc, argv) if (disconnector && !hungup) { set_up_tty(ttyfd, 1); if (device_script(disconnector, ttyfd, ttyfd) < 0) { - syslog(LOG_WARNING, "disconnect script failed"); + warn("disconnect script failed"); } else { - syslog(LOG_INFO, "Serial link disconnected."); + info("Serial link disconnected."); } } @@ -613,25 +621,30 @@ main(argc, argv) if (!demand) { if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - syslog(LOG_WARNING, "unable to delete pid file: %m"); + warn("unable to delete pid file: %m"); pidfilename[0] = 0; } if (!persist) break; + kill_link = 0; if (demand) demand_discard(); if (holdoff > 0 && need_holdoff) { phase = PHASE_HOLDOFF; TIMEOUT(holdoff_end, NULL, holdoff); do { - if (setjmp(sigjmp) == 0) { - waiting = 1; - sigprocmask(SIG_UNBLOCK, &mask, NULL); - wait_time(timeleft(&timo)); + if (sigsetjmp(sigjmp, 1) == 0) { + sigprocmask(SIG_BLOCK, &mask, NULL); + if (kill_link) { + sigprocmask(SIG_UNBLOCK, &mask, NULL); + } else { + waiting = 1; + sigprocmask(SIG_UNBLOCK, &mask, NULL); + wait_time(timeleft(&timo)); + } } - sigprocmask(SIG_BLOCK, &mask, NULL); waiting = 0; calltimeout(); if (kill_link) { @@ -686,7 +699,7 @@ create_pidfile() fprintf(pidfile, "%d\n", pid); (void) fclose(pidfile); } else { - syslog(LOG_ERR, "Failed to create pid file %s: %m", pidfilename); + error("Failed to create pid file %s: %m", pidfilename); pidfilename[0] = 0; } sprintf(numbuf, "%d", pid); @@ -721,7 +734,7 @@ get_input() return; if (len == 0) { - syslog(LOG_NOTICE, "Modem hangup"); + notice("Modem hangup"); hungup = 1; lcp_lowerdown(0); /* serial link is no longer available */ link_terminated(0); @@ -777,7 +790,7 @@ get_input() } if (debug) - syslog(LOG_WARNING, "Unsupported protocol (0x%x) received", protocol); + warn("Unsupported protocol (0x%x) received", protocol); lcp_sprotrej(0, p - PPP_HDRLEN, len + PPP_HDRLEN); } @@ -816,7 +829,7 @@ cleanup() close_tty(); if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) - syslog(LOG_WARNING, "unable to delete pid file: %m"); + warn("unable to delete pid file: %m"); pidfilename[0] = 0; if (locked) @@ -894,10 +907,8 @@ timeout(func, arg, time) /* * Allocate timeout. */ - if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) { - syslog(LOG_ERR, "Out of memory in timeout()!"); - die(1); - } + if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) + fatal("Out of memory in timeout()!"); newp->c_arg = arg; newp->c_func = func; gettimeofday(&timenow, NULL); @@ -952,10 +963,8 @@ calltimeout() while (callout != NULL) { p = callout; - if (gettimeofday(&timenow, NULL) < 0) { - syslog(LOG_ERR, "Failed to get time of day: %m"); - die(1); - } + if (gettimeofday(&timenow, NULL) < 0) + fatal("Failed to get time of day: %m"); if (!(p->c_time.tv_sec < timenow.tv_sec || (p->c_time.tv_sec == timenow.tv_sec && p->c_time.tv_usec <= timenow.tv_usec))) @@ -1021,13 +1030,13 @@ static void hup(sig) int sig; { - syslog(LOG_INFO, "Hangup (SIGHUP)"); + info("Hangup (SIGHUP)"); kill_link = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); if (waiting) - longjmp(sigjmp, 1); + siglongjmp(sigjmp, 1); } @@ -1041,14 +1050,14 @@ static void term(sig) int sig; { - syslog(LOG_INFO, "Terminating on signal %d.", sig); + info("Terminating on signal %d.", sig); persist = 0; /* don't try to restart */ kill_link = 1; if (conn_running) /* Send the signal to the [dis]connector process(es) also */ kill_my_pg(sig); if (waiting) - longjmp(sigjmp, 1); + siglongjmp(sigjmp, 1); } @@ -1061,7 +1070,7 @@ chld(sig) int sig; { if (waiting) - longjmp(sigjmp, 1); + siglongjmp(sigjmp, 1); } @@ -1096,7 +1105,7 @@ open_ccp(sig) { open_ccp_flag = 1; if (waiting) - longjmp(sigjmp, 1); + siglongjmp(sigjmp, 1); } @@ -1112,7 +1121,7 @@ bad_signal(sig) if (crashed) _exit(127); crashed = 1; - syslog(LOG_ERR, "Fatal signal %d", sig); + error("Fatal signal %d", sig); if (conn_running) kill_my_pg(SIGTERM); die(1); @@ -1137,8 +1146,7 @@ device_script(program, in, out) if (pid < 0) { conn_running = 0; - syslog(LOG_ERR, "Failed to create child process: %m"); - die(1); + fatal("Failed to create child process: %m"); } if (pid == 0) { @@ -1171,18 +1179,21 @@ device_script(program, in, out) } } setuid(uid); + if (getuid() != uid) { + syslog(LOG_ERR, "setuid failed"); + exit(1); + } setgid(getgid()); execl("/bin/sh", "sh", "-c", program, (char *)0); syslog(LOG_ERR, "could not exec /bin/sh: %m"); - _exit(99); + exit(99); /* NOTREACHED */ } while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; - syslog(LOG_ERR, "error waiting for (dis)connection process: %m"); - die(1); + fatal("error waiting for (dis)connection process: %m"); } conn_running = 0; @@ -1236,15 +1247,13 @@ run_program(prog, args, must_exist, done, arg) if (stat(prog, &sbuf) < 0 || !S_ISREG(sbuf.st_mode) || (sbuf.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { if (must_exist || errno != ENOENT) - syslog(LOG_WARNING, "Can't execute %s: %m", prog); + warn("Can't execute %s: %m", prog); return 0; } pid = fork(); - if (pid == -1) { - syslog(LOG_ERR, "Failed to create child process for %s: %m", prog); - die(1); - } + if (pid == -1) + fatal("Failed to create child process for %s: %m", prog); if (pid == 0) { int new_fd; @@ -1277,31 +1286,25 @@ run_program(prog, args, must_exist, done, arg) #ifdef BSD /* Force the priority back to zero if pppd is running higher. */ if (setpriority (PRIO_PROCESS, 0, 0) < 0) - syslog (LOG_WARNING, "can't reset priority to 0: %m"); + syslog(LOG_WARNING, "can't reset priority to 0: %m"); #endif /* SysV recommends a second fork at this point. */ /* run the program */ execve(prog, args, script_env); - if (must_exist || errno != ENOENT) { - int i; + if (must_exist || errno != ENOENT) syslog(LOG_WARNING, "Can't execute %s: %m", prog); - for (i = 0; args[i]; ++i) - syslog(LOG_DEBUG, "args[%d] = '%s'", i, args[i]); - for (i = 0; script_env[i]; ++i) - syslog(LOG_DEBUG, "env[%d] = '%s'", i, script_env[i]); - } _exit(-1); } if (debug) - syslog(LOG_DEBUG, "Script %s started; pid = %d", prog, pid); + dbglog("Script %s started; pid = %d", prog, pid); ++n_children; chp = (struct subprocess *) malloc(sizeof(struct subprocess)); if (chp == NULL) { - syslog(LOG_WARNING, "losing track of %s process", prog); + warn("losing track of %s process", prog); } else { chp->pid = pid; chp->prog = prog; @@ -1333,18 +1336,17 @@ reap_kids() if (chp->pid == pid) break; if (debug) - syslog(LOG_DEBUG, "process %d (%s) finished, status = 0x%x", + dbglog("process %d (%s) finished, status = 0x%x", pid, (chp? chp->prog: "??"), status); if (WIFSIGNALED(status)) { - syslog(LOG_WARNING, - "Child process %s (pid %d) terminated with signal %d", - (chp? chp->prog: "??"), pid, WTERMSIG(status)); + warn("Child process %s (pid %d) terminated with signal %d", + (chp? chp->prog: "??"), pid, WTERMSIG(status)); } if (chp && chp->done) (*chp->done)(chp->arg); } if (pid == -1 && errno != ECHILD) - syslog(LOG_ERR, "Error waiting for child process: %m"); + error("Error waiting for child process: %m"); } @@ -1362,7 +1364,7 @@ log_packet(p, len, prefix, level) char *prefix; int level; { - strcpy(line, prefix); + strlcpy(line, sizeof(line), prefix); linep = line + strlen(line); format_packet(p, len, pr_log, NULL); if (linep != line) @@ -1428,14 +1430,14 @@ pr_log __V((void *arg, char *fmt, ...)) fmt = va_arg(pvar, char *); #endif - n = vfmtmsg(buf, sizeof(buf), fmt, pvar); + n = vslprintf(buf, sizeof(buf), fmt, pvar); va_end(pvar); if (linep + n + 1 > line + sizeof(line)) { syslog(LOG_DEBUG, "%s", line); linep = line; } - strcpy(linep, buf); + strlcpy(linep, line + sizeof(line) - linep, buf); linep += n; } @@ -1485,19 +1487,19 @@ void novm(msg) char *msg; { - syslog(LOG_ERR, "Virtual memory exhausted allocating %s\n", msg); - die(1); + fatal("Virtual memory exhausted allocating %s\n", msg); } /* - * fmtmsg - format a message into a buffer. Like sprintf except we + * slprintf - format a message into a buffer. Like sprintf except we * also specify the length of the output buffer, and we handle - * %r (recursive format), %m (error message) and %I (IP address) formats. + * %r (recursive format), %m (error message), %v (visible string), + * %q (quoted string), %t (current time) and %I (IP address) formats. * Doesn't do floating-point formats. * Returns the number of chars put into buf. */ int -fmtmsg __V((char *buf, int buflen, char *fmt, ...)) +slprintf __V((char *buf, int buflen, char *fmt, ...)) { va_list args; int n; @@ -1513,18 +1515,18 @@ fmtmsg __V((char *buf, int buflen, char *fmt, ...)) buflen = va_arg(args, int); fmt = va_arg(args, char *); #endif - n = vfmtmsg(buf, buflen, fmt, args); + n = vslprintf(buf, buflen, fmt, args); va_end(args); return n; } /* - * vfmtmsg - like fmtmsg, takes a va_list instead of a list of args. + * vslprintf - like slprintf, takes a va_list instead of a list of args. */ #define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) int -vfmtmsg(buf, buflen, fmt, args) +vslprintf(buf, buflen, fmt, args) char *buf; int buflen; char *fmt; @@ -1628,10 +1630,10 @@ vfmtmsg(buf, buflen, fmt, args) case 'r': f = va_arg(args, char *); #ifndef __powerpc__ - n = vfmtmsg(buf, buflen + 1, f, va_arg(args, va_list)); + n = vslprintf(buf, buflen + 1, f, va_arg(args, va_list)); #else /* On the powerpc, a va_list is an array of 1 structure */ - n = vfmtmsg(buf, buflen + 1, f, va_arg(args, void *)); + n = vslprintf(buf, buflen + 1, f, va_arg(args, void *)); #endif buf += n; buflen -= n; @@ -1746,16 +1748,14 @@ void script_setenv(var, value) char *var, *value; { - int vl = strlen(var); + size_t vl = strlen(var) + strlen(value) + 2; int i; char *p, *newstring; - newstring = (char *) malloc(vl + strlen(value) + 2); + newstring = (char *) malloc(vl); if (newstring == 0) return; - strcpy(newstring, var); - newstring[vl] = '='; - strcpy(newstring+vl+1, value); + slprintf(newstring, vl, "%s=%s", var, value); /* check if this variable is already set */ if (script_env != 0) { @@ -1812,3 +1812,170 @@ script_unsetenv(var) } } } + +/* + * strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +void +strlcpy(char *dest, size_t len, const char *src) +{ + if (len == 0) + return; + if (strlen(src) < len) + strcpy(dest, src); + else { + strncpy(dest, src, len - 1); + dest[len-1] = 0; + } +} + +/* + * strlcat - like strcat/strncat, doesn't overflow destination buffer, + * always leaves destination null-terminated (for len > 0). + */ +void +strlcat(char *dest, size_t len, const char *src) +{ + size_t dlen; + + if (len == 0) + return; + dlen = strlen(dest); + if (dlen < len - 1) + strlcpy(dest + dlen, len - dlen, src); +} + +/* + * fatal - log an error message and die horribly. + */ +void +fatal __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_ERR, "%s", line); + + die(1); /* as promised */ +} + +/* + * error - log an error message. + */ +void +error __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_ERR, "%s", line); +} + +/* + * warn - log a warning message. + */ +void +warn __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_WARNING, "%s", line); +} + +/* + * notice - log a notice-level message. + */ +void +notice __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_NOTICE, "%s", line); +} + +/* + * info - log an informational message. + */ +void +info __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_INFO, "%s", line); +} + +/* + * dbglog - log a debug message. + */ +void +dbglog __V((char *fmt, ...)) +{ + va_list pvar; + +#if __STDC__ + va_start(pvar, fmt); +#else + char *fmt; + va_start(pvar); + fmt = va_arg(pvar, char *); +#endif + + vslprintf(line, sizeof(line), fmt, pvar); + va_end(pvar); + + syslog(LOG_DEBUG, "%s", line); +} diff --git a/pppd/options.c b/pppd/options.c index 2371ed3..838a3b8 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -18,7 +18,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: options.c,v 1.50 1999/03/08 05:34:44 paulus Exp $"; +static char rcsid[] = "$Id: options.c,v 1.51 1999/03/12 06:07:19 paulus Exp $"; #endif #include @@ -60,10 +60,6 @@ static char rcsid[] = "$Id: options.c,v 1.50 1999/03/08 05:34:44 paulus Exp $"; char *strdup __P((char *)); #endif -#ifndef GIDSET_TYPE -#define GIDSET_TYPE gid_t -#endif - /* * Option variables and default values. */ @@ -159,11 +155,14 @@ option_t general_options[] = { { "-all", o_special_noarg, noopt, "Don't request/allow any LCP or IPCP options (useless)" }, { "connect", o_string, &connector, - "A program to set up a connection", OPT_A2INFO, &connector_info }, + "A program to set up a connection", + OPT_A2INFO | OPT_PRIVFIX, &connector_info }, { "disconnect", o_string, &disconnector, - "Program to disconnect serial device", OPT_A2INFO, &disconnector_info }, + "Program to disconnect serial device", + OPT_A2INFO | OPT_PRIVFIX, &disconnector_info }, { "welcome", o_string, &welcomer, - "Script to welcome client", OPT_A2INFO, &welcomer_info }, + "Script to welcome client", + OPT_A2INFO | OPT_PRIVFIX, &welcomer_info }, { "maxconnect", o_int, &maxconnect, "Set connection time limit", OPT_LLIMIT|OPT_NOINCR|OPT_ZEROINF }, { "crtscts", o_int, &crtscts, @@ -422,17 +421,17 @@ options_from_user() char *user, *path, *file; int ret; struct passwd *pw; + size_t pl; pw = getpwuid(getuid()); if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) return 1; file = _PATH_USEROPT; - path = malloc(strlen(user) + strlen(file) + 2); + pl = strlen(user) + strlen(file) + 2; + path = malloc(pl); if (path == NULL) novm("init file name"); - strcpy(path, user); - strcat(path, "/"); - strcat(path, file); + slprintf(path, pl, "%s/%s", user, file); ret = options_from_file(path, 0, 1, privileged); free(path); return ret; @@ -447,20 +446,22 @@ options_for_tty() { char *dev, *path, *p; int ret; + size_t pl; dev = devnam; if (strncmp(dev, "/dev/", 5) == 0) dev += 5; if (strcmp(dev, "tty") == 0) return 1; /* don't look for /etc/ppp/options.tty */ - path = malloc(strlen(_PATH_TTYOPT) + strlen(dev) + 1); + pl = strlen(_PATH_TTYOPT) + strlen(dev) + 1; + path = malloc(pl); if (path == NULL) novm("tty init file name"); - strcpy(path, _PATH_TTYOPT); + slprintf(path, pl, "%s%s", _PATH_TTYOPT, dev); /* Turn slashes into dots, for Solaris case (e.g. /dev/term/a) */ - for (p = path + strlen(path); *dev != 0; ++dev) - *p++ = (*dev == '/'? '.': *dev); - *p = 0; + for (p = path + strlen(_PATH_TTYOPT); *p != 0; ++p) + if (*p == '/') + *p = '.'; ret = options_from_file(path, 0, 0, 1); free(path); return ret; @@ -513,6 +514,13 @@ process_option(opt, argv) option_error("%s option is disabled", opt->name); return 0; } + if ((opt->flags & OPT_PRIVFIX) && !privileged_option) { + struct option_info *ip = (struct option_info *) opt->addr2; + if (ip && ip->priv) { + option_error("%s option cannot be overridden", opt->name); + return 0; + } + } switch (opt->type) { case o_bool: @@ -581,11 +589,7 @@ process_option(opt, argv) case o_string: if (opt->flags & OPT_STATIC) { - if (opt->upper_limit) { - strncpy((char *)(opt->addr), *argv, opt->upper_limit); - ((char *)(opt->addr))[opt->upper_limit-1] = 0; - } else - strcpy((char *)(opt->addr), *argv); + strlcpy((char *)(opt->addr), opt->upper_limit, *argv); } else { sv = strdup(*argv); if (sv == NULL) @@ -683,7 +687,7 @@ option_error __V((char *fmt, ...)) va_start(args); fmt = va_arg(args, char *); #endif - vfmtmsg(buf, sizeof(buf), fmt, args); + vslprintf(buf, sizeof(buf), fmt, args); va_end(args); if (phase == PHASE_INITIALIZE) fprintf(stderr, "%s: %s\n", progname, buf); @@ -698,9 +702,8 @@ readable(fd) int fd; { uid_t uid; - int ngroups, i; + int i; struct stat sbuf; - GIDSET_TYPE groups[NGROUPS_MAX]; uid = getuid(); if (uid == 0) @@ -711,7 +714,6 @@ readable(fd) return sbuf.st_mode & S_IRUSR; if (sbuf.st_gid == getgid()) return sbuf.st_mode & S_IRGRP; - ngroups = getgroups(NGROUPS_MAX, groups); for (i = 0; i < ngroups; ++i) if (sbuf.st_gid == groups[i]) return sbuf.st_mode & S_IRGRP; @@ -1053,8 +1055,7 @@ callfile(argv) l = strlen(arg) + strlen(_PATH_PEERFILES) + 1; if ((fname = (char *) malloc(l)) == NULL) novm("call file name"); - strcpy(fname, _PATH_PEERFILES); - strcat(fname, arg); + slprintf(fname, l, "%s%s", _PATH_PEERFILES, arg); ok = options_from_file(fname, 1, 1, 1); @@ -1176,9 +1177,8 @@ setdevname(cp, quiet) return 0; if (strncmp("/dev/", cp, 5) != 0) { - strcpy(dev, "/dev/"); - strncat(dev, cp, MAXPATHLEN - 5); - dev[MAXPATHLEN-1] = 0; + strlcpy(dev, sizeof(dev), "/dev/"); + strlcat(dev, sizeof(dev), cp); cp = dev; } @@ -1192,8 +1192,13 @@ setdevname(cp, quiet) return -1; } - (void) strncpy(devnam, cp, MAXPATHLEN); - devnam[MAXPATHLEN-1] = 0; + if (devnam_info.priv && !privileged_option) { + if (!quiet) + option_error("device name cannot be overridden"); + return -1; + } + + strlcpy(devnam, sizeof(devnam), cp); default_device = FALSE; devnam_info.priv = privileged_option; devnam_info.source = option_source; @@ -1252,10 +1257,8 @@ setipaddr(arg) return -1; } else { remote = *(u_int32_t *)hp->h_addr; - if (remote_name[0] == 0) { - strncpy(remote_name, colon, MAXNAMELEN); - remote_name[MAXNAMELEN-1] = 0; - } + if (remote_name[0] == 0) + strlcpy(remote_name, sizeof(remote_name), colon); } } if (bad_ip_adrs(remote)) { diff --git a/pppd/patchlevel.h b/pppd/patchlevel.h index 1882b59..14d160c 100644 --- a/pppd/patchlevel.h +++ b/pppd/patchlevel.h @@ -1,6 +1,6 @@ -/* $Id: patchlevel.h,v 1.35 1999/02/26 10:33:43 paulus Exp $ */ -#define PATCHLEVEL 6 +/* $Id: patchlevel.h,v 1.36 1999/03/12 06:07:19 paulus Exp $ */ +#define PATCHLEVEL 7 #define VERSION "2.3" -#define IMPLEMENTATION "" +#define IMPLEMENTATION "alpha" #define DATE "26 February 1999" diff --git a/pppd/pppd.8 b/pppd/pppd.8 index a4cd4c5..b4bbdb0 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -1,5 +1,5 @@ .\" manual page [] for pppd 2.3 -.\" $Id: pppd.8,v 1.33 1999/03/03 00:52:08 paulus Exp $ +.\" $Id: pppd.8,v 1.34 1999/03/12 06:07:19 paulus Exp $ .\" SH section heading .\" SS subsection heading .\" LP paragraph @@ -36,7 +36,9 @@ Control Protocol, IPCP). Communicate over the named device. The string "/dev/" is prepended if necessary. If no device name is given, or if the name of the terminal connected to the standard input is given, pppd will use that terminal, -and will not fork to put itself in the background. +and will not fork to put itself in the background. A value for this +option from a privileged source cannot be overridden by a +non-privileged user. .TP .I Set the baud rate to (a decimal number). On systems such as @@ -73,8 +75,9 @@ is described below. .B connect \fIscript Use the executable or shell command specified by \fIscript\fR to set up the serial line. This script would typically use the chat(8) -program to dial the modem and start the remote ppp session. This -option is privileged if the \fInoauth\fR option is used. +program to dial the modem and start the remote ppp session. A value +for this option from a privileged source cannot be overridden by a +non-privileged user. .TP .B crtscts Use hardware flow control (i.e. RTS/CTS) to control the flow of @@ -112,8 +115,8 @@ Run the executable or shell command specified by \fIscript\fR after pppd has terminated the link. This script could, for example, issue commands to the modem to cause it to hang up if hardware modem control signals were not available. The disconnect script is not run if the -modem has already hung up. This option is privileged if the -\fInoauth\fR option is used. +modem has already hung up. A value for this option from a privileged +source cannot be overridden by a non-privileged user. .TP .B escape \fIxx,yy,... Specifies that certain characters should be escaped on transmission @@ -612,6 +615,13 @@ compression, and agree to compress transmitted frames with Predictor-1 if requested. This option has no effect unless the kernel driver supports Predictor-1 compression. .TP +.B privgroup \fIgroup-name +Allows members of group \fIgroup-name\fR to use privileged options. +This is a privileged option. Use of this option requires care as +there is no guarantee that members of \fIgroup-name\fR cannot use pppd +to become root themselves. Consider it equivalent to putting the +members of \fIgroup-name\fR in the kmem or disk group. +.TP .B proxyarp Add an entry to this system's ARP [Address Resolution Protocol] table with the IP address of the peer and the Ethernet address of this @@ -661,8 +671,8 @@ must be between 2 and 16 (inclusive). .B welcome \fIscript Run the executable or shell command specified by \fIscript\fR before initiating PPP negotiation, after the connect script (if any) has -completed. This option is privileged if the \fInoauth\fR option is -used. +completed. A value for this option from a privileged source cannot be +overridden by a non-privileged user. .TP .B xonxoff Use software flow control (i.e. XON/XOFF) to control the flow of data on diff --git a/pppd/pppd.h b/pppd/pppd.h index 2388b78..405dcc7 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -16,7 +16,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: pppd.h,v 1.28 1999/03/08 05:34:45 paulus Exp $ + * $Id: pppd.h,v 1.29 1999/03/12 06:07:20 paulus Exp $ */ /* @@ -94,9 +94,14 @@ typedef struct { #define OPT_A2INFO 0x100000 /* addr2 -> option_info to update */ #define OPT_A2COPY 0x200000 /* addr2 -> second location to rcv value */ #define OPT_ENABLE 0x400000 /* use *addr2 as enable for option */ +#define OPT_PRIVFIX 0x800000 /* can't be overridden if noauth */ #define OPT_VAL(x) ((x) & OPT_VALUE) +#ifndef GIDSET_TYPE +#define GIDSET_TYPE gid_t +#endif + /* * Global variables. */ @@ -116,6 +121,8 @@ extern int privileged; /* We were run by real-uid root */ extern int need_holdoff; /* Need holdoff period after link terminates */ extern char **script_env; /* Environment variables for scripts */ extern int detached; /* Have detached from controlling tty */ +extern GIDSET_TYPE groups[NGROUPS_MAX]; /* groups the user is in */ +extern int ngroups; /* How many groups valid in groups */ /* * Variables set by command-line options. @@ -124,7 +131,7 @@ extern int detached; /* Have detached from controlling tty */ extern int debug; /* Debug flag */ extern int kdebugflag; /* Tell kernel to print debug messages */ extern int default_device; /* Using /dev/tty or equivalent */ -extern char devnam[]; /* Device name */ +extern char devnam[MAXPATHLEN]; /* Device name */ extern int crtscts; /* Use hardware flow control */ extern bool modem; /* Use modem control lines */ extern int inspeed; /* Input/Output speed requested */ @@ -136,19 +143,20 @@ extern char *connector; /* Script to establish physical link */ extern char *disconnector; /* Script to disestablish physical link */ extern char *welcomer; /* Script to welcome client after connection */ extern int maxconnect; /* Maximum connect time (seconds) */ -extern char user[]; /* Our name for authenticating ourselves */ -extern char passwd[]; /* Password for PAP */ +extern char user[MAXNAMELEN];/* Our name for authenticating ourselves */ +extern char passwd[MAXSECRETLEN]; /* Password for PAP */ extern bool auth_required; /* Peer is required to authenticate */ extern bool persist; /* Reopen link after it goes down */ extern bool uselogin; /* Use /etc/passwd for checking PAP */ -extern char our_name[]; /* Our name for authentication purposes */ -extern char remote_name[]; /* Peer's name for authentication */ +extern char our_name[MAXNAMELEN];/* Our name for authentication purposes */ +extern char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ extern int explicit_remote;/* remote_name specified with remotename opt */ extern bool demand; /* Do dial-on-demand */ extern char *ipparam; /* Extra parameter for ip up/down scripts */ extern bool cryptpap; /* Others' PAP passwords are encrypted */ extern int idle_time_limit;/* Shut down link if idle for this long */ extern int holdoff; /* Dead time before restarting */ + #ifdef PPP_FILTER extern struct bpf_program pass_filter; /* Filter for pkts to pass */ extern struct bpf_program active_filter; /* Filter for link-active pkts */ @@ -240,11 +248,19 @@ void log_packet __P((u_char *, int, char *, int)); /* Format a packet and log it with syslog */ void print_string __P((char *, int, void (*) (void *, char *, ...), void *)); /* Format a string for output */ -int fmtmsg __P((char *, int, char *, ...)); /* sprintf++ */ -int vfmtmsg __P((char *, int, char *, va_list)); /* vsprintf++ */ +int slprintf __P((char *, int, char *, ...)); /* sprintf++ */ +int vslprintf __P((char *, int, char *, va_list)); /* vsprintf++ */ void script_setenv __P((char *, char *)); /* set script env var */ void script_unsetenv __P((char *)); /* unset script env var */ void hangup_modem __P((int)); /* Make modem hang up */ +void strlcpy __P((char *, size_t, const char *)); /* safe strcpy */ +void strlcat __P((char *, size_t, const char *)); /* safe strncpy */ +void dbglog __P((char *, ...)); /* log a debug message */ +void info __P((char *, ...)); /* log an informational message */ +void notice __P((char *, ...)); /* log a notice-level message */ +void warn __P((char *, ...)); /* log a warning message */ +void error __P((char *, ...)); /* log an error message */ +void fatal __P((char *, ...)); /* log an error message and die(1) */ /* Procedures exported from auth.c */ void link_required __P((int)); /* we are starting to use the link */ @@ -449,7 +465,7 @@ extern struct option_info welcomer_info; #define BZERO(s, n) memset(s, 0, n) #define EXIT(u) quit() -#define PRINTMSG(m, l) { m[l] = '\0'; syslog(LOG_INFO, "Remote message: %s", m); } +#define PRINTMSG(m, l) { info("Remote message: %0.*v", l, m); } /* * MAKEHEADER - Add Header fields to a packet. diff --git a/pppd/sys-NeXT.c b/pppd/sys-NeXT.c index b42e0d1..6ec682f 100644 --- a/pppd/sys-NeXT.c +++ b/pppd/sys-NeXT.c @@ -20,7 +20,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-NeXT.c,v 1.11 1999/03/08 01:46:19 paulus Exp $"; +static char rcsid[] = "$Id: sys-NeXT.c,v 1.12 1999/03/12 06:07:20 paulus Exp $"; #endif #include @@ -126,7 +126,7 @@ sys_cleanup() struct ifreq ifr; if (if_is_up) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 && ((ifr.ifr_flags & IFF_UP) != 0)) { ifr.ifr_flags &= ~IFF_UP; @@ -170,7 +170,7 @@ ppp_available() if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return 1; /* can't tell - maybe we're not root */ - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; close(s); @@ -602,7 +602,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) u_int x; struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); ifr.ifr_mtu = mtu; if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); @@ -768,7 +768,7 @@ sifup(u) u_int x; struct npioctl npi; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); return 0; @@ -819,7 +819,7 @@ sifdown(u) /* ignore errors, because ttyfd might have been closed by now. */ - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); rv = 0; @@ -854,7 +854,7 @@ sifaddr(u, o, h, m) struct ifreq ifr; ret = 1; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if (ioctl(sockfd, SIOCSIFADDR, (caddr_t) &ifr) < 0) { @@ -1043,7 +1043,7 @@ get_ether_addr(ipaddr, hwaddr) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); /* * Check that the interface is up, and not point-to-point * or loopback. @@ -1105,7 +1105,7 @@ ether_by_host(hostname, etherptr) * find the address in the * top domain of netinfo. */ - strcat(strcpy(path, "/machines/"), hostname); + slprintf(path, sizeof(path), "/machines/%s", hostname); if (ni_open((void *)0, "/", &conn) || ni_root(conn, &root) @@ -1116,7 +1116,7 @@ ether_by_host(hostname, etherptr) /* * Now we can convert the returned string into an ethernet address. */ - strcpy(path, val.ni_namelist_val[0]); + strlcpy(path, sizeof(path), val.ni_namelist_val[0]); ni_free(conn); if ((thisptr = (struct ether_addr*)ether_aton(path)) == NULL) return 1; @@ -1176,7 +1176,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1272,9 +1272,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1298,13 +1298,15 @@ lock(dev) { int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST diff --git a/pppd/sys-aix4.c b/pppd/sys-aix4.c index e03c407..9fcd101 100644 --- a/pppd/sys-aix4.c +++ b/pppd/sys-aix4.c @@ -21,7 +21,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-aix4.c,v 1.14 1999/03/08 01:46:19 paulus Exp $"; +static char rcsid[] = "$Id: sys-aix4.c,v 1.15 1999/03/12 06:07:21 paulus Exp $"; #endif /* @@ -108,7 +108,7 @@ sys_cleanup() struct ifreq ifr; if (if_is_up) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 && ((ifr.ifr_flags & IFF_UP) != 0)) { ifr.ifr_flags &= ~IFF_UP; @@ -644,7 +644,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) int c; struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); ifr.ifr_mtu = mtu; if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); @@ -793,7 +793,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); return 0; @@ -845,7 +845,7 @@ sifdown(u) ioctl(ttyfd, SIOCSETNPMODE, &npi); /* ignore errors, because ttyfd might have been closed by now. */ - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); rv = 0; @@ -879,7 +879,7 @@ sifaddr(u, o, h, m) struct ifreq ifr; ret = 1; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); if (m != 0) { syslog(LOG_INFO, "Setting interface mask to %s\n", ip_ntoa(m)); @@ -1247,7 +1247,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1277,9 +1277,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); diff --git a/pppd/sys-bsd.c b/pppd/sys-bsd.c index e4becf5..c2475a1 100644 --- a/pppd/sys-bsd.c +++ b/pppd/sys-bsd.c @@ -21,7 +21,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-bsd.c,v 1.35 1999/03/08 01:46:21 paulus Exp $"; +static char rcsid[] = "$Id: sys-bsd.c,v 1.36 1999/03/12 06:07:21 paulus Exp $"; /* $NetBSD: sys-bsd.c,v 1.1.1.3 1997/09/26 18:53:04 christos Exp $ */ #endif @@ -128,7 +128,7 @@ sys_cleanup() struct ifreq ifr; if (if_is_up) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 && ((ifr.ifr_flags & IFF_UP) != 0)) { ifr.ifr_flags &= ~IFF_UP; @@ -185,7 +185,7 @@ ppp_available() if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return 1; /* can't tell */ - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; close(s); @@ -688,7 +688,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) u_int x; struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); ifr.ifr_mtu = mtu; if (ioctl(sockfd, SIOCSIFMTU, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl(SIOCSIFMTU): %m"); @@ -888,7 +888,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); return 0; @@ -939,7 +939,7 @@ sifdown(u) ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); /* ignore errors, because ppp_fd might have been closed by now. */ - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); rv = 0; @@ -974,7 +974,7 @@ sifaddr(u, o, h, m) struct ifaliasreq ifra; struct ifreq ifr; - strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); + strlcpy(ifra.ifra_name, sizeof(ifra.ifra_name), ifname); SET_SA_FAMILY(ifra.ifra_addr, AF_INET); ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); @@ -985,7 +985,7 @@ sifaddr(u, o, h, m) } else BZERO(&ifra.ifra_mask, sizeof(ifra.ifra_mask)); BZERO(&ifr, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCDIFADDR, (caddr_t) &ifr) < 0) { if (errno != EADDRNOTAVAIL) syslog(LOG_WARNING, "Couldn't remove interface address: %m"); @@ -1016,7 +1016,7 @@ cifaddr(u, o, h) struct ifaliasreq ifra; ifaddrs[0] = 0; - strncpy(ifra.ifra_name, ifname, sizeof(ifra.ifra_name)); + strlcpy(ifra.ifra_name, sizeof(ifra.ifra_name), ifname); SET_SA_FAMILY(ifra.ifra_addr, AF_INET); ((struct sockaddr_in *) &ifra.ifra_addr)->sin_addr.s_addr = o; SET_SA_FAMILY(ifra.ifra_broadaddr, AF_INET); @@ -1294,7 +1294,7 @@ get_ether_addr(ipaddr, hwaddr) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len)) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); /* * Check that the interface is up, and not point-to-point * or loopback. @@ -1393,7 +1393,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1442,13 +1442,15 @@ lock(dev) char hdb_lock_buffer[12]; int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 7514063..900e9af 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -953,7 +953,7 @@ void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp) * Set the MTU and other parameters for the ppp device */ memset (&ifr, '\0', sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); ifr.ifr_mtu = mtu; if (ioctl(sock_fd, SIOCSIFMTU, (caddr_t) &ifr) < 0) @@ -1130,7 +1130,7 @@ static int path_to_procfs (void) fp = fopen(MOUNTED, "r"); if (fp == NULL) { /* Default the mount location of /proc */ - strncpy (route_buffer, "/proc", sizeof (route_buffer)-10); + strlcpy (route_buffer, sizeof (route_buffer), "/proc"); return 1; } @@ -1144,8 +1144,7 @@ static int path_to_procfs (void) if (mntent == 0) return 0; - strncpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer)-10); - route_buffer [sizeof (route_buffer)-10] = '\0'; + strlcpy(route_buffer, sizeof (route_buffer), mntent->mnt_dir); return 1; } @@ -1160,7 +1159,7 @@ static char *path_to_route (void) syslog (LOG_ERR, "proc file system not mounted"); return 0; } - strcat (route_buffer, "/net/route"); + strlcat (route_buffer, sizeof(route_buffer), "/net/route"); return (route_buffer); } @@ -1523,7 +1522,7 @@ static int get_ether_addr (u_int32_t ipaddr, if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); SYSDEBUG ((LOG_DEBUG, "proxy arp: examining interface %s", ifreq.ifr_name)); /* @@ -1662,7 +1661,7 @@ u_int32_t GetMask (u_int32_t addr) /* * Check that the interface is up, and not point-to-point nor loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sock_fd, SIOCGIFFLAGS, &ifreq) < 0) { continue; @@ -1796,7 +1795,7 @@ int ppp_available(void) return 0; } - strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; /* * If the device did not exist then attempt to create one by putting the @@ -1807,7 +1806,7 @@ int ppp_available(void) { if (ppp_registered()) { - strncpy (ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; } } @@ -1925,11 +1924,11 @@ void logwtmp (const char *line, const char *name, const char *host) if (ut.ut_id[0] == 0) { - strncpy(ut.ut_id, line + 3, sizeof(ut.ut_id)); + strlcpy(ut.ut_id, sizeof(ut.ut_id), line + 3); } - strncpy(ut.ut_user, name, sizeof(ut.ut_user)); - strncpy(ut.ut_line, line, sizeof(ut.ut_line)); + strlcpy(ut.ut_user, sizeof(ut.ut_user), name); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); time(&ut.ut_time); @@ -1939,7 +1938,7 @@ void logwtmp (const char *line, const char *name, const char *host) /* Insert the host name if one is supplied */ if (*host) { - strncpy (ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy (ut.ut_host, sizeof(ut.ut_host), host); } /* Insert the IP address of the remote system if IP is enabled */ @@ -1983,63 +1982,52 @@ void logwtmp (const char *line, const char *name, const char *host) */ int lock (char *dev) - { +{ #ifdef LOCKLIB int result; - lock_file = malloc(strlen(dev) + 1); + lock_file = strdup(dev); if (lock_file == NULL) - { novm("lock file name"); - } - strcpy (lock_file, dev); result = mklock (dev, (void *) 0); - if (result > 0) - { + if (result > 0) { syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, result); free (lock_file); lock_file = NULL; result = -1; - } - else - { - if (result < 0) - { + } + else { + if (result < 0) { syslog (LOG_ERR, "Can't create lock file %s", lock_file); free (lock_file); lock_file = NULL; result = -1; - } - } + } + } return (result); #else char hdb_lock_buffer[12]; int fd, n; int pid = getpid(); char *p; + size_t l; p = strrchr(dev, '/'); if (p != NULL) - { dev = ++p; - } - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) - { novm("lock file name"); - } - strcpy (lock_file, LOCK_PREFIX); - strcat (lock_file, dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); /* * Attempt to create the lock file at this point. */ - while (1) - { + while (1) { fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644); - if (fd >= 0) - { + if (fd >= 0) { pid = getpid(); #ifndef PID_BINARY sprintf (hdb_lock_buffer, "%010d\n", pid); @@ -2049,34 +2037,28 @@ int lock (char *dev) #endif close(fd); return 0; - } + } /* * If the file exists then check to see if the pid is stale */ - if (errno == EEXIST) - { + if (errno == EEXIST) { fd = open(lock_file, O_RDONLY, 0); - if (fd < 0) - { + if (fd < 0) { if (errno == ENOENT) /* This is just a timing problem. */ - { continue; - } break; - } + } /* Read the lock file to find out who has the device locked */ n = read (fd, hdb_lock_buffer, 11); close (fd); - if (n < 0) - { + if (n < 0) { syslog(LOG_ERR, "Can't read pid from lock file %s", lock_file); break; - } + } /* See the process still exists. */ - if (n > 0) - { + if (n > 0) { #ifndef PID_BINARY hdb_lock_buffer[n] = '\0'; sscanf (hdb_lock_buffer, " %d", &pid); @@ -2085,26 +2067,23 @@ int lock (char *dev) #endif if (pid == 0 || pid == getpid() || (kill(pid, 0) == -1 && errno == ESRCH)) - { n = 0; - } - } + } /* If the process does not exist then try to remove the lock */ - if (n == 0 && unlink (lock_file) == 0) - { + if (n == 0 && unlink (lock_file) == 0) { syslog (LOG_NOTICE, "Removed stale lock on %s (pid %d)", dev, pid); continue; - } + } syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, pid); break; - } + } syslog(LOG_ERR, "Can't create lock file %s: %m(%d)", lock_file, errno); break; - } + } free(lock_file); lock_file = NULL; @@ -2170,7 +2149,7 @@ int sifup (int u) struct ifreq ifr; memset (&ifr, '\0', sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) @@ -2205,7 +2184,7 @@ int sifdown (int u) if_is_up = 0; memset (&ifr, '\0', sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sock_fd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { if (! ok_error (errno)) @@ -2246,7 +2225,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, SET_SA_FAMILY (ifr.ifr_dstaddr, AF_INET); SET_SA_FAMILY (ifr.ifr_netmask, AF_INET); - strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy (ifr.ifr_name, sizeof (ifr.ifr_name), ifname); /* * Set our IP address */ @@ -2523,7 +2502,7 @@ int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) else { memset (&ifr, '\0', sizeof (ifr)); - strcpy (ifr.ifr_name, ifname); + strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname); memcpy (sipx->sipx_node, node, IPX_NODE_LEN); sipx->sipx_family = AF_IPX; @@ -2585,7 +2564,7 @@ int cipxfaddr (int unit) else { memset (&ifr, '\0', sizeof (ifr)); - strcpy (ifr.ifr_name, ifname); + strlcpy (ifr.ifr_name, sizeof(ifr.ifr_name), ifname); sipx->sipx_type = IPX_FRAME_ETHERII; sipx->sipx_action = IPX_DLTITF; @@ -2665,7 +2644,7 @@ sys_check_options(void) { if (path_to_procfs()) { - strcat (route_buffer, "/net/ipx_interface"); + strlcat (route_buffer, sizeof(route_buffer), "/net/ipx_interface"); if (lstat (route_buffer, &stat_buf) >= 0) { break; diff --git a/pppd/sys-osf.c b/pppd/sys-osf.c index c748720..cba5e35 100644 --- a/pppd/sys-osf.c +++ b/pppd/sys-osf.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-osf.c,v 1.17 1999/03/10 03:07:48 paulus Exp $"; +static char rcsid[] = "$Id: sys-osf.c,v 1.18 1999/03/12 06:07:22 paulus Exp $"; #endif #include @@ -1077,7 +1077,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface up (get): %m"); return 0; @@ -1100,7 +1100,7 @@ sifdown(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface down (get): %m"); return 0; @@ -1163,7 +1163,7 @@ sifaddr(u, o, h, m) /* flush old address, if any */ bzero(&ifr, sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if ((ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) @@ -1173,7 +1173,7 @@ sifaddr(u, o, h, m) } bzero(&addreq, sizeof (addreq)); - strncpy(addreq.ifra_name, ifname, sizeof (addreq.ifra_name)); + strlcpy(addreq.ifra_name, sizeof (addreq.ifra_name), ifname); SET_SA_FAMILY(addreq.ifra_addr, AF_INET); SET_SA_FAMILY(addreq.ifra_broadaddr, AF_INET); ((struct sockaddr_in *)&addreq.ifra_addr)->sin_addr.s_addr = o; @@ -1218,7 +1218,7 @@ cifaddr(u, o, h) ifaddrs[0] = 0; ifaddrs[1] = 0; bzero(&ifr, sizeof (ifr)); - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = o; if (ioctl(sockfd, (int)SIOCDIFADDR, (caddr_t) &ifr) < 0) { @@ -1368,7 +1368,7 @@ get_ether_addr(ipaddr, hwaddr) * Check that the interface is up, and not point-to-point * or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1397,7 +1397,7 @@ get_ether_addr(ipaddr, hwaddr) return 0; syslog(LOG_INFO, "found interface %s for proxy arp", ifr->ifr_name); - strncpy(ifdevreq.ifr_name, ifr->ifr_name, sizeof(ifdevreq.ifr_name)); + strlcpy(ifdevreq.ifr_name, sizeof(ifdevreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, (int)SIOCRPHYSADDR, &ifdevreq) < 0) { perror("ioctl(SIOCRPHYSADDR)"); @@ -1422,9 +1422,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1481,7 +1481,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1626,13 +1626,15 @@ lock(dev) char hdb_lock_buffer[12]; int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST diff --git a/pppd/sys-sunos4.c b/pppd/sys-sunos4.c index 75bc29f..9e84b7e 100644 --- a/pppd/sys-sunos4.c +++ b/pppd/sys-sunos4.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-sunos4.c,v 1.12 1999/03/08 05:34:46 paulus Exp $"; +static char rcsid[] = "$Id: sys-sunos4.c,v 1.13 1999/03/12 06:07:23 paulus Exp $"; #endif #include @@ -758,7 +758,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) /* set mtu for ip as well */ memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); ifr.ifr_metric = link_mtu; if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP MTU: %m"); @@ -909,7 +909,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface up (get): %m"); return 0; @@ -932,7 +932,7 @@ sifdown(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface down (get): %m"); return 0; @@ -981,7 +981,7 @@ sifaddr(u, o, h, m) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = m; if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { @@ -1170,7 +1170,7 @@ get_ether_addr(ipaddr, hwaddr) * Check that the interface is up, and not point-to-point * or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1203,7 +1203,7 @@ get_ether_addr(ipaddr, hwaddr) syslog(LOG_ERR, "Couldn't open /dev/nit: %m"); return 0; } - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(nit_fd, NIOCBIND, &ifreq) < 0 || ioctl(nit_fd, SIOCGIFADDR, &ifreq) < 0) { syslog(LOG_ERR, "Couldn't get hardware address for %s: %m", @@ -1243,9 +1243,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1303,7 +1303,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1378,13 +1378,15 @@ lock(dev) char hdb_lock_buffer[12]; int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s", LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST diff --git a/pppd/sys-svr4.c b/pppd/sys-svr4.c index d525064..4173e4d 100644 --- a/pppd/sys-svr4.c +++ b/pppd/sys-svr4.c @@ -26,7 +26,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-svr4.c,v 1.23 1999/03/08 05:34:46 paulus Exp $"; +static char rcsid[] = "$Id: sys-svr4.c,v 1.24 1999/03/12 06:07:23 paulus Exp $"; #endif #include @@ -824,7 +824,7 @@ ppp_send_config(unit, mtu, asyncmap, pcomp, accomp) /* set the MTU for IP as well */ memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); ifr.ifr_metric = link_mtu; if (ioctl(ipfd, SIOCSIFMTU, &ifr) < 0) { syslog(LOG_ERR, "Couldn't set IP MTU: %m"); @@ -1006,7 +1006,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface up (get): %m"); return 0; @@ -1031,7 +1031,7 @@ sifdown(u) if (ipmuxid < 0) return 1; - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(ipfd, SIOCGIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "Couldn't mark interface down (get): %m"); return 0; @@ -1079,7 +1079,7 @@ sifaddr(u, o, h, m) int ret = 1; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); ifr.ifr_addr.sa_family = AF_INET; INET_ADDR(ifr.ifr_addr) = m; if (ioctl(ipfd, SIOCSIFNETMASK, &ifr) < 0) { @@ -1291,7 +1291,7 @@ get_ether_addr(ipaddr, hwaddr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & @@ -1367,12 +1367,12 @@ get_hw_addr(name, ina, hwaddr) * We have to open the device and ask it for its hardware address. * First split apart the device name and unit. */ - strcpy(ifdev, "/dev/"); - q = ifdev + 5; /* strlen("/dev/") */ - while (*name != 0 && !isdigit(*name)) - *q++ = *name++; - *q = 0; - unit = atoi(name); + slprintf(ifdev, sizeof(ifdev), "/dev/%s", name); + for (q = ifdev + strlen(ifdev); --q >= ifdev; ) + if (!isdigit(*q)) + break; + unit = atoi(q+1); + q[1] = 0; /* * Open the device and do a DLPI attach and phys_addr_req. @@ -1540,7 +1540,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1569,9 +1569,9 @@ logwtmp(line, name, host) if (name[0] != 0) { /* logging in */ - strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user)); - strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id)); - strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line)); + strlcpy(utmpx.ut_user, sizeof(utmpx.ut_user), name); + strlcpy(utmpx.ut_id, sizeof(utmpx.ut_id), ifname); + strlcpy(utmpx.ut_line, sizeof(utmpx.ut_line), line); utmpx.ut_pid = getpid(); utmpx.ut_type = USER_PROCESS; } else { diff --git a/pppd/sys-ultrix.c b/pppd/sys-ultrix.c index cb1303b..92d3bd2 100644 --- a/pppd/sys-ultrix.c +++ b/pppd/sys-ultrix.c @@ -21,7 +21,7 @@ */ #ifndef lint -static char rcsid[] = "$Id: sys-ultrix.c,v 1.24 1999/03/08 01:46:24 paulus Exp $"; +static char rcsid[] = "$Id: sys-ultrix.c,v 1.25 1999/03/12 06:07:24 paulus Exp $"; #endif /* @@ -106,7 +106,7 @@ sys_cleanup() struct ifreq ifr; if (if_is_up) { - strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof(ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) >= 0 && ((ifr.ifr_flags & IFF_UP) != 0)) { ifr.ifr_flags &= ~IFF_UP; @@ -186,7 +186,7 @@ ppp_available() if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) return 1; /* can't tell */ - strncpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), "ppp0"); ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0; close(s); @@ -840,7 +840,7 @@ sifup(u) { struct ifreq ifr; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); return 0; @@ -891,7 +891,7 @@ sifdown(u) ioctl(ppp_fd, PPPIOCSNPMODE, (caddr_t) &npi); /* ignore errors, because ppp_fd might have been closed by now. */ - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); if (ioctl(sockfd, SIOCGIFFLAGS, (caddr_t) &ifr) < 0) { syslog(LOG_ERR, "ioctl (SIOCGIFFLAGS): %m"); rv = 0; @@ -926,7 +926,7 @@ sifaddr(u, o, h, m) struct ifreq ifr; ret = 1; - strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); + strlcpy(ifr.ifr_name, sizeof (ifr.ifr_name), ifname); SET_SA_FAMILY(ifr.ifr_addr, AF_INET); if (m != 0) { ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = m; @@ -1108,7 +1108,7 @@ get_ether_addr(ipaddr, hwaddr) ((char *)&ifr->ifr_addr + sizeof(struct sockaddr))) { if (ifr->ifr_addr.sa_family == AF_INET) { ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr; - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); /* * Check that the interface is up, and not point-to-point * or loopback. @@ -1139,7 +1139,7 @@ get_ether_addr(ipaddr, hwaddr) /* * Grab the physical address for this interface. */ - strncpy(ifdevea.ifr_name, ifr->ifr_name, sizeof(ifdevea.ifr_name)); + strlcpy(ifdevea.ifr_name, sizeof(ifdevea.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCRPHYSADDR, &ifdevea) < 0) { syslog(LOG_ERR, "Couldn't get h/w address for %s: %m", ifr->ifr_name); return 0; @@ -1200,7 +1200,7 @@ GetMask(addr) /* * Check that the interface is up, and not point-to-point or loopback. */ - strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); + strlcpy(ifreq.ifr_name, sizeof(ifreq.ifr_name), ifr->ifr_name); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) continue; if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK)) @@ -1286,9 +1286,9 @@ logwtmp(line, name, host) if ((fd = open(WTMPFILE, O_WRONLY|O_APPEND, 0)) < 0) return; if (!fstat(fd, &buf)) { - (void)strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - (void)strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - (void)strncpy(ut.ut_host, host, sizeof(ut.ut_host)); + strlcpy(ut.ut_line, sizeof(ut.ut_line), line); + strlcpy(ut.ut_name, sizeof(ut.ut_name), name); + strlcpy(ut.ut_host, sizeof(ut.ut_host), host); (void)time(&ut.ut_time); if (write(fd, (char *)&ut, sizeof(struct utmp)) != sizeof(struct utmp)) (void)ftruncate(fd, buf.st_size); @@ -1312,13 +1312,15 @@ lock(dev) { int fd, pid, n; char *p; + size_t l; if ((p = strrchr(dev, '/')) != NULL) dev = p + 1; - lock_file = malloc(strlen(LOCK_PREFIX) + strlen(dev) + 1); + l = strlen(LOCK_PREFIX) + strlen(dev) + 1; + lock_file = malloc(l); if (lock_file == NULL) novm("lock file name"); - strcat(strcpy(lock_file, LOCK_PREFIX), dev); + slprintf(lock_file, l, "%s%s, LOCK_PREFIX, dev); while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { if (errno == EEXIST -- 2.39.2