bin/103873: login(1) SEGFAULT on unsuccessful login
douglas steinwand
dzs-pr at dzs.fx.org
Sun Oct 1 10:20:29 PDT 2006
>Number: 103873
>Category: bin
>Synopsis: login(1) SEGFAULT on unsuccessful login
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sun Oct 01 17:20:27 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: douglas steinwand
>Release: 6.2-PRERELEASE
>Organization:
>Environment:
FreeBSD thinkpad.fx.org 6.2-PRERELEASE FreeBSD 6.2-PRERELEASE #4: Sat Sep 30 20:42:55 PDT 2006 root at thinkpad.fx.org:/usr/obj/usr/src/sys/HAWK6 i386
>Description:
It seems that the login_audit.c doesn't check that pwd is non-NULL before dereferencing it. Below is a patch with a possible solution.
>How-To-Repeat:
At the console, press Enter a few times, or run login(1) from a shell. If you do not successfuly login, the application exits and syslog notes something like:
Oct 1 10:08:51 thinkpad kernel: pid 62854 (login), uid 0: exited on signal 11
>Fix:
--- usr.bin/login/login_audit.c.orig Tue Sep 5 16:53:21 2006
+++ usr.bin/login/login_audit.c Sun Oct 1 09:46:41 2006
@@ -51,6 +51,17 @@
*/
static au_tid_t tid;
+/* returns -1 on failure, 0 on success */
+static int
+get_pwd(uid_t *uid, gid_t *gid)
+{
+ if (pwd == NULL)
+ return(-1);
+ *uid = pwd->pw_uid;
+ *gid = pwd->pw_gid;
+ return(0);
+}
+
/*
* The following tokens are included in the audit record for a successful
* login: header, subject, return.
@@ -62,11 +73,14 @@
int aufd;
au_mask_t aumask;
auditinfo_t auinfo;
- uid_t uid = pwd->pw_uid;
- gid_t gid = pwd->pw_gid;
+ uid_t uid;
+ gid_t gid;
pid_t pid = getpid();
long au_cond;
+ if (get_pwd(&uid, &gid) == -1)
+ return;
+
/* If we are not auditing, don't cut an audit record; just return. */
if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
if (errno == ENOSYS)
@@ -140,8 +154,8 @@
errx(1, "login: Audit Error: au_to_subject32() failed");
} else {
/* We know the subject -- so use its value instead. */
- uid = pwd->pw_uid;
- gid = pwd->pw_gid;
+ if (get_pwd(&uid, &gid) == -1)
+ errx(1, "login: Audit Error: au_to_subject32() failed");
if ((tok = au_to_subject32(uid, geteuid(), getegid(), uid,
gid, pid, pid, &tid)) == NULL)
errx(1, "login: Audit Error: au_to_subject32() failed");
@@ -172,10 +186,13 @@
int aufd;
au_mask_t aumask;
auditinfo_t auinfo;
- uid_t uid = pwd->pw_uid;
- gid_t gid = pwd->pw_gid;
+ uid_t uid;
+ gid_t gid;
pid_t pid = getpid();
long au_cond;
+
+ if (get_pwd(&uid, &gid) == -1)
+ return;
/* If we are not auditing, don't cut an audit record; just return. */
if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list