[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
MiNT 1.09 security: f_delete() patch
Hi!
Here's a patch which makes MiNT's f_delete() respect the sticky bit according
to the semantic how I understand it and hope it really is... Well, at least
it's better and/or a bit more secure than it is now... :-)
It goes like this:
If I haven't write permission to the parent directory, I loose. Otherwise,
if the sticky bit isn't set, I can delete anything regardless of its mode
or if it's mine at all. If the sticky bit is set, I can only delete a file
if it's mine, or if the whole directory is mine. In the last case I again can
delete every file in the directory.
Well, look at the code if you like... :-)
so long,
TeSche
--
PS: If the above written looks weird, then that's probably because it _is_.
WhoDunnIt: Torsten Scherer (Schiller, Tesche, ...)
Where: Faculty of Technology, University of Bielefeld, Germany
EMail: itschere@techfak.uni-bielefeld.de / tesche@hrz.uni-bielefeld.de
--- cut cut cut ---
--- orig/dosdir.c Fri Nov 19 15:34:12 1993
+++ my/dosdir.c Fri Dec 17 11:02:50 1993
@@ -716,36 +716,78 @@
release_cookie(&fc);
return xattr.attr;
}
}
+/* tesche: this one respects the sticky bit
+ */
+
long ARGS_ON_STACK
f_delete(name)
const char *name;
{
- fcookie dir;
- long r;
- char temp1[PATH_MAX];
+ fcookie dir, fc;
+ long r;
+ char temp1[PATH_MAX];
+ XATTR dxattr, fxattr;
TRACE(("Fdelete(%s)", name));
- r = path2cookie(name, temp1, &dir);
+/* first, get the directory cookie */
+ if ((r = path2cookie(name, temp1, &dir))) {
+ DEBUG(("Fdelete(%s): error %ld, perhaps path not found", name, r));
+ return r;
+ }
- if (r) {
- DEBUG(("Fdelete: error %ld", r));
+/* check for write permission on directory, sorry, can't use dir_access()
+ * here cause we may also need other bits of the XATTR structure
+ */
+ if ((r = (dir.fs->getxattr)(&dir, &dxattr))) {
+ DEBUG(("Fdelete(%s): can't get directory attributes", name));
+ release_cookie(&dir);
return r;
}
-/* check for write permission on directory */
- r = dir_access(&dir, S_IWOTH);
- if (r) {
- DEBUG(("Fdelete(%s): write access to directory denied",name));
- } else {
-/* BUG: we should check here for a read-only file */
- r = (*dir.fs->remove)(&dir,temp1);
+ if (((dxattr.mode & S_IFMT) != S_IFDIR) || denyaccess(&dxattr, S_IWOTH)) {
+ DEBUG(("Fdelete(%s): write access to directory denied", name));
+ release_cookie(&dir);
+ return EACCDN;
+ }
+
+/* if sticky bit set and directory isn't ours, we need some more checks */
+ if ((dxattr.mode & S_ISVTX) && (curproc->euid != dxattr.uid)) {
+
+ if ((r = relpath2cookie(&dir, temp1, 0, &fc, 0))) {
+ DEBUG(("Fdelete(%s): error %ld, perhaps file not found", name, r));
+ release_cookie(&dir);
+ return r;
+ }
+
+/* check ownership of the file */
+ if ((r = (fc.fs->getxattr)(&fc, &fxattr))) {
+ DEBUG(("Fdelete(%s): can't get file attributes", name));
+ release_cookie(&fc);
+ release_cookie(&dir);
+ return r;
+ }
+
+ if (curproc->euid != fxattr.uid) {
+ DEBUG(("Fdelete(%s): write access to file denied", name));
+ release_cookie(&fc);
+ release_cookie(&dir);
+ return EACCDN;
+ }
+
+ release_cookie(&fc);
}
+
+/* actually delete the file */
+ if ((r = (*dir.fs->remove)(&dir,temp1)))
+ DEBUG(("Fdelete(%s): error %ld", name, r));
+
release_cookie(&dir);
+
return r;
}
long ARGS_ON_STACK
f_rename(junk, old, new)