lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130508100143.GA6131@dyad.programming.kicks-ass.net>
Date:	Wed, 8 May 2013 12:01:43 +0200
From:	Peter Zijlstra <peterz@...radead.org>
To:	Sasha Levin <sasha.levin@...cle.com>
Cc:	torvalds@...ux-foundation.org, mingo@...nel.org,
	linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/9] liblockdep: Wrap kernel/lockdep.c to allow usage
 from userspace

On Tue, Apr 30, 2013 at 02:54:33PM -0400, Sasha Levin wrote:
> diff --git a/tools/lib/lockdep/common.c b/tools/lib/lockdep/common.c
> new file mode 100644
> index 0000000..eb5e481
> --- /dev/null
> +++ b/tools/lib/lockdep/common.c
> @@ -0,0 +1,33 @@
> +#include <stddef.h>
> +#include <stdbool.h>
> +#include <linux/compiler.h>
> +#include <linux/lockdep.h>
> +#include <unistd.h>
> +#include <sys/syscall.h>
> +
> +static struct task_struct current_obj;
> +
> +/* lockdep wants these */
> +bool debug_locks = true;
> +bool debug_locks_silent;
> +
> +__attribute__((constructor)) static void liblockdep_init(void)
> +{
> +	lockdep_init();
> +}
> +
> +__attribute__((destructor)) static void liblockdep_exit(void)
> +{
> +	debug_check_no_locks_held(&current_obj);
> +}
> +
> +struct task_struct *__curr(void)
> +{
> +	if (current_obj.pid == 0) {
> +		/* Makes lockdep output pretty */
> +		prctl(PR_GET_NAME, current_obj.comm);
> +		current_obj.pid = syscall(__NR_gettid);
> +	}
> +
> +	return &current_obj;
> +}

> diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
> new file mode 100644
> index 0000000..8e9a5c4
> --- /dev/null
> +++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
> @@ -0,0 +1,58 @@
> +#ifndef _LIBLOCKDEP_LOCKDEP_H_
> +#define _LIBLOCKDEP_LOCKDEP_H_
> +
> +#include <sys/prctl.h>
> +#include <sys/syscall.h>
> +#include <string.h>
> +#include <limits.h>
> +#include <linux/utsname.h>
> +
> +
> +#define MAX_LOCK_DEPTH 2000UL
> +
> +#include "../../../include/linux/lockdep.h"
> +
> +struct task_struct {
> +	u64 curr_chain_key;
> +	int lockdep_depth;
> +	unsigned int lockdep_recursion;
> +	struct held_lock held_locks[MAX_LOCK_DEPTH];
> +	gfp_t lockdep_reclaim_gfp;
> +	int pid;
> +	char comm[17];
> +};
> +
> +extern struct task_struct *__curr(void);
> +
> +#define current (__curr())
> +
> +#define debug_locks_off() 1
> +#define task_pid_nr(tsk) ((tsk)->pid)
> +
> +#define KSYM_NAME_LEN 128
> +#define printk printf
> +
> +#define KERN_ERR
> +#define KERN_CONT
> +
> +#define list_del_rcu list_del
> +
> +#define atomic_t unsigned long
> +#define atomic_inc(x) ((*(x))++)
> +
> +static struct new_utsname *init_utsname(void)
> +{
> +	static struct new_utsname n = (struct new_utsname) {
> +		.release = "liblockdep",
> +		.version = LIBLOCKDEP_VERSION,
> +	};
> +
> +	return &n;
> +}
> +
> +#define print_tainted() ""
> +#define static_obj(x) 1
> +
> +#define debug_show_all_locks()
> +
> +#endif

I don't see how this could possible work for threaded programs; you only have a
single task_struct instance. Wouldn't you need something like the below?

---

static int (*pthread_create_orig)(pthread_t *__restrict,
		__const pthread_attr_t *__restrict,
		void *(*)(void *),
		void *__restrict) = NULL;


static __thread struct task_struct __current;

#define current (&__current)

static void sched_fork(void)
{
	/* init __current */
}

__attribute__((constructor)) static void sched_init(void) 
{
	pthread_create_orig = dlsym(RTLD_NEXT, "pthread_create");
	if (!pthread_create_orig) {
		char *error = dlerror();
		if (!error)
			error = "pthread_create is NULL";
		die("%s\n", error);
	}

	sched_fork(); /* main thread */
}

__attribute__((destructor)) static void sched_exit(void)
{
	/* */
}

struct tramp_data {

	void *(*func)(void *);
	void *arg;

	pthread_mutex_t lock;
	pthread_cond_t  wait;
};

static void *tramp_func(void *data)
{
	struct tramp_data *tramp_data = data;
	void *(*func)(void *) = tramp_data->func;
	void *arg = tramp_data->arg;

	sched_fork();

	pthread_mutex_lock(&tramp_data->lock);
	pthread_cond_signal(&tramp_data->wait);
	pthread_mutex_unlock(&tramp_data->lock);

	return func(arg);
}

/* hijack pthread_create() */
int pthread_create(pthread_t *__restrict thread,
		__const pthread_attr_t *__restrict attr,
		void *(*func)(void *),
		void *__restrict arg)
{
	struct tramp_data tramp_data = {
		.func = func,
		.arg = arg,
	};
	int ret;

	pthread_cond_init(&tramp_data.wait, NULL);
	pthread_mutex_init(&tramp_data.lock, NULL);

	pthread_mutex_lock(&tramp_data.lock);

	ret = pthread_create_orig(thread, attr, &tramp_func, &tramp_data);
	if (!ret)
		pthread_cond_wait(&tramp_data.wait, &tramp_data.lock);

	pthread_mutex_unlock(&tramp_data.lock);

	pthread_mutex_destroy(&tramp_data.lock);
	pthread_cond_destroy(&tramp_data.wait);

	return ret;
} 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