[Patch]: Create Global Privilege
Pierre A. Humblet
pierre@phumblet.no-ip.org
Sat Dec 6 02:30:00 GMT 2003
At 02:54 PM 12/5/2003 +0100, Corinna Vinschen wrote:
>On Dec 5 08:02, Pierre A. Humblet wrote:
>> At 12:14 PM 12/5/2003 +0100, Corinna Vinschen wrote:
>> >Two questions:
>> >
>
>> >What is the advantage of using a finite loop with fcntl(F_SETLK) over
>> >using fcntl(F_SETLKW) just once? This seems potentially less secure
>> >than F_SETLKW and also less secure than the former Mutex solution.
>>
>> The only reason is that F_SETLKW doesn't work on 9X so you need
>> a loop there anyway. But thinking more about it, we should have both
>> F_SETLKW and a loop. On NT the loop will never kick in. On 9x F_SETLKW
>> works like F_SETLK and the loop is useful. The loop could also be made
>> much longer.
>
>I agree. Are you going to change your patch accordingly?
Sure, here it is. BTW, F_SETLKW is yucky, at least on NT4. Not only
the fcntl call isn't interruptible but the process itself can't be
killed with kill -9 while waiting. The sig thread itself waits during
the close() call in the exit sequence.
Also a thread can deadlock by locking overlapping file segments.
This is FYI, it doesn't matter greatly here.
Pierre
2003-12-06 Pierre Humblet <pierre.humblet@ieee.org>
* syscalls.cc (locked_append): New.
(updwtmp): Remove mutex code and call locked_append.
(pututline): Ditto.
-------------- next part --------------
Index: syscalls.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
retrieving revision 1.301
diff -u -p -r1.301 syscalls.cc
--- syscalls.cc 28 Nov 2003 20:55:58 -0000 1.301
+++ syscalls.cc 6 Dec 2003 01:06:35 -0000
@@ -2553,28 +2553,37 @@ ffs (int i)
return table[x >> a] + a;
}
+static void
+locked_append (int fd, const void * buf, size_t size)
+{
+ struct __flock64 lock_buffer = {F_WRLCK, SEEK_SET, 0, 0, 0};
+ int count = 0;
+
+ do
+ if ((lock_buffer.l_start = lseek64 (fd, 0, SEEK_END)) != (_off64_t)-1
+ && fcntl_worker (fd, F_SETLKW, &lock_buffer) != -1)
+ {
+ if (lseek64 (fd, 0, SEEK_END) != (_off64_t)-1)
+ write (fd, buf, size);
+ lock_buffer.l_type = F_UNLCK;
+ fcntl_worker (fd, F_SETLK, &lock_buffer);
+ break;
+ }
+ while (count++ < 1000
+ && (errno == EACCES || errno == EAGAIN)
+ && !usleep (1000));
+}
+
extern "C" void
updwtmp (const char *wtmp_file, const struct utmp *ut)
{
- /* Writing to wtmp must be atomic to prevent mixed up data. */
- char mutex_name[CYG_MAX_PATH];
- HANDLE mutex;
int fd;
- mutex = CreateMutex (NULL, FALSE, shared_name (mutex_name, "wtmp_mutex", 0));
- if (mutex)
- while (WaitForSingleObject (mutex, INFINITE) == WAIT_ABANDONED)
- ;
- if ((fd = open (wtmp_file, O_WRONLY | O_APPEND | O_BINARY, 0)) >= 0)
+ if ((fd = open (wtmp_file, O_WRONLY | O_BINARY, 0)) >= 0)
{
- write (fd, ut, sizeof *ut);
+ locked_append (fd, ut, sizeof *ut);
close (fd);
}
- if (mutex)
- {
- ReleaseMutex (mutex);
- CloseHandle (mutex);
- }
}
extern "C" void
@@ -2783,25 +2792,15 @@ pututline (struct utmp *ut)
ut->ut_type, ut->ut_pid, ut->ut_line, ut->ut_id);
debug_printf ("ut->ut_user '%s', ut->ut_host '%s'\n",
ut->ut_user, ut->ut_host);
- /* Read/write to utmp must be atomic to prevent overriding data
- by concurrent processes. */
- char mutex_name[CYG_MAX_PATH];
- HANDLE mutex = CreateMutex (NULL, FALSE,
- shared_name (mutex_name, "utmp_mutex", 0));
- if (mutex)
- while (WaitForSingleObject (mutex, INFINITE) == WAIT_ABANDONED)
- ;
+
struct utmp *u;
if ((u = getutid (ut)))
- lseek (utmp_fd, -sizeof *ut, SEEK_CUR);
- else
- lseek (utmp_fd, 0, SEEK_END);
- write (utmp_fd, ut, sizeof *ut);
- if (mutex)
{
- ReleaseMutex (mutex);
- CloseHandle (mutex);
+ lseek (utmp_fd, -sizeof *ut, SEEK_CUR);
+ write (utmp_fd, ut, sizeof *ut);
}
+ else
+ locked_append (utmp_fd, ut, sizeof *ut);
}
extern "C"
More information about the Cygwin-patches
mailing list