diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2013-03-02 13:05:52 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2013-03-02 13:05:52 -0800 |
commit | 2db41375423b6a48a55df2c5922bb2813319f06f (patch) | |
tree | 50c68274acb327e04705554b5828201ed63732f9 | |
parent | b5029e230d10ea412e4ff1d4867a0c884d130039 (diff) | |
download | emacs-2db41375423b6a48a55df2c5922bb2813319f06f.tar.gz |
* filelock.c (lock_file): Don't access freed storage.
-rw-r--r-- | src/ChangeLog | 1 | ||||
-rw-r--r-- | src/filelock.c | 49 |
2 files changed, 23 insertions, 27 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 7afae3df6f5..adff00f7189 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -27,6 +27,7 @@ that's not portable. (lock_file): Document that this function can return if lock creation fails. + (lock_file): Don't access freed storage. 2013-03-02 Andreas Schwab <schwab@linux-m68k.org> diff --git a/src/filelock.c b/src/filelock.c index d52e9faeb44..14b9d4aaca5 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -597,11 +597,9 @@ lock_if_free (lock_info_type *clasher, register char *lfname) void lock_file (Lisp_Object fn) { - register Lisp_Object attack, orig_fn, encoded_fn; - register char *lfname, *locker; - ptrdiff_t locker_size; + Lisp_Object orig_fn, encoded_fn; + char *lfname; lock_info_type lock_info; - printmax_t pid; struct gcpro gcpro1; USE_SAFE_ALLOCA; @@ -642,32 +640,29 @@ lock_file (Lisp_Object fn) call1 (intern ("ask-user-about-supersession-threat"), fn); } - UNGCPRO; - - /* Try to lock the lock. */ - if (lock_if_free (&lock_info, lfname) <= 0) - /* Return now if we have locked it, or if lock creation failed */ - return; - /* Else consider breaking the lock */ - locker_size = (strlen (lock_info.user) + strlen (lock_info.host) - + INT_STRLEN_BOUND (printmax_t) - + sizeof "@ (pid )"); - locker = SAFE_ALLOCA (locker_size); - pid = lock_info.pid; - esprintf (locker, "%s@%s (pid %"pMd")", - lock_info.user, lock_info.host, pid); - FREE_LOCK_INFO (lock_info); - - attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); - SAFE_FREE (); - if (!NILP (attack)) - /* User says take the lock */ + /* Try to lock the lock. */ + if (0 < lock_if_free (&lock_info, lfname)) { - lock_file_1 (lfname, 1); - return; + /* Someone else has the lock. Consider breaking it. */ + ptrdiff_t locker_size = (strlen (lock_info.user) + strlen (lock_info.host) + + INT_STRLEN_BOUND (printmax_t) + + sizeof "@ (pid )"); + char *locker = SAFE_ALLOCA (locker_size); + printmax_t pid = lock_info.pid; + Lisp_Object attack; + esprintf (locker, "%s@%s (pid %"pMd")", + lock_info.user, lock_info.host, pid); + FREE_LOCK_INFO (lock_info); + + attack = call2 (intern ("ask-user-about-lock"), fn, build_string (locker)); + /* Take the lock if the user said so. */ + if (!NILP (attack)) + lock_file_1 (lfname, 1); } - /* User says ignore the lock */ + + UNGCPRO; + SAFE_FREE (); } void |