summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'net-ftp/netkit-ftpd/files/netkit-ftpd-0.17-setguid.patch')
-rw-r--r--net-ftp/netkit-ftpd/files/netkit-ftpd-0.17-setguid.patch66
1 files changed, 66 insertions, 0 deletions
diff --git a/net-ftp/netkit-ftpd/files/netkit-ftpd-0.17-setguid.patch b/net-ftp/netkit-ftpd/files/netkit-ftpd-0.17-setguid.patch
new file mode 100644
index 000000000000..f5d0cf75fcfd
--- /dev/null
+++ b/net-ftp/netkit-ftpd/files/netkit-ftpd-0.17-setguid.patch
@@ -0,0 +1,66 @@
+--- linux-ftpd-0.17/ftpd/popen.c
++++ linux-ftpd-0.17/ftpd/popen.c
+@@ -169,8 +169,13 @@
+ * XXX: this doesn't seem right... and shouldn't
+ * we initgroups, or at least setgroups(0,0)?
+ */
+- setgid(getegid());
+- setuid(i);
++
++/*
++ * PSz 25 Aug 06 Must check the return status of these setgid/setuid calls,
++ * see http://www.bress.net/blog/archives/34-setuid-madness.html
++ */
++ if ( setgid(getegid()) != 0 ) _exit(1);
++ if ( setuid(i) != 0 ) _exit(1);
+
+ #ifndef __linux__
+ /*
+--- linux-ftpd-0.17/ftpd/ftpd.c
++++ linux-ftpd-0.17/ftpd/ftpd.c
+@@ -1159,6 +1159,13 @@
+ }
+ strcpy(pw->pw_dir, "/");
+ setenv("HOME", "/", 1);
++ }
++ /* PSz 25 Aug 06 chdir for real users done after setting UID */
++ if (seteuid((uid_t)pw->pw_uid) < 0) {
++ reply(550, "Can't set uid.");
++ goto bad;
++ }
++ if (guest || dochroot) { /* do nothing, handled above */
+ } else if (chdir(pw->pw_dir) < 0) {
+ if (chdir("/") < 0) {
+ reply(530, "User %s: can't change directory to %s.",
+@@ -1167,10 +1174,7 @@
+ } else
+ lreply(230, "No directory! Logging in with home=/");
+ }
+- if (seteuid((uid_t)pw->pw_uid) < 0) {
+- reply(550, "Can't set uid.");
+- goto bad;
+- }
++
+ sigfillset(&allsigs);
+ sigprocmask(SIG_UNBLOCK,&allsigs,NULL);
+
+@@ -1408,7 +1412,8 @@
+ goto bad;
+ sleep(tries);
+ }
+- (void) seteuid((uid_t)pw->pw_uid);
++/* PSz 25 Aug 06 Check return status */
++ if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1);
+ sigfillset(&allsigs);
+ sigprocmask (SIG_UNBLOCK, &allsigs, NULL);
+
+@@ -1440,7 +1445,8 @@
+ bad:
+ /* Return the real value of errno (close may change it) */
+ t = errno;
+- (void) seteuid((uid_t)pw->pw_uid);
++/* PSz 25 Aug 06 Check return status */
++ if (seteuid((uid_t)pw->pw_uid) != 0) _exit(1);
+ sigfillset (&allsigs);
+ sigprocmask (SIG_UNBLOCK, &allsigs, NULL);
+ (void) close(s);