From: Richard M Kreuter Date: Thu, 10 Jan 2008 01:48:12 +0000 (+0000) Subject: 1.0.13.19: Odds and ends (OpenBSD NEWS, minor bug in PROBE-FILE, mkstemp()) X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=77d46c398278c0bbe221722c21c01d47713cd878;p=sbcl.git 1.0.13.19: Odds and ends (OpenBSD NEWS, minor bug in PROBE-FILE, mkstemp()) * Add note about OpenBSD revival in NEWS * PROBE-FILE, TRUENAME were returning an extra value from filename parsing * Have our internal mkstemp() binding take a mode, and remove unix-chmod from sb-unix. This slightly improves RUN-PROGRAM security on Unix platforms where mkstemp() doesn't create a new file with mode #o0600. --- diff --git a/NEWS b/NEWS index 74c2788..f2af05e 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ ;;;; -*- coding: utf-8; -*- changes in sbcl-1.0.14 relative to sbcl-1.0.13: + * Revived support for OpenBSD (contributed by Josh Elsasser) * bug fix: RESOLVE-CONFLICT (and the other name conflict machinery) is now actually exported from SB-EXT as documented. (reported by Maciej Katafiasz) diff --git a/package-data-list.lisp-expr b/package-data-list.lisp-expr index 646947b..e100300 100644 --- a/package-data-list.lisp-expr +++ b/package-data-list.lisp-expr @@ -2131,6 +2131,7 @@ no guarantees of interface stability." "UID-USERNAME" "UID-HOMEDIR" "WITH-RESTARTED-SYSCALL" + "SB-MKSTEMP" ;; stuff with a one-to-one mapping to Unix constructs "D-INO" "D-NAME" "D-NAMLEN" "D-OFF" "D-RECLEN" "DEV-T" "DIRECT" @@ -2149,7 +2150,7 @@ no guarantees of interface stability." "RU-STIME" "RU-UTIME" "RUSAGE_CHILDREN" "RUSAGE_SELF" "RUSEAGE" "R_OK" "S-IEXEC" "S-IFBLK" "S-IFCHR" "S-IFDIR" "S-IFLNK" "S-IFMT" "S-IFREG" "S-IFSOCK" "S-IREAD" "S-ISGID" "S-ISUID" "S-ISVTX" - "S-IWRITE" "SAVETEXT" "SC-MASK" "SC-ONSTACK" "SC-PC" "SETGIDEXEC" + "S-IWRITE" "SAVETEXT" "SB-MKSTEMP" "SC-MASK" "SC-ONSTACK" "SETUIDEXEC" "SG-ERASE" "SG-FLAGS" "SG-ISPEED" "SG-KILL" "SG-OSPEED" "SGTTYB" "SIZE-T" "ST-ATIME" "ST-BLKSIZE" "ST-BLOCKS" "ST-CTIME" "ST-DEV" "ST-GID" "ST-MODE" "ST-MTIME" "ST-NLINK" @@ -2157,12 +2158,12 @@ no guarantees of interface stability." "TIMEVAL" "TIMEZONE" "TIOCFLUSH" "TIOCGETC" "TIOCGETP" "TIOCGLTC" "TIOCGPGRP" "TIOCGWINSZ" "TIOCNOTTY" "TIOCSETC" "TIOCSETP" "TIOCSLTC" "TIOCSPGRP" "TIOCSWINSZ" "TV-SEC" "TV-USEC" - "TZ-DSTTIME" "TZ-MINUTESWEST" "UID-T" "UNIX-CHMOD" "UNIX-CLOSE" + "TZ-DSTTIME" "TZ-MINUTESWEST" "UID-T" "UNIX-CLOSE" "UNIX-DUP""UNIX-EXIT" "UNIX-FILE-MODE" "UNIX-FSTAT" "UNIX-GETHOSTNAME" "UNIX-GETPID" "UNIX-GETRUSAGE" "UNIX-GETTIMEOFDAY" "UNIX-GETUID" "UNIX-GID" "UNIX-IOCTL" "UNIX-ISATTY" "UNIX-LSEEK" "UNIX-LSTAT" "UNIX-MKDIR" - "UNIX-MKSTEMP" "UNIX-OPEN" "UNIX-PATHNAME" "UNIX-PID" + "UNIX-OPEN" "UNIX-PATHNAME" "UNIX-PID" "UNIX-PIPE" "UNIX-READ" "UNIX-READLINK" "UNIX-REALPATH" "UNIX-RENAME" "UNIX-SELECT" "UNIX-STAT" "UNIX-UID" "UNIX-UNLINK" "UNIX-WRITE" diff --git a/src/code/filesys.lisp b/src/code/filesys.lisp index cf4838b..9ac3ae3 100644 --- a/src/code/filesys.lisp +++ b/src/code/filesys.lisp @@ -522,22 +522,24 @@ (declare (ignore ino nlink gid rdev size atime)) (if existsp (case query-for - (:truename (parse-native-namestring - ;; Note: in case the file is stat'able, POSIX - ;; realpath(3) gets us a canonical absolute - ;; filename, even if the post-merge PATHNAME - ;; is not absolute... - (multiple-value-bind (realpath errno) - (sb!unix:unix-realpath filename) - (if realpath - realpath - (simple-file-perror "couldn't resolve ~A" - filename errno))) - (pathname-host pathname) - (sane-default-pathname-defaults) - ;; ... but without any trailing slash. - :as-directory (eql (logand mode sb!unix:s-ifmt) - sb!unix:s-ifdir))) + (:truename (nth-value + 0 + (parse-native-namestring + ;; Note: in case the file is stat'able, POSIX + ;; realpath(3) gets us a canonical absolute + ;; filename, even if the post-merge PATHNAME + ;; is not absolute... + (multiple-value-bind (realpath errno) + (sb!unix:unix-realpath filename) + (if realpath + realpath + (simple-file-perror "couldn't resolve ~A" + filename errno))) + (pathname-host pathname) + (sane-default-pathname-defaults) + ;; ... but without any trailing slash. + :as-directory (eql (logand mode sb!unix:s-ifmt) + sb!unix:s-ifdir)))) (:author (sb!unix:uid-username uid)) (:write-date (+ unix-to-universal-time mtime))) (progn @@ -577,25 +579,27 @@ ;; re-merge against *DEFAULT-PATHNAME-DEFAULTS*, ;; since PATHNAME may be a relative pathname. (merge-pathnames - (parse-native-namestring - (multiple-value-bind (realpath errno) - (sb!unix:unix-realpath - (native-namestring - (make-pathname - :name :unspecific - :type :unspecific - :version :unspecific - :defaults (parse-native-namestring - filename - (pathname-host pathname) - (sane-default-pathname-defaults))))) - (if realpath - realpath - (simple-file-perror "couldn't resolve ~A" - filename errno))) - (pathname-host pathname) - (sane-default-pathname-defaults) - :as-directory t) + (nth-value + 0 + (parse-native-namestring + (multiple-value-bind (realpath errno) + (sb!unix:unix-realpath + (native-namestring + (make-pathname + :name :unspecific + :type :unspecific + :version :unspecific + :defaults (parse-native-namestring + filename + (pathname-host pathname) + (sane-default-pathname-defaults))))) + (if realpath + realpath + (simple-file-perror "couldn't resolve ~A" + filename errno))) + (pathname-host pathname) + (sane-default-pathname-defaults) + :as-directory t)) pathname)) (:author (sb!unix:uid-username uid)) (:write-date (+ unix-to-universal-time mtime)))))) diff --git a/src/code/run-program.lisp b/src/code/run-program.lisp index 1a928fd..22fcfdb 100644 --- a/src/code/run-program.lisp +++ b/src/code/run-program.lisp @@ -921,14 +921,10 @@ Users Manual for details about the PROCESS structure."#-win32" ;; run afoul of disk quotas or to choke on small /tmp file systems. (flet ((make-temp-fd () (multiple-value-bind (fd name/errno) - (sb-unix:unix-mkstemp "/tmp/.run-program-XXXXXX") + (sb-unix:sb-mkstemp "/tmp/.run-program-XXXXXX" #o0600) (unless fd (error "could not open a temporary file: ~A" (strerror name/errno))) - #-win32 #|FIXME: should say (logior s_irusr s_iwusr)|# - (unless (sb-unix:unix-chmod name/errno #o600) - (sb-unix:unix-close fd) - (error "failed to chmod the temporary file?!")) (unless (sb-unix:unix-unlink name/errno) (sb-unix:unix-close fd) (error "failed to unlink ~A" name/errno)) diff --git a/src/code/unix.lisp b/src/code/unix.lisp index be73122..a26a951 100644 --- a/src/code/unix.lisp +++ b/src/code/unix.lisp @@ -180,16 +180,22 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted." ;;;; stdlib.h ;;; There are good reasons to implement some OPEN options with an -;;; mkstemp(3) followed by a fchmod(2) followed by a rename(2), but we -;;; don't do that yet. Instead, this function is used only to make a -;;; temporary file for RUN-PROGRAM. sb_mkstemp() is a wrapper that -;;; lives in src/runtime/wrap.c. -(defun unix-mkstemp (template-string) +;;; mkstemp(3)-like routine, but we don't do that yet. Instead, this +;;; function is used only to make a temporary file for RUN-PROGRAM. +;;; sb_mkstemp() is a wrapper that lives in src/runtime/wrap.c. Since +;;; SUSv3 mkstemp() doesn't specify the mode of the created file and +;;; since we have to implement most of this ourselves for Windows +;;; anyway, it seems worthwhile to depart from the mkstemp() +;;; specification by taking a mode to use when creating the new file. +(defun sb-mkstemp (template-string mode) + (declare (type string template-string) + (type unix-file-mode mode)) (let ((template-buffer (string-to-octets template-string))) (with-pinned-objects (template-buffer) (let ((fd (alien-funcall (extern-alien "sb_mkstemp" - (function int (* char))) - (vector-sap template-buffer)))) + (function int (* char) int)) + (vector-sap template-buffer) + mode))) (if (minusp fd) (values nil (get-errno)) (values fd (octets-to-string template-buffer))))))) @@ -761,17 +767,6 @@ SYSCALL-FORM. Repeat evaluation of SYSCALL-FORM if it is interrupted." (syscall ("fstat_wrapper" int (* (struct wrapped_stat))) (%extract-stat-results (addr buf)) fd (addr buf)))) - -;;; RUN-PROGRAM creates temporary files with mkstemp, but SUSv3 -;;; doesn't specify the mode of a newly created file under mkstemp, -;;; and C libraries may vary, so we fix the mode ourselves. -;;; Eventually some OPEN actions should probably be implemented with -;;; mkstemp(3)/chmod(2)/rename(2) as well. -#!-win32 -(defun unix-chmod (path mode) - (declare (type unix-pathname path) - (type unix-file-mode mode)) - (void-syscall ("chmod" c-string int) path mode)) ;;;; time.h diff --git a/src/runtime/wrap.c b/src/runtime/wrap.c index a510702..8e17e37 100644 --- a/src/runtime/wrap.c +++ b/src/runtime/wrap.c @@ -34,6 +34,8 @@ #include #include #include +#include + #ifndef LISP_FEATURE_WIN32 #include #include @@ -43,7 +45,6 @@ #if defined(LISP_FEATURE_WIN32) #define WIN32_LEAN_AND_MEAN -#include #include #endif @@ -282,16 +283,31 @@ fstat_wrapper(int filedes, struct stat_wrapper *buf) return ret; } -/* A wrapper for mkstemp(3), which seems not to exist on Windows. */ -int sb_mkstemp (char *template) { +/* A wrapper for mkstemp(3), for two reasons: (1) mkstemp does not + exist on Windows; (2) by passing down a mode_t, we don't need a + binding to chmod in SB-UNIX, and need not concern ourselves with + umask issues if we want to use mkstemp to make new files in + OPEN. */ +int sb_mkstemp (char *template, mode_t mode) { #ifdef LISP_FEATURE_WIN32 +#define PATHNAME_BUFFER_SIZE MAX_PATH +#define MKTEMP _mktemp +#else +#define PATHNAME_BUFFER_SIZE PATH_MAX +#define MKTEMP mktemp +#endif int fd; - char buf[MAX_PATH]; + char buf[PATHNAME_BUFFER_SIZE]; while (1) { + /* Fruit fallen from the tree: for people who like + microoptimizations, we might not need to copy the whole + template on every loop, but only the last several characters. + But I didn't feel like testing the boundary cases in Windows's + _mktemp. */ strcpy((char*)&buf, template); - if (_mktemp((char*)&buf)) { - if ((fd=open((char*)&buf, O_CREAT|O_EXCL|O_RDWR, S_IRUSR|S_IWUSR))!=-1) { + if (MKTEMP((char*)&buf)) { + if ((fd=open((char*)&buf, O_CREAT|O_EXCL|O_RDWR, mode))!=-1) { strcpy(template, (char*)&buf); return (fd); } else @@ -300,9 +316,8 @@ int sb_mkstemp (char *template) { } else return (-1); } -#else - return(mkstemp(template)); -#endif +#undef MKTEMP +#undef PATHNAME_BUFFER_SIZE } diff --git a/version.lisp-expr b/version.lisp-expr index 29c6535..4825adf 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.13.18" +"1.0.13.19"