[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

MiNT patches (fwd)



Here's a message from Wolfgang Lux.  He asked me to forward it to the
MiNT mailing list.

Michael


Wolfgang Lux wrote:

Date: Tue, 23 Aug 1994 12:07:32 +0200
From: ibmpa!rio.heidelbg.ibm.com!lux@ibminet.awdpa.ibm.com (Wolfgang Lux)
Message-Id: <9408231007.AA20275@rio.heidelbg.ibm.com>
To: hohmuth%inf.tu-dresden.de@ibmpa.awdpa.ibm.com
Subject: MiNT patches

Hallo Michael,

leider habe ich keine Adresse der MiNT Mailing List, daher moechte ich dich
bitten die folgenden MiNT-Patches an die Mitglieder der Mailing List
weiterzureichen.

Wolfgang

8<-----------------------------
Hi folks,

here a list of bug-fixes and enhancements relative to the MiNT 1.10h9
mega patch collected by Michael Hohmuth.

The following bugs are fixed with this patch:

- mint.h: Added an #include <file.h>, which was necessary for me to
compile the whole stuff.

- biosfs.c: Use the "rsconf trick" from the TIOC[IO]BAUD case in
bios_ioctl for the TIOC[CS]BRK and TIO[GS]FLAGS cases, so setting
terminal flags will now work correctly on /dev/modem2 and
/dev/serial[12], too. As a side effect of this bug fix I made the
mapin function a local function in xbios.c to avoid any further
(mis)uses of this function outside xbios.c. (There don't seem to be
any useful applications to this function outside of xbios.c, 
anyway :-)

- nalloc2.c: In nalloc I restored the old check whether the size of a
block matches the requested size. The code I fixed always checks for
enough size to save the requested memory plus the size of a block
header, however this made the test whether to unlink the block
completly always fail. I restored the old behaviour (which has worked
for me in (a fixed) MiNT 1.09 for around half a year without problems.

- biosfs.c (again): Copied the workaround for the broken Iorec(0) call
in --- at least TOS 2.05 (which is my setup) --- from the xbios
function uiorec, to the initialization of the bios_tty structure
iorec's. Because the bconmap2 variable is initialized only later in
bios_init I had to initialize it in biosfs, too. (I didn't bother to
remove the initialization in init_bios, in case some decides to change
the initialization order :-)

I also added the following enhancements to MiNT 1.10:

- tty.c: On all Un*x systems I know, the werase character deletes the
previous even if there are white space characters between the cursor
and the previous word. In MiNT the word was only deleted if the cursor
was at the end of the word. I fixed this behaviour to be like Un*x.

- dosdir.c: Changed f_chown, so a user can change the group of a file
to any of his supplementary groups, not only the effective group id.
Also added one more "posix"ism; if the file has set-uid or set-gid bit
set these bits are reset when f_chown is called by a non-root process
and the file is not a directory.

- dosdir.c, dosfile.c, filesys.c: Added BSD-like setgid and sticky bit
semantics for directories. Setgid semantics are implemented in do_open
and d_mkdir, so that any file or directory that is created in a
directory whose setgid bit is on, will be created with a group id
equal to that of the directory instead of the process' effective group
id. (This complements nicely the existence of supplementary groups
:-). Sticky bit semantics prevent any non-root process from deleting a
file or directory in a directory with sticky bit on, which the process
doesn't own. This is implemented d_delete, f_delete and f_rename(!).
As a side effect I modified the dir_access routine, so that it returns
the file mode bits in a (new) third parameter.

Hope you like this,
Wolfgang

diff -U2 -r -x*.orig /usr/src/MiNT-1.10/biosfs.c ./biosfs.c
--- /usr/src/MiNT-1.10/biosfs.c	Thu Aug 18 11:07:30 1994
+++ ./biosfs.c	Mon Aug 22 11:40:42 1994
@@ -266,5 +266,5 @@
 	struct bios_file *b, *c;
 	int majdev, mindev;
-	int i, oldmap = 1;
+	int i;

 	broot = BDEV;
@@ -306,11 +306,15 @@
 		b->next = 0;
 	}
+/* We cannot call the XBIOS in the following initialization because of
+ * a broken Iorec(0) in --- at least --- TOS 2.05 (see xbios.c) :-(
+ * This workaround requires that MAPTAB, i.e. bconmap2 being initialized.
+ * This is done in bios_init, which is called at a later time, so we
+ * have to initialize it ourselves.
+ */
 	if (has_bconmap)
-		oldmap = (int) Bconmap(-1);
+		bconmap2 = (BCONMAP2_T *)Bconmap(-2);
 	/* Initialize bios_tty structures */
 	for (i=0;c && i<MAX_BTTY;c=c->next, i++) {
-		if (has_bconmap)
-			Bconmap(c->private);
-		bttys[i].irec = Iorec(0);
+		bttys[i].irec = (IOREC_T *)MAPTAB[i].iorec;
 		bttys[i].orec = bttys[i].irec+1;
 		bttys[i].rsel = &(c->tty->rsel);
@@ -319,6 +323,4 @@
 		bttys[i].maxbaud = MAXBAUD;
 	}
-	if (has_bconmap)
-		Bconmap(oldmap);
 	btty_max = i;

@@ -1909,7 +1911,10 @@
 	    {
 		unsigned long bits;
+		int oldmap;

 		dev = f->fc.aux;
 		if (dev == 1 || dev >= 6) {
+/* trick rsconf into setting the correct port (it uses curproc->bconmap) */
+			oldmap = curproc->bconmap;
 			if (has_bconmap) {
 				if (dev == 1)
@@ -1929,5 +1934,5 @@
 					break;
 				}
-				mapin(dev);
+			        curproc->bconmap = dev;
 			}
 		} else {
@@ -1941,4 +1946,5 @@
 			bits |= 8;
 		(void)rsconf(-1, -1, -1, -1, (int)bits, -1);
+		curproc->bconmap = oldmap;
 		break;
 	    }
@@ -1950,11 +1956,15 @@
 		unsigned char ucr;
 		short flow;
+		int oldmap;

 		dev = f->fc.aux;
 		if (dev == 1 || dev >= 6) {
+/* trick rsconf into setting the correct port (it uses curproc->bconmap) */
+			oldmap = curproc->bconmap;
 			sgflags = &((struct tty *)f->devinfo)->sg.sg_flags;
 			oflags = *sgflags & (T_TANDEM|T_RTSCTS);
 			if (has_bconmap)
-				mapin((dev == 1) ? curproc->bconmap : dev);
+				curproc->bconmap =
+					(dev == 1) ? curproc->bconmap : dev;
 			bits = rsconf(-1, -1, -1, -1, -1, -1);	/* get settings */
 			ucr = (bits >> 24L) & 0x0ff;		/* isolate UCR byte */
@@ -1986,4 +1996,5 @@
 				*((unsigned short *)buf) = oflags;
 			}
+			curproc->bconmap = oldmap;
 		} else {
 			return EINVFN;
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/dosdir.c ./dosdir.c
--- /usr/src/MiNT-1.10/dosdir.c	Thu Aug 18 11:07:44 1994
+++ ./dosdir.c	Mon Aug 22 19:50:10 1994
@@ -109,4 +109,7 @@
 	long r;
 	char temp1[PATH_MAX];
+	short cur_gid, cur_egid;
+	XATTR xattr;
+	unsigned mode;

 	TRACE(("Dcreate(%s)", path));
@@ -118,5 +121,5 @@
 	}
 /* check for write permission on the directory */
