rad_unlockfd
Brian Candler
B.Candler at pobox.com
Sun May 12 16:16:42 CEST 2013
I noticed something odd in rad_unlockfd - both 2.x.x and master.
int rad_unlockfd(int fd, int lock_len)
{
...
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_CUR;
return fcntl(fd, F_UNLCK, (void *)&fl);
However, according to the Linux manpage for fcntl:
F_SETLK (struct flock *)
Acquire a lock (when l_type is F_RDLCK or F_WRLCK) or release a
lock (when l_type is F_UNLCK) on the bytes specified by the
l_whence, l_start, and l_len fields of lock. If a conflicting
lock is held by another process, this call returns -1 and sets
errno to EACCES or EAGAIN.
That is: to unlock, the command should be F_SETLK(W) and the l_type should
be F_UNLCK. The OSX (BSD) manpage agrees.
On Linux, the constant F_UNLCK is 2, so calling fcntl(fd, F_UNLCK...)
is the same as calling fcntl(fd, F_SETFD...)
The other oddity is using SEEK_CUR for both lock and unlock. If you have
written to the file in the mean time, then the current file offset will have
changed, so you may end up unlocking a different byte range to the one you
locked. I'd say SEEK_SET with offset 0 and length 0 (which locks or unlocks
the entire file, including past its end) is safest - at least when
unlocking.
As far as I can see, only rad_utmp calls this function, so the impact is not
huge.
Regards,
Brian.
More information about the Freeradius-Devel
mailing list