mock/src mock.c,NONE,1.1 Makefile,1.2,1.3
John Clark Williams (jcwillia)
fedora-extras-commits at redhat.com
Wed Jun 28 15:14:49 UTC 2006
Author: jcwillia
Update of /cvs/fedora/mock/src
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv31610/src
Modified Files:
Makefile
Added Files:
mock.c
Log Message:
updated version to 0.7 (new launcher mechanism)
--- NEW FILE mock.c ---
//
// mock.c - setuid program for launching mock.py
//
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Library General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// Copyright (c) 2006 - Clark Williams <williams at redhat.com>
// portions lifted from mock-helper.c by Seth Vidal
// namespace idea courtesy Enrico Scholz <enrico.scholz at informatik.tu-chemnitz.de>
//#define _GNU_SOURCE
#include "config.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <sched.h>
#include <assert.h>
#include <asm/unistd.h>
#include <signal.h>
#if 0
#ifdef USE_SELINUX
#include <selinux/selinux.h>
#endif
#endif
#define PYTHON_PATH "/usr/bin/python"
#define MOCK_PATH "/usr/bin/mock.py"
static char const * const ALLOWED_ENV[] =
{
"dist",
"ftp_proxy",
"http_proxy",
"https_proxy",
"no_proxy",
"PS1",
};
#define ALLOWED_ENV_SIZE (sizeof (ALLOWED_ENV) / sizeof (ALLOWED_ENV[0]))
#define SAFE_PATH "PATH=/bin:/usr/bin:/usr/sbin"
#define SAFE_HOME "HOME=/root"
#define NSFLAG "NAMESPACE=1"
// Note that MAX_ENV_SIZE is allowed size, plus the ones we add plus a null entry
// so, if you add more variables, increase the constant below!
#define MAX_ENV_SIZE 4 + ALLOWED_ENV_SIZE
//
// helper functions
//
//
// print formatted string to stderr and terminate
//
void error (const char *format, ...)
{
va_list ap;
va_start (ap, format);
fprintf (stderr, "mock: error: ");
vfprintf (stderr, format, ap);
va_end (ap);
fprintf (stderr, "\n");
exit (1);
}
//
// debug print
//
static int debugging = 0;
void debug(const char *format, ...)
{
if (debugging) {
va_list ap;
va_start (ap, format);
fprintf (stderr, "DEBUG: ");
vfprintf (stderr, format, ap);
va_end (ap);
}
}
///////////////////////////////////////////
//
// main logic
//
//////////////////////////////////////////
int main (int argc, char **argv)
{
char * env[MAX_ENV_SIZE+1] = {
[0] = SAFE_PATH,
[1] = SAFE_HOME,
[2] = NSFLAG,
};
char **newargv;
int newargc, newargvsz;
int i, idx = 2;
int status;
pid_t pid;
if (getenv("MOCKDEBUG"))
debugging = 1;
// copy in allowed environment variables to our environment
debug("copying envionment\n");
for (i = 0; i < ALLOWED_ENV_SIZE; ++i) {
char *ptr = getenv (ALLOWED_ENV[i]);
if (ptr==0) continue;
ptr -= strlen (ALLOWED_ENV[i]) + 1;
env[idx++] = ptr;
}
assert(idx <= MAX_ENV_SIZE);
env[idx] = NULL;
// set up a new argv/argc
// new argv[0] will be "/usr/bin/python"
// new argv[1] will be "/usr/bin/mock.py"
// remainder of new argv will be old argv[1:n]
// allocate one extra for null at end
newargc = argc + 1;
newargvsz = sizeof(char *) * (newargc + 1);
newargv = alloca(newargvsz);
newargv[0] = PYTHON_PATH;
debug("argv[0] = %s\n", newargv[0]);
newargv[1] = MOCK_PATH;
debug("argv[1] = %s\n", newargv[1]);
for (i = 1; i < argc; i++) {
newargv[i+1] = argv[i];
debug("argv[%d] = %s\n", i+1, newargv[i+1]);
}
newargv[newargc] = NULL;
// clone a new process with a separate namespace
// Note: we have to use syscall here, since we want the
// raw system call 'clone', not the glibc library wrapper
// Also note: The SIGCHLD or'ed into the flags argument. If you
// don't specify an exit signal, the child is detached and waitpid
// won't work (how the heck Enrico figured it out is beyond me, since
// there are only two mentions of CSIGNAL in fork.c...)
debug("cloning new namespace\n");
pid = syscall(__NR_clone, CLONE_VFORK|CLONE_NEWNS|SIGCHLD, 0);
// urk! no clone?
if (pid == -1)
error("clone failed: %s\n", strerror(errno));
// exec python
if (pid == 0) {
debug("exec'ing python\n");
execve(PYTHON_PATH, newargv, env);
error("execve failed: %s\n", strerror(errno));
}
// wait for the child to finish and exit appropriately
debug("waiting for child to finish\n");
if (waitpid(pid, &status, 0) != pid)
error("waitpid failed: %s\n", strerror(errno));
if (WIFEXITED(status)) {
debug("Exiting with status 0x%x (0x%x)\n", WEXITSTATUS(status), status);
exit(WEXITSTATUS(status));
}
if (WIFSIGNALED(status))
error("errored out with signal %d\n", WTERMSIG(status));
exit(-1); // WTF? how did we get here?
}
Index: Makefile
===================================================================
RCS file: /cvs/fedora/mock/src/Makefile,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- Makefile 17 Jun 2005 20:53:31 -0000 1.2
+++ Makefile 28 Jun 2006 15:14:46 -0000 1.3
@@ -1,32 +1,39 @@
-CC=gcc
-EXECUTABLE=mock-helper
-SBINDIR=/usr/sbin
-MOCKGROUP=mock
-DESTDIR=''
-INSTALL=/usr/bin/install
-MKDIR=/bin/mkdir
+CC := gcc
+CFLAGS := -O2 -g -Wall -Werror
+#DEBUG := -DDEBUG=1
+EXECUTABLE:= mock
+LIBRARY := libselinux-mock.so
+BINDIR := /usr/bin
+MOCKGROUP:= mock
+#DESTDIR := ''
+INSTALL := /usr/bin/install
+MKDIR := /bin/mkdir
ifndef NOSELINUX
SELINUXFLAGS=-DUSE_SELINUX=1 -lselinux
endif
ifneq (,$(filter ppc64 x86_64 s390x,$(shell uname -m)))
-LIBDIR = /usr/lib64
+LIBDIR := /usr/lib64
else
-LIBDIR = /usr/lib
+LIBDIR := /usr/lib
endif
-all:
- $(CC) $(CFLAGS) -o $(EXECUTABLE) mock-helper.c $(SELINUXFLAGS)
+all: $(EXECUTABLE) $(LIBRARY)
+
+$(LIBRARY): selinux-mock.o
+ $(LD) -shared -o $(LIBRARY) selinux-mock.o
+
+selinux-mock.o: selinux-mock.c
$(CC) $(CFLAGS) -fPIC -c selinux-mock.c
- $(LD) -shared -o libselinux-mock.so selinux-mock.o
+
+$(EXECUTABLE): mock.c
+ $(CC) $(CFLAGS) $(DEBUG) -o $@ $<
clean:
- rm -f $(EXECUTABLE)
+ rm -f $(EXECUTABLE) $(LIBRARY)
rm -f *~ *.bak *.o *.so
-install:
- $(MKDIR) -p $(DESTDIR)/$(SBINDIR) $(DESTDIR)/$(LIBDIR)
- $(INSTALL) -m 4750 $(EXECUTABLE) $(DESTDIR)/$(SBINDIR)/$(EXECUTABLE)
- $(INSTALL) -m 755 libselinux-mock.so $(DESTDIR)/$(LIBDIR)
-
+install: $(EXECUTABLE) $(LIBRARY)
+ $(INSTALL) -D -m 755 $(EXECUTABLE) $(DESTDIR)/$(BINDIR)/$(EXECUTABLE)
+ $(INSTALL) -D -m 755 $(LIBRARY) $(DESTDIR)/$(LIBDIR)/$(LIBRARY)
More information about the fedora-extras-commits
mailing list