summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/txr/stdlib/path-test.tl27
-rw-r--r--txr.136
2 files changed, 41 insertions, 22 deletions
diff --git a/share/txr/stdlib/path-test.tl b/share/txr/stdlib/path-test.tl
index 77384fa3..3a7146a8 100644
--- a/share/txr/stdlib/path-test.tl
+++ b/share/txr/stdlib/path-test.tl
@@ -114,25 +114,36 @@
(sys:path-test (s stat path)
(let ((m s.mode)
(euid (geteuid)))
- (mlet ((g (getgrgid s.gid)))
- (and (eql euid s.uid)
+ (mlet ((g (getgrgid s.gid))
+ (name (let ((pw (getpwuid euid)))
+ (if pw pw.name)))
+ (suname (let ((pw (getpwuid 0)))
+ (if pw pw.name))))
+ (and (or (zerop s.uid)
+ (eql euid s.uid))
(zerop (logand m s-iwoth))
(or (zerop (logand m s-iwgrp))
(null g.mem)
- (and (not (rest g.mem))
- (equal (getpwuid euid).name (first g.mem)))))))))
+ (and (all g.mem (orf (op equal name)
+ (op equal suname))))))))))
(defun path-strictly-private-to-me-p (path)
(sys:path-test (s stat path)
(let ((m s.mode)
(euid (geteuid)))
- (mlet ((g (getgrgid s.gid)))
- (and (eql euid s.uid)
+ (mlet ((g (getgrgid s.gid))
+ (name (let ((pw (getpwuid euid)))
+ (if pw pw.name)))
+ (suname (let ((pw (getpwuid 0)))
+ (if pw pw.name))))
+ (and (or (zerop s.uid)
+ (eql euid s.uid))
(zerop (logand m (logior s-iroth s-iwoth)))
(or (zerop (logand m (logior s-iroth s-iwgrp)))
(null g.mem)
- (and (not (rest g.mem))
- (equal (getpwuid euid).name (first g.mem)))))))))
+ (and (all g.mem (orf (op equal name)
+ (op equal suname))))))))))
+
(defmacro sys:path-examine ((sym statfun path) . body)
^[sys:do-path-test ,statfun ,path
diff --git a/txr.1 b/txr.1
index 50e61627..081a8a2f 100644
--- a/txr.1
+++ b/txr.1
@@ -53870,8 +53870,8 @@ The rules which the function applies are as follows:
A file to be examined is initially assumed to be strictly private.
-If the file is not owned by the effective user ID of the caller, then
-it is not private.
+If the file is not owned by the effective user ID of the caller, or
+else by the superuser, then it is not private.
If the file grants write permission to "others", then it is not private.
@@ -53879,12 +53879,12 @@ If the file grants read permission to "others", then it is not strictly
private.
If the file grants write permission to the group owner, then it is not
-private, unless either the group is empty, or else the group has exactly one
-member, who is the owner of the file.
+private if the group contains names other than that of the file owner or the
+superuser.
If the file grants read permission to the group owner, then it is not
-strictly private, unless either the group is empty, or else the group has
-exactly one member, who is the owner of the file.
+strictly private if the group contains names other than that of the file owner
+or the superuser.
Note that this interpretation of "private" and "strictly private" is vulnerable
to the following time-of-check to time-of-use race condition with regard to the
@@ -53898,15 +53898,23 @@ race if
.meta path
is a string rather than a
.code stat
-structure. If the directory which contains the file is writable to others, the
-file can pass the check at the time the function is called, but before it is
-used, the file can be replaced by another file with different permissions.
-To guard against this race, one must open the file, and then use
+structure. If any components of the
+.meta path
+are symbolic links or directories that can be manipulated by other
+users, then the object named by
+.meta path
+file can pass the check, but can later
+.meta path
+can be subverted to refer to a different object.
+
+One way to guard against this race is to open the file, then use
.code fstat
-on the stream, using the structure returned by fstat to perform the check,
-with the understanding that it applies only to the open file, and not
-necessarily to whatever object may now be retrieved by the original
-directory entry.
+on the stream to obtain a
+.code stat
+structure which is then used as an argument to
+.code path-private-to-me-p
+or
+.codn path-strictly-private-to-me-p .
.coNP Functions @ path-newer and @ path-older
.synb