Batch/At (if it wasn't broken, no worries I broke it :-) )
YONETANI Tomokazu
qhwt+dfly at les.ath.cx
Mon Sep 4 08:36:47 PDT 2006
On Mon, Sep 04, 2006 at 12:36:28PM +0000, Jamie wrote:
> I don't know if batch was broken or not, but I couldn't get it to
> work on my setup.
>
> I patched it, removed the macros and replaced them with functions
> (to make debugging easier) as well as set a mode flag, so that
> entering priv_start() twice would return the second time without
> doing anything.
Actually, it's the fopen() in check_permission() that's tickling
something. I attached a small C code to demonstrate this. On DragonFly
(confirmed on 1.6 and 1.7), if you don't close a file descriptor you opened
right after the first setreuid(real_uid, effective_uid), the second one
with the same argument fails, whether you close the descriptor or not.
If you move the close() before the setreuid() above it and the program
succeeds.
I tried this program on a machine running FreeBSD 4.9-RELEASE, but no error
occurred, so there must be a difference in the kernel or the library.
/*
* usage:
* $ gcc -W -Wall at.c
* $ su
* # chown root a.out; chmod u+s a.out
* # exit
* $ ./a.out
*/
#include <err.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#define CHECK(expr) \
if ((expr) != 0) \
err(1, #expr)
int
main()
{
uid_t real_uid, effective_uid;
int fd;
real_uid = getuid();
effective_uid = geteuid();
CHECK(setreuid(effective_uid, real_uid));
CHECK(setreuid(real_uid, effective_uid));
fd = open("/etc/hosts", O_RDONLY);
CHECK(setreuid(effective_uid, real_uid));
close(fd), fd = -1; /* move this above the previous line */
CHECK(setreuid(real_uid, effective_uid));
printf("uid %d, euid %d\n", getuid(), geteuid());
CHECK(setreuid(effective_uid, real_uid));
return 0;
}
More information about the Kernel
mailing list