svn commit: r310393 - head/usr.sbin/syslogd
Hiroki Sato
hrs at FreeBSD.org
Thu Dec 22 13:46:18 UTC 2016
Author: hrs
Date: Thu Dec 22 13:46:17 2016
New Revision: 310393
URL: https://svnweb.freebsd.org/changeset/base/310393
Log:
- Fix a use-after-free bug when dq_timeout == 1 and
sending SIGTERM to the process failed. It is an
unusual situation but it can happen.
- Split deadq_remove() into deadq_remove() and
deadq_removebypid().
- Normalize variable names of struct deadq_entry *.
Modified:
head/usr.sbin/syslogd/syslogd.c
Modified: head/usr.sbin/syslogd/syslogd.c
==============================================================================
--- head/usr.sbin/syslogd/syslogd.c Thu Dec 22 13:38:50 2016 (r310392)
+++ head/usr.sbin/syslogd/syslogd.c Thu Dec 22 13:46:17 2016 (r310393)
@@ -236,9 +236,6 @@ static TAILQ_HEAD(, deadq_entry) deadq_h
#define DQ_TIMO_INIT 2
-typedef struct deadq_entry *dq_t;
-
-
/*
* Struct to hold records of network addresses that are allowed to log
* to us.
@@ -334,7 +331,8 @@ static int addsock(struct sockaddr *, so
static struct filed *cfline(const char *, const char *, const char *);
static const char *cvthname(struct sockaddr *);
static void deadq_enter(pid_t, const char *);
-static int deadq_remove(pid_t);
+static int deadq_remove(struct deadq_entry *);
+static int deadq_removebypid(pid_t);
static int decode(const char *, const CODE *);
static void die(int) __dead2;
static void dodie(int);
@@ -1509,7 +1507,7 @@ reapchild(int signo __unused)
continue;
/* First, look if it's a process from the dead queue. */
- if (deadq_remove(pid))
+ if (deadq_removebypid(pid))
continue;
/* Now, look in list of active processes. */
@@ -2252,7 +2250,7 @@ static void
markit(void)
{
struct filed *f;
- dq_t q, next;
+ struct deadq_entry *dq, *dq0;
now = time((time_t *)NULL);
MarkSeq += TIMERINTVL;
@@ -2273,14 +2271,12 @@ markit(void)
}
/* Walk the dead queue, and see if we should signal somebody. */
- for (q = TAILQ_FIRST(&deadq_head); q != NULL; q = next) {
- next = TAILQ_NEXT(q, dq_entries);
-
- switch (q->dq_timeout) {
+ TAILQ_FOREACH_SAFE(dq, &deadq_head, dq_entries, dq0) {
+ switch (dq->dq_timeout) {
case 0:
/* Already signalled once, try harder now. */
- if (kill(q->dq_pid, SIGKILL) != 0)
- (void)deadq_remove(q->dq_pid);
+ if (kill(dq->dq_pid, SIGKILL) != 0)
+ (void)deadq_remove(dq);
break;
case 1:
@@ -2292,12 +2288,13 @@ markit(void)
* didn't even really exist, in case we simply
* drop it from the dead queue).
*/
- if (kill(q->dq_pid, SIGTERM) != 0)
- (void)deadq_remove(q->dq_pid);
- /* FALLTHROUGH */
-
+ if (kill(dq->dq_pid, SIGTERM) != 0)
+ (void)deadq_remove(dq);
+ else
+ dq->dq_timeout--;
+ break;
default:
- q->dq_timeout--;
+ dq->dq_timeout--;
}
}
MarkSet = 0;
@@ -2738,7 +2735,7 @@ p_open(const char *prog, pid_t *rpid)
static void
deadq_enter(pid_t pid, const char *name)
{
- dq_t p;
+ struct deadq_entry *dq;
int status;
/*
@@ -2752,36 +2749,42 @@ deadq_enter(pid_t pid, const char *name)
return;
}
- p = malloc(sizeof(struct deadq_entry));
- if (p == NULL) {
+ dq = malloc(sizeof(*dq));
+ if (dq == NULL) {
logerror("malloc");
exit(1);
}
- *p = (struct deadq_entry){
+ *dq = (struct deadq_entry){
.dq_pid = pid,
.dq_timeout = DQ_TIMO_INIT
};
- TAILQ_INSERT_TAIL(&deadq_head, p, dq_entries);
+ TAILQ_INSERT_TAIL(&deadq_head, dq, dq_entries);
}
static int
-deadq_remove(pid_t pid)
+deadq_remove(struct deadq_entry *dq)
{
- dq_t q;
-
- TAILQ_FOREACH(q, &deadq_head, dq_entries) {
- if (q->dq_pid == pid)
- break;
- }
- if (q != NULL) {
- TAILQ_REMOVE(&deadq_head, q, dq_entries);
- free(q);
+ if (dq != NULL) {
+ TAILQ_REMOVE(&deadq_head, dq, dq_entries);
+ free(dq);
return (1);
}
return (0);
}
+static int
+deadq_removebypid(pid_t pid)
+{
+ struct deadq_entry *dq;
+
+ TAILQ_FOREACH(dq, &deadq_head, dq_entries) {
+ if (dq->dq_pid == pid)
+ break;
+ }
+ return (deadq_remove(dq));
+}
+
static void
log_deadchild(pid_t pid, int status, const char *name)
{
More information about the svn-src-head
mailing list