-	r = dir_access(&dir, S_IWOTH);
+	r = dir_access(&dir, S_IWOTH, &mode);
 	if (r) {
 		DEBUG(("Dcreate(%s): write access to directory denied",path));
@@ -124,5 +127,21 @@
 		return r;
 	}
-	r = (*dir.fs->mkdir)(&dir, temp1, DEFAULT_DIRMODE & ~curproc->umask);
+	if (mode & S_ISGID) {
+		r = (*dir.fs->getxattr)(&dir, &xattr);
+		if (r) {
+			DEBUG(("Dcreate(%s): file system returned %ld", path, r));
+		} else {
+			cur_gid = curproc->rgid;
+			cur_egid = curproc->egid;
+			curproc->rgid = curproc->egid = xattr.gid;
+			r = (*dir.fs->mkdir)(&dir, temp1,
+					     (DEFAULT_DIRMODE & ~curproc->umask)
+					     | S_ISGID);
+			curproc->rgid = cur_gid;
+			curproc->egid = cur_egid;
+		}
+	} else
+		r = (*dir.fs->mkdir)(&dir, temp1,
+				     DEFAULT_DIRMODE & ~curproc->umask);
 	release_cookie(&dir);
 	return r;
@@ -139,4 +158,5 @@
 	XATTR xattr;
 	char temp1[PATH_MAX];
