Date: Sat, 15 Sep 2001 23:31:25 -0400 (EDT) From: "Andrew R. Reiter" <arr@watson.org> To: freebsd-audit@freebsd.org Subject: sliplogin patches Message-ID: <Pine.NEB.3.96L.1010915232244.41506A-300000@fledge.watson.org>
index | next in thread | raw e-mail
[-- Attachment #1 --]
Hey,
I was looking at sliplogin() and noticed that the signal handler usage was
kinda poor (bad functions in hup_handler()). So I wanted to make patches
for it. After getting style 9'd (kinda like slashdotted, but you get
beaten up for not fully style(9)'ing something prepatch), i decided to
write the style(9) patch for good measure; hopefully it's good :-). So,
sliplogin.c.style-diff is the style(9) patch.
the security patch is sliplogin.c.sec-diff. this patch fixes the signal
race problem in the essence of the kkenn fix in syslogd (mark the signal,
check if it's been marked and execute -- to put it very pseudo-like).
also, I fixed probably some unnecesary things but thought it should be
done for "good measure" -- those are:
- moving strncpy() + buf[sizeof-1] = '\0' -> strlcpy()
- remove sizeof(blah) - 1 in fgets() where there _shouldn't_ be a
-1 (man 3 fgets).
anyway, like usual, comments are appreciated and probably needed (slowly
becomming style(9)-ful).
cheers,
Andrew
btw -- patches can also be seen at:
http://www.watson.org/~arr/fbsd-audit/usr.sbin/sliplogin/
*-------------.................................................
| Andrew R. Reiter
| arr@fledge.watson.org
| "It requires a very unusual mind
| to undertake the analysis of the obvious" -- A.N. Whitehead
[-- Attachment #2 --]
--- sliplogin.c.orig Sat Sep 15 20:46:44 2001
+++ sliplogin.c.1 Sat Sep 15 21:21:22 2001
@@ -97,6 +97,17 @@
NULL
};
+struct slip_modes {
+ char *sm_name;
+ int sm_or_flag;
+ int sm_and_flag;
+} modes[] = {
+ {"normal", 0, 0},
+ {"compress", IFF_LINK0, IFF_LINK2},
+ {"noicmp", IFF_LINK1, 0},
+ {"autocomp", IFF_LINK2, IFF_LINK0}
+};
+
int unit;
int slip_mode;
speed_t speed;
@@ -107,8 +118,8 @@
char loginargs[BUFSIZ];
char loginfile[MAXPATHLEN];
char loginname[BUFSIZ];
-static char raddr[32]; /* remote address */
-char ifname[IFNAMSIZ]; /* interface name */
+char ifname[IFNAMSIZ]; /* interface name */
+static char raddr[32]; /* remote address */
static char pidfilename[MAXPATHLEN]; /* name of pid file */
static char iffilename[MAXPATHLEN]; /* name of if file */
static pid_t pid; /* our pid */
@@ -116,34 +127,22 @@
char *
make_ipaddr(void)
{
-static char address[20] ="";
-struct hostent *he;
-unsigned long ipaddr;
-
-address[0] = '\0';
-if ((he = gethostbyname(raddr)) != NULL) {
- ipaddr = ntohl(*(long *)he->h_addr_list[0]);
- sprintf(address, "%lu.%lu.%lu.%lu",
- ipaddr >> 24,
- (ipaddr & 0x00ff0000) >> 16,
- (ipaddr & 0x0000ff00) >> 8,
- (ipaddr & 0x000000ff));
+ static char address[20] ="";
+ struct hostent *he;
+ unsigned long ipaddr;
+
+ address[0] = '\0';
+ if ((he = gethostbyname(raddr)) != NULL) {
+ ipaddr = ntohl(*(long *)he->h_addr_list[0]);
+ sprintf(address, "%lu.%lu.%lu.%lu",
+ ipaddr >> 24,
+ (ipaddr & 0x00ff0000) >> 16,
+ (ipaddr & 0x0000ff00) >> 8,
+ (ipaddr & 0x000000ff));
}
-
-return address;
+ return address;
}
-struct slip_modes {
- char *sm_name;
- int sm_or_flag;
- int sm_and_flag;
-} modes[] = {
- "normal", 0 , 0 ,
- "compress", IFF_LINK0, IFF_LINK2,
- "noicmp", IFF_LINK1, 0 ,
- "autocomp", IFF_LINK2, IFF_LINK0,
-};
-
void
findid(name)
char *name;
@@ -172,9 +171,11 @@
goto accfile_err;
if (loginargs[0] == '#' || isspace(loginargs[0]))
continue;
- n = sscanf(loginargs, "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
- user, laddr, raddr, mask, slopt[0], slopt[1],
- slopt[2], slopt[3], slopt[4]);
+ n = sscanf(loginargs,
+ "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]"
+ "%15s%*[ \t]%15s%*[ \t]%15s%*[ \t]%15s\n",
+ user, laddr, raddr, mask, slopt[0], slopt[1],
+ slopt[2], slopt[3], slopt[4]);
if (n < 4) {
syslog(LOG_ERR, "%s: wrong format\n", _PATH_ACCESS);
exit(1);
@@ -182,12 +183,12 @@
if (strcmp(user, name) != 0)
continue;
- (void) fclose(fp);
+ (void)fclose(fp);
slip_mode = 0;
for (i = 0; i < n - 4; i++) {
- for (j = 0; j < sizeof(modes)/sizeof(struct slip_modes);
- j++) {
+ for (j = 0;
+ j < sizeof(modes)/sizeof(struct slip_modes); j++) {
if (strcmp(modes[j].sm_name, slopt[i]) == 0) {
slip_mode |= (modes[j].sm_or_flag);
slip_mode &= ~(modes[j].sm_and_flag);
@@ -202,9 +203,11 @@
* one specific to this host. If none found, try for
* a generic one.
*/
- (void)snprintf(loginfile, sizeof(loginfile), "%s.%s", _PATH_LOGIN, name);
+ (void)snprintf(loginfile, sizeof(loginfile),
+ "%s.%s", _PATH_LOGIN, name);
if (access(loginfile, R_OK|X_OK) != 0) {
- (void)strncpy(loginfile, _PATH_LOGIN, sizeof(loginfile)-1);
+ (void)strncpy(loginfile, _PATH_LOGIN,
+ sizeof(loginfile)-1);
loginfile[sizeof(loginfile)-1] = '\0';
if (access(loginfile, R_OK|X_OK)) {
syslog(LOG_ERR,
@@ -213,9 +216,11 @@
exit(5);
}
}
- (void)snprintf(slparmsfile, sizeof(slparmsfile), "%s.%s", _PATH_SLPARMS, name);
+ (void)snprintf(slparmsfile, sizeof(slparmsfile),
+ "%s.%s", _PATH_SLPARMS, name);
if (access(slparmsfile, R_OK|X_OK) != 0) {
- (void)strncpy(slparmsfile, _PATH_SLPARMS, sizeof(slparmsfile)-1);
+ (void)strncpy(slparmsfile, _PATH_SLPARMS,
+ sizeof(slparmsfile)-1);
slparmsfile[sizeof(slparmsfile)-1] = '\0';
if (access(slparmsfile, R_OK|X_OK))
*slparmsfile = '\0';
@@ -234,19 +239,20 @@
goto slfile_err;
if (buf[0] == '#' || isspace(buf[0]))
continue;
- n = sscanf(buf, "%d %d %d", &keepal, &outfill, &slunit);
+ n = sscanf(buf, "%d %d %d",
+ &keepal, &outfill, &slunit);
if (n < 1) {
slwrong_fmt:
- syslog(LOG_ERR, "%s: wrong format\n", slparmsfile);
+ syslog(LOG_ERR, "%s: wrong format\n",
+ slparmsfile);
exit(1);
}
- (void) fclose(fp);
+ (void)fclose(fp);
break;
}
if (n == 0)
goto slwrong_fmt;
}
-
return;
}
syslog(LOG_ERR, "SLIP access denied for %s\n", name);
@@ -304,22 +310,23 @@
int s;
{
char logoutfile[MAXPATHLEN];
+ char logincmd[2*MAXPATHLEN+32];
- (void) close(0);
+ (void)close(0);
seteuid(0);
- (void)snprintf(logoutfile, sizeof(logoutfile), "%s.%s", _PATH_LOGOUT, loginname);
+ (void)snprintf(logoutfile, sizeof(logoutfile),
+ "%s.%s", _PATH_LOGOUT, loginname);
if (access(logoutfile, R_OK|X_OK) != 0) {
(void)strncpy(logoutfile, _PATH_LOGOUT, sizeof(logoutfile)-1);
logoutfile[sizeof(logoutfile)-1] = '\0';
}
if (access(logoutfile, R_OK|X_OK) == 0) {
- char logincmd[2*MAXPATHLEN+32];
-
- (void) snprintf(logincmd, sizeof(logincmd), "%s %d %ld %s", logoutfile, unit, speed, loginargs);
- (void) system(logincmd);
+ (void)snprintf(logincmd, sizeof(logincmd),
+ "%s %d %u %s", logoutfile, unit, speed, loginargs);
+ (void)system(logincmd);
}
- syslog(LOG_INFO, "closed %s slip unit %d (%s)\n", loginname, unit,
- sigstr(s));
+ syslog(LOG_INFO, "closed %s slip unit %d (%s)\n",
+ loginname, unit, sigstr(s));
if (unlink(pidfilename) < 0 && errno != ENOENT)
syslog(LOG_WARNING, "unable to delete pid file: %m");
if (unlink(iffilename) < 0 && errno != ENOENT)
@@ -328,9 +335,9 @@
/* NOTREACHED */
}
-
/* Modify the slip line mode and add any compression or no-icmp flags. */
-void line_flags(unit)
+void
+line_flags(unit)
int unit;
{
struct ifreq ifr;
@@ -361,7 +368,7 @@
close(s);
}
-
+int
main(argc, argv)
int argc;
char *argv[];
@@ -382,7 +389,7 @@
name = argv[0];
s = getdtablesize();
for (fd = 3 ; fd < s ; fd++)
- (void) close(fd);
+ (void)close(fd);
openlog(name, LOG_PID|LOG_PERROR, LOG_DAEMON);
uid = getuid();
if (argc > 1) {
@@ -401,7 +408,7 @@
syslog(LOG_ERR, "open %s: %m", argv[2]);
exit(2);
}
- (void) dup2(fd, 0);
+ (void)dup2(fd, 0);
if (fd > 2)
close(fd);
}
@@ -420,11 +427,11 @@
}
findid(name);
}
- (void) fchmod(0, 0600);
- (void) fprintf(stderr, "starting slip login for %s\n", loginname);
- (void) fprintf(stderr, "your address is %s\n\n", make_ipaddr());
+ (void)fchmod(0, 0600);
+ (void)fprintf(stderr, "starting slip login for %s\n", loginname);
+ (void)fprintf(stderr, "your address is %s\n\n", make_ipaddr());
- (void) fflush(stderr);
+ (void)fflush(stderr);
sleep(1);
/* set up the line parameters */
@@ -454,8 +461,8 @@
syslog(LOG_ERR, "ioctl (SLIOCGUNIT): %m");
exit(1);
}
- (void) signal(SIGHUP, hup_handler);
- (void) signal(SIGTERM, hup_handler);
+ (void)signal(SIGHUP, hup_handler);
+ (void)signal(SIGTERM, hup_handler);
if (keepal > 0) {
(void) signal(SIGURG, hup_handler);
@@ -471,14 +478,14 @@
/* write pid to file */
pid = getpid();
- (void) sprintf(ifname, "sl%d", unit);
- (void) sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
+ (void)sprintf(ifname, "sl%d", unit);
+ (void)sprintf(pidfilename, "%s%s.pid", _PATH_VARRUN, ifname);
if ((pidfile = fopen(pidfilename, "w")) != NULL) {
fprintf(pidfile, "%d\n", pid);
- (void) fclose(pidfile);
+ (void)fclose(pidfile);
} else {
syslog(LOG_ERR, "Failed to create pid file %s: %m",
- pidfilename);
+ pidfilename);
pidfilename[0] = 0;
}
@@ -491,10 +498,10 @@
n++;
break;
}
- (void) sprintf(iffilename, "%s%s.if", _PATH_VARRUN, &devnam[n]);
+ (void)sprintf(iffilename, "%s%s.if", _PATH_VARRUN, &devnam[n]);
if ((iffile = fopen(iffilename, "w")) != NULL) {
fprintf(iffile, "sl%d\n", unit);
- (void) fclose(iffile);
+ (void)fclose(iffile);
} else {
syslog(LOG_ERR, "Failed to create if file %s: %m", iffilename);
iffilename[0] = 0;
@@ -502,32 +509,33 @@
syslog(LOG_INFO, "attaching slip unit %d for %s\n", unit, loginname);
- (void)snprintf(logincmd, sizeof(logincmd), "%s %d %ld %s", loginfile, unit, speed,
- loginargs);
+ (void)snprintf(logincmd, sizeof(logincmd), "%s %d %u %s",
+ loginfile, unit, speed, loginargs);
+
/*
* aim stdout and errout at /dev/null so logincmd output won't
* babble into the slip tty line.
*/
- (void) close(1);
+ (void)close(1);
if ((fd = open(_PATH_DEVNULL, O_WRONLY)) != 1) {
if (fd < 0) {
syslog(LOG_ERR, "open %s: %m", _PATH_DEVNULL);
exit(1);
}
- (void) dup2(fd, 1);
- (void) close(fd);
+ (void)dup2(fd, 1);
+ (void)close(fd);
}
- (void) dup2(1, 2);
+ (void)dup2(1, 2);
/*
* Run login and logout scripts as root (real and effective);
* current route(8) is setuid root, and checks the real uid
* to see whether changes are allowed (or just "route get").
*/
- (void) setuid(0);
- if (s = system(logincmd)) {
+ (void)setuid(0);
+ if ((s = system(logincmd)) != 0) {
syslog(LOG_ERR, "%s login failed: exit status %d from %s",
- loginname, s, loginfile);
+ loginname, s, loginfile);
exit(6);
}
@@ -539,6 +547,5 @@
/* twiddle thumbs until we get a signal */
while (1)
sigpause(0);
-
/* NOTREACHED */
}
[-- Attachment #3 --]
--- sliplogin.c.1 Sat Sep 15 21:21:22 2001
+++ sliplogin.c Sat Sep 15 22:19:16 2001
@@ -124,6 +124,8 @@
static char iffilename[MAXPATHLEN]; /* name of if file */
static pid_t pid; /* our pid */
+volatile sig_atomic_t sig_hup;
+
char *
make_ipaddr(void)
{
@@ -158,15 +160,14 @@
environ = restricted_environ; /* minimal protection for system() */
- (void)strncpy(loginname, name, sizeof(loginname)-1);
- loginname[sizeof(loginname)-1] = '\0';
+ (void)strlcpy(loginname, name, sizeof(loginname));
if ((fp = fopen(_PATH_ACCESS, "r")) == NULL) {
accfile_err:
syslog(LOG_ERR, "%s: %m\n", _PATH_ACCESS);
exit(1);
}
- while (fgets(loginargs, sizeof(loginargs) - 1, fp)) {
+ while (fgets(loginargs, sizeof(loginargs), fp)) {
if (ferror(fp))
goto accfile_err;
if (loginargs[0] == '#' || isspace(loginargs[0]))
@@ -206,9 +207,8 @@
(void)snprintf(loginfile, sizeof(loginfile),
"%s.%s", _PATH_LOGIN, name);
if (access(loginfile, R_OK|X_OK) != 0) {
- (void)strncpy(loginfile, _PATH_LOGIN,
- sizeof(loginfile)-1);
- loginfile[sizeof(loginfile)-1] = '\0';
+ (void)strlcpy(loginfile, _PATH_LOGIN,
+ sizeof(loginfile));
if (access(loginfile, R_OK|X_OK)) {
syslog(LOG_ERR,
"access denied for %s - no %s\n",
@@ -219,9 +219,8 @@
(void)snprintf(slparmsfile, sizeof(slparmsfile),
"%s.%s", _PATH_SLPARMS, name);
if (access(slparmsfile, R_OK|X_OK) != 0) {
- (void)strncpy(slparmsfile, _PATH_SLPARMS,
- sizeof(slparmsfile)-1);
- slparmsfile[sizeof(slparmsfile)-1] = '\0';
+ (void)strlcpy(slparmsfile, _PATH_SLPARMS,
+ sizeof(slparmsfile));
if (access(slparmsfile, R_OK|X_OK))
*slparmsfile = '\0';
}
@@ -234,7 +233,7 @@
exit(1);
}
n = 0;
- while (fgets(buf, sizeof(buf) - 1, fp) != NULL) {
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
if (ferror(fp))
goto slfile_err;
if (buf[0] == '#' || isspace(buf[0]))
@@ -306,20 +305,26 @@
}
void
+wanthup(s)
+ int s;
+{
+ sig_hup = s;
+}
+
+void
hup_handler(s)
int s;
{
char logoutfile[MAXPATHLEN];
char logincmd[2*MAXPATHLEN+32];
+ sig_hup = 0;
(void)close(0);
seteuid(0);
(void)snprintf(logoutfile, sizeof(logoutfile),
"%s.%s", _PATH_LOGOUT, loginname);
- if (access(logoutfile, R_OK|X_OK) != 0) {
- (void)strncpy(logoutfile, _PATH_LOGOUT, sizeof(logoutfile)-1);
- logoutfile[sizeof(logoutfile)-1] = '\0';
- }
+ if (access(logoutfile, R_OK|X_OK) != 0)
+ (void)strlcpy(logoutfile, _PATH_LOGOUT, sizeof(logoutfile));
if (access(logoutfile, R_OK|X_OK) == 0) {
(void)snprintf(logincmd, sizeof(logincmd),
"%s %d %u %s", logoutfile, unit, speed, loginargs);
@@ -461,11 +466,11 @@
syslog(LOG_ERR, "ioctl (SLIOCGUNIT): %m");
exit(1);
}
- (void)signal(SIGHUP, hup_handler);
- (void)signal(SIGTERM, hup_handler);
+ (void)signal(SIGHUP, wanthup);
+ (void)signal(SIGTERM, wanthup);
if (keepal > 0) {
- (void) signal(SIGURG, hup_handler);
+ (void)signal(SIGURG, wanthup);
if (ioctl(0, SLIOCSKEEPAL, &keepal) < 0) {
syslog(LOG_ERR, "ioctl(SLIOCSKEEPAL): %m");
exit(1);
@@ -545,7 +550,10 @@
/* reset uid to users' to allow the user to give a signal. */
seteuid(uid);
/* twiddle thumbs until we get a signal */
- while (1)
+ while (1) {
+ if (sig_hup)
+ hup_handler(sig_hup);
sigpause(0);
+ }
/* NOTREACHED */
}
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.NEB.3.96L.1010915232244.41506A-300000>
