Changeset 15146


Ignore:
Timestamp:
Dec 19, 2011, 9:13:29 PM (8 years ago)
Author:
gb
Message:

Optionally use environment variables to initilize CCL's notion of
some filesystem paths, if CCL:*TRUST-PATHS-FROM-ENVIRONMENT* is true
(as it is by default.)

Specifically:

  • on Unix systems (including Android), try to use the value of the "HOME" environment variable to initialize (USER-HOMEDIR-PATHNAME).
  • On Android (only) for now, make TEMP-PATHNAME try to use the value of TMPDIR if the directory component of the value returned by #_tmpnam doesn't exist. (It seems to be "/tmp", which would make sense if /tmp existed on Android.)

It's possible that someone might have "HOME" set incorrectly, and that
trusting (easily spoofed) environment variables opens security
vulnerabilities. (The glibc docs mention the latter possibility, then
note that env variables are usually used because of their convenience.)

Fixes ticket:892 and fixes ticket:893.

Location:
trunk/source
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/level-1/linux-files.lisp

    r15083 r15146  
    234234          (return i))))))
    235235
     236(defparameter *trust-paths-from-environment* t
     237  "When true (as it is by default), environment variables can be used
     238to initialize CCL's notion of some filesystem paths.  This may expose
     239CCL or your application to greater security risks in some cases; if you're
     240concerned about that, you may want to save an image with this variable
     241set to NIL.")
     242
     243
    236244(defun temp-pathname ()
    237245  "Return a suitable pathname for a temporary file.  A different name is returned
     
    239247checked, though no guarantee is given that one hasn't been created since."
    240248  (native-to-pathname
    241      #-windows-target (get-foreign-namestring (#_tmpnam (%null-ptr)))
     249     #-windows-target
     250     #-android-target (get-foreign-namestring (#_tmpnam (%null-ptr)))
     251     #+android-target
     252     ;; Android dutifully implements #_tmpnam and returns a namestring
     253     ;; in /tmp, but of course they don't usually provide /tmp .
     254     (let* ((s (get-foreign-namestring (#_tmpnam (%null-ptr)))))
     255       (if (probe-file (make-pathname :directory (pathname-directory s) :defaults nil))
     256         s
     257         (let* ((dirname (or (and *trust-paths-from-environment*
     258                                  (let* ((p (getenv "TMPDIR")))
     259                                    (and p
     260                                         (eq (nth-value 1 (%probe-file-x p))
     261                                             :directory)
     262                                         p)))
     263                             "/data/local/tmp"))
     264                (filename (make-string 8)))
     265           (loop
     266             (flet ((random-char ()
     267                      (let* ((n (random 62)))
     268                        (cond ((< n 10) (code-char (+ (char-code #\0) n)))
     269                              ((< n 36) (code-char (+ (char-code #\A) (- n 10))))
     270                              (t (code-char (+ (char-code #\a) (- n 36))))))))
     271               (dotimes (i (length filename))
     272                 (setf (schar filename i) (random-char)))
     273               (let* ((path (make-pathname :name filename :directory dirname :defaults nil)))
     274                 (unless (probe-file path)
     275                   (return (namestring path)))))))))
    242276     #+windows-target (rlet ((buffer (:array :wchar_t #.#$MAX_PATH)))
    243277                        (#_GetTempPathW #$MAX_PATH buffer)
     
    245279                            (#_GetTempFileNameW buffer c-prefix 0 buffer)
    246280                              (#_DeleteFileW buffer)
    247                                 (%get-native-utf-16-cstring buffer)))))
     281                              (%get-native-utf-16-cstring buffer)))))
    248282
    249283(defun current-directory-name ()
     
    902936          (return (get-foreign-namestring p))))))
    903937  #-windows-target
    904   #+android-target "/data/local" ; for now
    905   #-android-target
    906   (rlet ((pwd :passwd)
    907          (result :address pwd))
    908     (do* ((buflen 512 (* 2 buflen)))
    909          ()
    910       (%stack-block ((buf buflen))
    911         (let* ((err
    912                 #-solaris-target
    913                  (#_getpwuid_r userid pwd buf buflen result)
    914                  #+solaris-target
    915                  (external-call "__posix_getpwuid_r"
    916                                 :uid_t userid
    917                                 :address pwd
    918                                 :address buf
    919                                 :int buflen
    920                                 :address result
    921                                 :int)))
    922           (if (eql 0 err)
    923             (let* ((rp (%get-ptr result))
    924                    (dir (and (not (%null-ptr-p rp))
    925                              (get-foreign-namestring (pref rp :passwd.pw_dir)))))
    926               (return (if (and dir (eq (%unix-file-kind dir) :directory))
    927                         dir)))
    928             (unless (eql err #$ERANGE)
    929               (return nil))))))))
     938  (or (and *trust-paths-from-environment*
     939           (let* ((p (getenv "HOME")))
     940             (and p
     941                  (eq (nth-value 1 (%probe-file-x p)) :directory)
     942                  p)))
     943      #+android-target "/data/local" ; for now
     944      #-android-target
     945      (rlet ((pwd :passwd)
     946             (result :address pwd))
     947        (do* ((buflen 512 (* 2 buflen)))
     948             ()
     949          (%stack-block ((buf buflen))
     950            (let* ((err
     951                    #-solaris-target
     952                     (#_getpwuid_r userid pwd buf buflen result)
     953                     #+solaris-target
     954                     (external-call "__posix_getpwuid_r"
     955                                    :uid_t userid
     956                                    :address pwd
     957                                    :address buf
     958                                    :int buflen
     959                                    :address result
     960                                    :int)))
     961              (if (eql 0 err)
     962                (let* ((rp (%get-ptr result))
     963                       (dir (and (not (%null-ptr-p rp))
     964                                 (get-foreign-namestring (pref rp :passwd.pw_dir)))))
     965                  (return (if (and dir (eq (%unix-file-kind dir) :directory))
     966                            dir)))
     967                (unless (eql err #$ERANGE)
     968                  (return nil)))))))))
    930969
    931970(defun %delete-file (name)
  • trunk/source/lib/ccl-export-syms.lisp

    r15141 r15146  
    323323     directoryp
    324324     delete-directory
     325     *trust-paths-from-environment*
    325326
    326327
Note: See TracChangeset for help on using the changeset viewer.