Fix buffer overrun, and run as nobody
This commit is contained in:
parent
33f9fb3527
commit
01d5123979
@ -1,4 +1,4 @@
|
|||||||
# $Id: BSD.var.dist,v 1.23 1995/05/17 09:31:17 rgrimes Exp $
|
# $Id: BSD.var.dist,v 1.24 1995/11/19 16:50:34 ache Exp $
|
||||||
#
|
#
|
||||||
|
|
||||||
/set type=dir uname=bin gname=bin mode=0755
|
/set type=dir uname=bin gname=bin mode=0755
|
||||||
@ -40,7 +40,7 @@
|
|||||||
..
|
..
|
||||||
run uname=bin
|
run uname=bin
|
||||||
..
|
..
|
||||||
rwho uname=bin
|
rwho uname=bin gname=daemon mode=0775
|
||||||
..
|
..
|
||||||
/set type=dir uname=uucp gname=daemon mode=0755
|
/set type=dir uname=uucp gname=daemon mode=0755
|
||||||
spool uname=bin gname=bin
|
spool uname=bin gname=bin
|
||||||
|
@ -65,6 +65,7 @@ static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93";
|
|||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This version of Berkeley's rwhod has been modified to use IP multicast
|
* This version of Berkeley's rwhod has been modified to use IP multicast
|
||||||
@ -96,6 +97,9 @@ static char sccsid[] = "@(#)rwhod.c 8.1 (Berkeley) 6/6/93";
|
|||||||
* -- Steve Deering, Stanford University, February 1989
|
* -- Steve Deering, Stanford University, February 1989
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define UNPRIV_USER "nobody"
|
||||||
|
#define UNPRIV_GROUP "daemon"
|
||||||
|
|
||||||
#define NO_MULTICAST 0 /* multicast modes */
|
#define NO_MULTICAST 0 /* multicast modes */
|
||||||
#define PER_INTERFACE_MULTICAST 1
|
#define PER_INTERFACE_MULTICAST 1
|
||||||
#define SCOPED_MULTICAST 2
|
#define SCOPED_MULTICAST 2
|
||||||
@ -137,15 +141,17 @@ int s, utmpf;
|
|||||||
|
|
||||||
#define WHDRSIZE (sizeof(mywd) - sizeof(mywd.wd_we))
|
#define WHDRSIZE (sizeof(mywd) - sizeof(mywd.wd_we))
|
||||||
|
|
||||||
|
void run_as __P((uid_t *, gid_t *));
|
||||||
int configure __P((int));
|
int configure __P((int));
|
||||||
void getboottime __P((int));
|
void getboottime __P((int));
|
||||||
void onalrm __P((int));
|
void onalrm __P((int));
|
||||||
void quit __P((char *));
|
void quit __P((char *));
|
||||||
void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
|
void rt_xaddrs __P((caddr_t, caddr_t, struct rt_addrinfo *));
|
||||||
int verify __P((char *));
|
int verify __P((char *, int));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
char *interval __P((int, char *));
|
char *interval __P((int, char *));
|
||||||
void Sendto __P((int, char *, int, int, char *, int));
|
void Sendto __P((int, const void *, size_t, int,
|
||||||
|
const struct sockaddr *, int));
|
||||||
#define sendto Sendto
|
#define sendto Sendto
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -160,11 +166,16 @@ main(argc, argv)
|
|||||||
int on = 1;
|
int on = 1;
|
||||||
char *cp;
|
char *cp;
|
||||||
struct sockaddr_in sin;
|
struct sockaddr_in sin;
|
||||||
|
uid_t unpriv_uid;
|
||||||
|
gid_t unpriv_gid;
|
||||||
|
|
||||||
if (getuid()) {
|
if (getuid()) {
|
||||||
fprintf(stderr, "rwhod: not super user\n");
|
fprintf(stderr, "rwhod: not super user\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_as(&unpriv_uid, &unpriv_gid);
|
||||||
|
|
||||||
argv++; argc--;
|
argv++; argc--;
|
||||||
while (argc > 0 && *argv[0] == '-') {
|
while (argc > 0 && *argv[0] == '-') {
|
||||||
if (strcmp(*argv, "-m") == 0) {
|
if (strcmp(*argv, "-m") == 0) {
|
||||||
@ -234,6 +245,8 @@ usage: fprintf(stderr, "usage: rwhod [ -m [ ttl ] ]\n");
|
|||||||
syslog(LOG_ERR, "bind: %m");
|
syslog(LOG_ERR, "bind: %m");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
setgid(unpriv_gid);
|
||||||
|
setuid(unpriv_uid);
|
||||||
if (!configure(s))
|
if (!configure(s))
|
||||||
exit(1);
|
exit(1);
|
||||||
signal(SIGALRM, onalrm);
|
signal(SIGALRM, onalrm);
|
||||||
@ -258,7 +271,7 @@ usage: fprintf(stderr, "usage: rwhod [ -m [ ttl ] ]\n");
|
|||||||
continue;
|
continue;
|
||||||
if (wd.wd_type != WHODTYPE_STATUS)
|
if (wd.wd_type != WHODTYPE_STATUS)
|
||||||
continue;
|
continue;
|
||||||
if (!verify(wd.wd_hostname)) {
|
if (!verify(wd.wd_hostname, sizeof wd.wd_hostname)) {
|
||||||
syslog(LOG_WARNING, "malformed host name from %x",
|
syslog(LOG_WARNING, "malformed host name from %x",
|
||||||
from.sin_addr);
|
from.sin_addr);
|
||||||
continue;
|
continue;
|
||||||
@ -300,22 +313,47 @@ usage: fprintf(stderr, "usage: rwhod [ -m [ ttl ] ]\n");
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
run_as(uid, gid)
|
||||||
|
uid_t *uid;
|
||||||
|
gid_t *gid;
|
||||||
|
{
|
||||||
|
struct passwd *pw;
|
||||||
|
|
||||||
|
pw = getpwnam(UNPRIV_USER);
|
||||||
|
if (!pw) {
|
||||||
|
syslog(LOG_ERR, "getpwnam(%s): %m", UNPRIV_USER);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*uid = pw->pw_uid;
|
||||||
|
|
||||||
|
pw = getpwnam(UNPRIV_GROUP);
|
||||||
|
if (!pw) {
|
||||||
|
syslog(LOG_ERR, "getpwnam(%s): %m", UNPRIV_GROUP);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*gid = pw->pw_gid;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check out host name for unprintables
|
* Check out host name for unprintables
|
||||||
* and other funnies before allowing a file
|
* and other funnies before allowing a file
|
||||||
* to be created. Sorry, but blanks aren't allowed.
|
* to be created. Sorry, but blanks aren't allowed.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
verify(name)
|
verify(name, maxlen)
|
||||||
register char *name;
|
register char *name;
|
||||||
|
register int maxlen;
|
||||||
{
|
{
|
||||||
register int size = 0;
|
register int size = 0;
|
||||||
|
|
||||||
while (*name) {
|
while (*name && size < maxlen) {
|
||||||
if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
|
if (!isascii(*name) || !(isalnum(*name) || ispunct(*name)))
|
||||||
return (0);
|
return (0);
|
||||||
name++, size++;
|
name++, size++;
|
||||||
}
|
}
|
||||||
|
*name = '\0';
|
||||||
return (size > 0);
|
return (size > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,16 +655,18 @@ configure(s)
|
|||||||
void
|
void
|
||||||
Sendto(s, buf, cc, flags, to, tolen)
|
Sendto(s, buf, cc, flags, to, tolen)
|
||||||
int s;
|
int s;
|
||||||
char *buf;
|
const void *buf;
|
||||||
int cc, flags;
|
size_t cc;
|
||||||
char *to;
|
int flags;
|
||||||
|
const struct sockaddr *to;
|
||||||
int tolen;
|
int tolen;
|
||||||
{
|
{
|
||||||
register struct whod *w = (struct whod *)buf;
|
register struct whod *w = (struct whod *)buf;
|
||||||
register struct whoent *we;
|
register struct whoent *we;
|
||||||
struct sockaddr_in *sin = (struct sockaddr_in *)to;
|
struct sockaddr_in *sin = (struct sockaddr_in *)to;
|
||||||
|
|
||||||
printf("sendto %x.%d\n", ntohl(sin->sin_addr), ntohs(sin->sin_port));
|
printf("sendto %x.%d\n", ntohl(sin->sin_addr.s_addr),
|
||||||
|
ntohs(sin->sin_port));
|
||||||
printf("hostname %s %s\n", w->wd_hostname,
|
printf("hostname %s %s\n", w->wd_hostname,
|
||||||
interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), " up"));
|
interval(ntohl(w->wd_sendtime) - ntohl(w->wd_boottime), " up"));
|
||||||
printf("load %4.2f, %4.2f, %4.2f\n",
|
printf("load %4.2f, %4.2f, %4.2f\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user