⬢ DragonFlyBSD Kernel Audit
DF-2825 / lockf_neg.c
← back to finding ↓ download raw
/* DF-2825: negative l_len rejected with EINVAL instead of POSIX
 * [l_start+l_len, l_start-1] semantics.
 *
 * expect (vulnerable):  F_SETLK(start=10,len=-5) -> errno 22 EINVAL
 * expect (patched):    -> 0, and F_SETLK(start=5,len=5) conflicts with it
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

int
main(void)
{
	struct flock fl;
	int fd, rv;

	fd = open("/tmp/df2825.lock", O_RDWR | O_CREAT, 0600);

	memset(&fl, 0, sizeof(fl));
	fl.l_type = F_WRLCK;
	fl.l_whence = SEEK_SET;
	fl.l_start = 10;
	fl.l_len = -5;

	rv = fcntl(fd, F_SETLK, &fl);
	printf("DF2825 F_SETLK(start=10,len=-5) rv=%d errno=%d (%s)\n",
	    rv, errno, strerror(errno));

	/* cross-check: does the kernel hold a POSIX lock on [5,9]? */
	memset(&fl, 0, sizeof(fl));
	fl.l_type = F_WRLCK;
	fl.l_whence = SEEK_SET;
	fl.l_start = 5;
	fl.l_len = 5;
	rv = fcntl(fd, F_GETLK, &fl);
	printf("DF2825 F_GETLK[5..9] rv=%d l_type=%d (F_UNLCK=2 means no lock)\n",
	    rv, fl.l_type);

	return 0;
}