+	unsigned mode;

 	TRACE(("Ddelete(%s)", path));
@@ -152,5 +172,5 @@
  * is located
  */
-	if ((r = dir_access(&parentdir, S_IWOTH)) != 0) {
+	if ((r = dir_access(&parentdir, S_IWOTH, &mode)) != 0) {
 		DEBUG(("Ddelete(%s): access to directory denied", path));
 		release_cookie(&parentdir);
@@ -172,4 +192,13 @@
 	}

+/* check effective uid if sticky bit is set in parent */
+	if ((mode & S_ISVTX) && curproc->euid
+	    && curproc->euid != xattr.uid) {
+		release_cookie(&targdir);
+		release_cookie(&parentdir);
+		DEBUG(("Ddelete: sticky bit set and not owner"));
+		return EACCDN;
+	}
+
 /* if the "directory" is a symbolic link, really unlink it */
 	if ( (xattr.mode & S_IFMT) == S_IFLNK ) {
@@ -370,4 +399,5 @@
 	int i, havelabel;
 	char temp1[PATH_MAX];
+	unsigned mode;

 	TRACE(("Fsfirst(%s, %x)", path, attrib));
@@ -514,5 +544,5 @@
  * sure that it really is a directory!)
  */
-	r = dir_access(&dir, S_IROTH);
+	r = dir_access(&dir, S_IROTH, &mode);
 	if (r) {
 		DEBUG(("Fsfirst(%s): access to directory denied (error code %ld)", path, r));
@@ -730,12 +760,9 @@
 	const char *name;
 {
-#if 0
 	fcookie dir, fc;
 	XATTR	xattr;
-#else
-	fcookie dir;
-#endif
 	long r;
 	char temp1[PATH_MAX];
+	unsigned mode;

 	TRACE(("Fdelete(%s)", name));
@@ -749,5 +776,5 @@

 /* check for write permission on directory */
-	r = dir_access(&dir, S_IWOTH);
+	r = dir_access(&dir, S_IWOTH, &mode);
 	if (r) {
 		DEBUG(("Fdelete(%s): write access to directory denied",name));
@@ -756,5 +783,4 @@
 	}

-#if 0
 /* now get the file attributes */
 	if ( (r = (*dir.fs->lookup)(&dir, temp1, &fc) ) != 0) {
@@ -771,4 +797,15 @@
 		return r;
 	}
+
+/* check effective uid if directories sticky bit is set */
+	if ((mode & S_ISVTX) && curproc->euid
+	    && curproc->euid != xattr.uid) {
+		release_cookie(&dir);
+		release_cookie(&fc);
+		DEBUG(("Fdelete: sticky bit set and not owner"));
+		return EACCDN;
+	}
+
+#if 0
 /* see if we're allowed to kill it */
 	if (denyaccess(&xattr, S_IWOTH)) {
@@ -781,7 +818,5 @@
 	r = (*dir.fs->remove)(&dir,temp1);

-#if 0
 	release_cookie(&fc);
-#endif
 	release_cookie(&dir);
 	return r;
@@ -797,4 +832,5 @@
 	char temp1[PATH_MAX], temp2[PATH_MAX];
 	long r;
+	unsigned mode;

 	UNUSED(junk);
@@ -842,6 +878,9 @@

 /* check for write permission on both directories */
-	r = dir_access(&olddir, S_IWOTH);
-	if (!r) r = dir_access(&newdir, S_IWOTH);
+	r = dir_access(&olddir, S_IWOTH, &mode);
+	if (!r && (mode & S_ISVTX) && curproc->euid
+	    && curproc->euid != xattr.uid)
+		r = EACCDN;
+	if (!r) r = dir_access(&newdir, S_IWOTH, &mode);
 	if (r) {
 		DEBUG(("Frename(%s,%s): access to a directory denied",old,new));
@@ -910,4 +949,5 @@
 	fcookie dir;
 	long r;
+	unsigned mode;

 	r = path2cookie(name, follow_links, &dir);
@@ -916,5 +956,5 @@
 		return r;
 	}
-	r = dir_access(&dir, S_IROTH);
+	r = dir_access(&dir, S_IROTH, &mode);
 	if (r) {
 		DEBUG(("Dopendir(%s): read permission denied", name));
@@ -1089,4 +1129,5 @@
 	char temp1[PATH_MAX], temp2[PATH_MAX];
 	long r;
+	unsigned mode;

 	TRACE(("Flink(%s, %s)", old, new));
@@ -1113,5 +1154,5 @@
 /* check for write permission on the destination directory */

-	r = dir_access(&newdir, S_IWOTH);
+	r = dir_access(&newdir, S_IWOTH, &mode);
 	if (r) {
 		DEBUG(("Flink(%s,%s): access to directory denied",old,new));
@@ -1135,4 +1176,5 @@
 	long r;
 	char temp1[PATH_MAX];
+	unsigned mode;

 	TRACE(("Fsymlink(%s, %s)", old, new));
@@ -1143,5 +1185,5 @@
 		return r;
 	}
-	r = dir_access(&newdir, S_IWOTH);
+	r = dir_access(&newdir, S_IWOTH, &mode);
 	if (r) {
 		DEBUG(("Fsymlink(%s,%s): access to directory denied",old,new));
@@ -1238,8 +1280,8 @@
 /* MiNT acts like _POSIX_CHOWN_RESTRICTED: a non-privileged process can
  * only change the ownership of a file that is owned by this user, to
- * the effective group id of the process
+ * the effective group id of the process or one of its supplementary groups
  */
 	if (curproc->euid) {
-		if (curproc->egid != gid)
+		if (curproc->egid != gid && !ngroupmatch(gid))
 			r = EACCDN;
 		else
@@ -1255,6 +1297,27 @@
 			return EACCDN;
 		}
+		r = (*fc.fs->chown)(&fc, uid, gid);
+
+	/* POSIX 5.6.5.2: if name refers to a regular file the set-user-ID and
+	 * set-group-ID bits of the file mode shall be cleared upon successful
+	 * return from the call to chown, unless the call is made by a process
+	 * with the appropriate privileges.
+	 * Note that POSIX leaves the behaviour unspecified for all other file
+	 * types. At least for directories with BSD-like setgid semantics,
+	 * these bits should be left unchanged.
+	 */
+		if (!r && (xattr.mode & S_IFMT) != S_IFDIR
+		    && (xattr.mode & (S_ISUID | S_ISGID))) {
+			long s;
+
+			s = (*fc.fs->chmode)(&fc, xattr.mode & ~(S_ISUID | S_ISGID));
+			if (!s)
+				DEBUG(("Fchown: chmode returned %ld (ignored)",
+				       s));
+		}
 	}
-	r = (*fc.fs->chown)(&fc, uid, gid);
+	else
+		r = (*fc.fs->chown)(&fc, uid, gid);
+
 	release_cookie(&fc);
 	return r;
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/dosfile.c ./dosfile.c
--- /usr/src/MiNT-1.10/dosfile.c	Thu Aug 18 11:07:50 1994
+++ ./dosfile.c	Mon Aug 22 10:07:02 1994
@@ -36,4 +36,5 @@
 	int creating;
 	char temp1[PATH_MAX];
+	short cur_gid, cur_egid;
 	extern FILESYS proc_filesys, pipe_filesys;

@@ -92,6 +93,13 @@
 			return NULL;
 		}
+	/* fake gid if directories setgid bit set */
+		cur_gid = curproc->rgid;
+		cur_egid = curproc->egid;
+		if (xattr.mode & S_ISGID)
+			curproc->rgid = curproc->egid = xattr.gid;
 		r = (*dir.fs->creat)(&dir, temp1,
 			(S_IFREG|DEFAULT_MODE) & (~curproc->umask), attr, &fc);
+		curproc->rgid = cur_gid;
+		curproc->egid = cur_egid;
 		if (r) {
 			DEBUG(("do_open(%s): error %ld while creating file",
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/filesys.c ./filesys.c
--- /usr/src/MiNT-1.10/filesys.c	Thu Aug 18 11:08:10 1994
+++ ./filesys.c	Sat Aug 20 12:43:24 1994
@@ -1166,7 +1166,8 @@
  */
 long
-dir_access(dir, perm)
+dir_access(dir, perm, mode)
 	fcookie *dir;
 	unsigned perm;
+	unsigned *mode;
 {
 	XATTR xattr;
@@ -1186,4 +1187,5 @@
 		return EACCDN;
 	}
+	*mode = xattr.mode;
 	return 0;
 }
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/mint.h ./mint.h
--- /usr/src/MiNT-1.10/mint.h	Thu Aug 18 11:08:40 1994
+++ ./mint.h	Thu Aug 18 12:59:10 1994
@@ -166,4 +166,5 @@
 #include "signal.h"
 #include "mem.h"
+#include "file.h"
 #include "proc.h"

diff -U2 -r -x*.orig /usr/src/MiNT-1.10/nalloc2.c ./nalloc2.c
--- /usr/src/MiNT-1.10/nalloc2.c	Thu Aug 18 11:08:42 1994
+++ ./nalloc2.c	Thu Aug 18 16:27:04 1994
@@ -101,5 +101,5 @@
 	for (b = *(q = &a->a_ffirst); b; b = *(q = &b->b_next)) {
 	    /* if big enough, use it */
-	    if (b->b_size >= (size + sizeof(struct block))) {
+	    if (b->b_size >= size) {

 		/* got one */
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/proto.h ./proto.h
--- /usr/src/MiNT-1.10/proto.h	Thu Aug 18 11:09:02 1994
+++ ./proto.h	Mon Aug 22 19:53:06 1994
@@ -27,5 +27,4 @@
 long ARGS_ON_STACK supexec P_((Func funcptr, long a1, long a2, long a3, long a4, long a5));
 long ARGS_ON_STACK midiws P_((int, const char *));
-int mapin P_((int));
 long ARGS_ON_STACK uiorec P_((int));
 long ARGS_ON_STACK rsconf P_((int, int, int, int, int, int));
@@ -196,7 +195,8 @@
 void dispose_fileptr P_((FILEPTR *f));
 int ARGS_ON_STACK denyshare P_((FILEPTR *list, FILEPTR *newfileptr));
+int ngroupmatch P_((int group));
 int denyaccess P_((XATTR *, unsigned));
 LOCK * ARGS_ON_STACK denylock P_((LOCK *list, LOCK *newlock));
-long dir_access P_((fcookie *, unsigned));
+long dir_access P_((fcookie *, unsigned, unsigned *));
 int has_wild P_((const char *name));
 void copy8_3 P_((char *dest, const char *src));
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/tty.c ./tty.c
--- /usr/src/MiNT-1.10/tty.c	Thu Aug 18 11:09:26 1994
+++ ./tty.c	Thu Aug 18 15:51:22 1994
@@ -192,4 +192,10 @@
 			else if ((char)ch == tty->ltc.t_werasc) {
 				while (bytes_read > 0 &&
+				       (ptr[-1] == ' ' || ptr[-1] == '\t')) {
+					ptr--;
+					erase(f, *ptr);
+					bytes_read--;
+				}
+				while (bytes_read > 0 &&
 				       !(ptr[-1] == ' ' || ptr[-1] == '\t')) {
 					ptr--;
diff -U2 -r -x*.orig /usr/src/MiNT-1.10/xbios.c ./xbios.c
--- /usr/src/MiNT-1.10/xbios.c	Thu Aug 18 11:09:40 1994
+++ ./xbios.c	Thu Aug 18 16:00:28 1994
@@ -146,5 +146,5 @@
 int curbconmap;

-int
+static int
 mapin(dev)
 	int dev;