[patch] remove deadcode

Matt Johnston matt at ucc.asn.au
Fri Jul 7 18:02:53 WST 2006


On Thu, Jul 06, 2006 at 02:49:40PM -0700, Erik Hovland wrote:
> I have finished an audit of dropbear and decided to reply to my own post
> because my current draft of patches expands on the same file (and a few
> others.
> 
> The patches should be consistent with current mtn repo and should have
> annotations in each file. I am willing to rework any patch that doesn't
> meet the statisfaction of the devs. So please send feedback.

Thanks for the eyeballing and patches. I've applied most of
them with only minor changes.

With the svr-chansession.c exit patch I think the current
code is correct, as the exit value will only be unset when
i == svr_ses.childpidsize.  I've modified the code to be a
bit clearer anyway.

For the ssh-pty.c patch, I don't think this improves the
security/correctness much. tty_name is always a /dev/ttyXXX
device, and if an attacker can manipulate paths in /dev/, then
there are larger problems.  Does that analysis sound
reasonable?

Cheers,
Matt

(PS, if you're using the monotone head, beware that there's
a known issue that can cause it to wait for input when
closing on Linux.)




> BUG: Potentially dangeruous use of stat/chown/chmod. Since we use the
> string tty_name for all calls on the tty device it is possible for
> someone to be underhanded and use these calls and that string
> to elevate priviledges.
> 
> FIX: Switch to using fstat/fchown/fchmod and obtain a file
> descriptor instead of using a string.
> 
> NOTE: I doubt this can be exploited. But why leave it hanging around.
> 
--- sshpty.c	old
+++ sshpty.c	new
@@ -356,6 +356,7 @@ void
 pty_setowner(struct passwd *pw, const char *tty_name)
 {
 	struct group *grp;
+	FILE* ttyfd;
 	gid_t gid;
 	mode_t mode;
 	struct stat st;
@@ -375,21 +376,25 @@ pty_setowner(struct passwd *pw, const ch
 	 * Warn but continue if filesystem is read-only and the uids match/
 	 * tty is owned by root.
 	 */
-	if (stat(tty_name, &st)) {
-		dropbear_exit("pty_setowner: stat(%.101s) failed: %.100s",
+	if (!(ttyfd = fopen(tty_name, "w+"))) {
+		dropbear_exit("pty_setowner: fopen(%.101s) failed: %.100s",
+			      tty_name, strerror(errno));
+	}
+	if (fstat(ttyfd, &st)) {
+		dropbear_exit("pty_setowner: fstat(%.101s) failed: %.100s",
 				tty_name, strerror(errno));
 	}
 
 	if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
-		if (chown(tty_name, pw->pw_uid, gid) < 0) {
+		if (fchown(ttyfd, pw->pw_uid, gid) < 0) {
 			if (errno == EROFS &&
 			    (st.st_uid == pw->pw_uid || st.st_uid == 0)) {
 				dropbear_log(LOG_ERR,
-					"chown(%.100s, %u, %u) failed: %.100s",
+					"fchown(%.100s, %u, %u) failed: %.100s",
 						tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
 						strerror(errno));
 			} else {
-				dropbear_exit("chown(%.100s, %u, %u) failed: %.100s",
+				dropbear_exit("fchown(%.100s, %u, %u) failed: %.100s",
 				    tty_name, (unsigned int)pw->pw_uid, (unsigned int)gid,
 				    strerror(errno));
 			}
@@ -397,16 +402,18 @@ pty_setowner(struct passwd *pw, const ch
 	}
 
 	if ((st.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) != mode) {
-		if (chmod(tty_name, mode) < 0) {
+		if (fchmod(ttyfd, mode) < 0) {
 			if (errno == EROFS &&
 			    (st.st_mode & (S_IRGRP | S_IROTH)) == 0) {
 				dropbear_log(LOG_ERR,
-					"chmod(%.100s, 0%o) failed: %.100s",
+					"fchmod(%.100s, 0%o) failed: %.100s",
 					tty_name, mode, strerror(errno));
 			} else {
-				dropbear_exit("chmod(%.100s, 0%o) failed: %.100s",
+				dropbear_exit("fchmod(%.100s, 0%o) failed: %.100s",
 				    tty_name, mode, strerror(errno));
 			}
 		}
 	}
+	if (ttyfd)
+	    fclose(ttyfd);
 }


More information about the Dropbear mailing list