linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* linux capabilities ?
@ 2005-01-20 18:02 jnf
  2005-01-20 21:49 ` Chris Wright
  0 siblings, 1 reply; 5+ messages in thread
From: jnf @ 2005-01-20 18:02 UTC (permalink / raw)
  To: linux-kernel

Hi.

I have been playing a little here and there with linux capabilities, and
seem to be hitting a few snags so I was hoping to obtain some input on
their current status. The kernel on the box in question is 2.6.10, with
the CAP_INIT_EFF_SET macro modified to allow init to have CAP_SETPCAP.

I am mostly trying to accomplish this so that I can run syslog as a
non-root user and as I understand it by digging through the source, one
should be able to accomplish this with the CAP_SYS_ADMIN capability-
however this does not appear to be true ?

in kernel/printk.c I see

error = security_syslog(type)
if (error)
        return error ;

which is defined in something like include/linux/security.h as a pointer
to cap_syslog(), which in turn is defined in security/commoncap.c where I
see:

if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
         return -EPERM
return 0;


Type 3 is:
*      3 -- Read up to the last 4k of messages in the ring buffer.

So when I give the process CAP_SYS_ADMIN I still cannot seem to read from
/proc/kmsg, I also tried giving it CAP_DAC_OVERRIDE just to test to see if
DAC's were the problem but that didn't seem to help any.

So with that said, anyone have any idea's as to what I need to do and any
details on the current state of the capabilities would be helpful.

Thanks,

jnf



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: linux capabilities ?
  2005-01-20 18:02 linux capabilities ? jnf
@ 2005-01-20 21:49 ` Chris Wright
  2005-01-20 22:54   ` jnf
  0 siblings, 1 reply; 5+ messages in thread
From: Chris Wright @ 2005-01-20 21:49 UTC (permalink / raw)
  To: jnf; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 2273 bytes --]

* jnf (jnf@innocence-lost.us) wrote:
> I have been playing a little here and there with linux capabilities, and
> seem to be hitting a few snags so I was hoping to obtain some input on
> their current status. The kernel on the box in question is 2.6.10, with
> the CAP_INIT_EFF_SET macro modified to allow init to have CAP_SETPCAP.

This is not exactly safe.  It was removed on purpose.  See this paper:
http://www.cs.berkeley.edu/~daw/papers/setuid-usenix02.pdf

> I am mostly trying to accomplish this so that I can run syslog as a
> non-root user and as I understand it by digging through the source, one
> should be able to accomplish this with the CAP_SYS_ADMIN capability-
> however this does not appear to be true ?

BTW, CAP_SYS_ADMIN is a lot of privileges, so even this would not be as
secure as you might hope.

> in kernel/printk.c I see
> 
> error = security_syslog(type)
> if (error)
>         return error ;
> 
> which is defined in something like include/linux/security.h as a pointer
> to cap_syslog(), which in turn is defined in security/commoncap.c where I
> see:
> 
> if ((type != 3 && type != 10) && !capable(CAP_SYS_ADMIN))
>          return -EPERM
> return 0;
> 
> 
> Type 3 is:
> *      3 -- Read up to the last 4k of messages in the ring buffer.

3 doesn't require any permissions.  It's like doing 'dmesg.'

> So when I give the process CAP_SYS_ADMIN I still cannot seem to read from
> /proc/kmsg, I also tried giving it CAP_DAC_OVERRIDE just to test to see if
> DAC's were the problem but that didn't seem to help any.

Since /proc/kmsg is 0400 you need CAP_DAC_READ_SEARCH (don't necessarily
need full override).  Otherwise, you are right, you do need CAP_SYS_ADMIN.
Or just use syslog(2) directly, and you'll avoid the DAC requirement.

> So with that said, anyone have any idea's as to what I need to do and any
> details on the current state of the capabilities would be helpful.

The best way is to drop the caps from within the syslogd.  Otherwise
you will gain/lose all caps on execve() due to the way caps actually
effectively follow uids.  Here, I threw together an example of some
other bits of code I have laying around (run it as root).

thanks,
-chris
-- 
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net

[-- Attachment #2: read_syslog.c --]
[-- Type: text/x-c++src, Size: 2403 bytes --]

/* Copyright (c) Chris Wright <chrisw@osdl.org>
 * GPL v2
 * Drop uid/gid and caps and read syslog
 */
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <sys/capability.h>


static void usage(void)
{
	printf("Usage: read_syslog options\n");
	printf("-u uid\n -p {use /proc/kmsg (default)}\n -s {use syslog(2)}\n");
}

static void dumpcred(void)
{
	uid_t ruid, euid, suid;
	gid_t rgid, egid, sgid;
	cap_t caps = cap_get_proc();

	getresuid(&ruid, &euid, &suid);
	getresgid(&rgid, &egid, &sgid);

	printf("      Real    Eff    Saved\n");
	printf("User  %-8d%-8d%-8d\n", ruid, euid, suid);
	printf("Group %-8d%-8d%-8d\n", rgid, egid, sgid);

	if (caps)
	{
		char *p = cap_to_text(caps, NULL);
		if (p) {
			printf("Caps: %s\n\n", p);
			cap_free(p);
		}
		cap_free(caps);
	}
}

static int usecap(const char *caps)
{
	int rc = -1;
	cap_t capset = cap_from_text(caps);
	if (capset)
	{
		rc = cap_set_proc(capset);
		if (rc) {
			perror("cap_set_proc");
		}
		cap_free(capset);
	}
	return rc;
}

static int drop_privs(uid_t uid, gid_t gid, const char *caps)
{
	int rc;
	dumpcred();
	prctl(PR_SET_KEEPCAPS, 1);
	rc = setresgid(gid, gid, gid);
	if (rc == -1) {
		perror("setresgid");
		goto out;
	}
	rc = setresuid(uid, uid, uid);
	if (rc == -1) {
		perror("setresuid");
		goto out;
	}
	rc = usecap(caps);
	if (rc == -1) {
		perror("usecap");
		goto out;
	}
out:
	dumpcred();
	return rc;
}

main(int argc, char *argv[])
{
	uid_t new_uid = 500;
	gid_t new_gid = 500;
	int c, fd, rc, use_proc = 1;
	char *caps = "cap_dac_read_search,cap_sys_admin=ep";
	char buf[1024];

	while ((c = getopt(argc, argv, "u:g:ps")) != -1) {
		switch(c) {
		case 'u':
			new_uid = atoi(optarg);
			break;
		case 'g':
			new_gid = atoi(optarg);
			break;
		case 'p':
			/* default */
			break;
		case 's':
			use_proc = 0;
			caps = "cap_sys_admin=ep";
			break;
		default:
			usage();
			exit(1);
			break;
		}
	}

	memset(buf, 0, sizeof(buf));
	if (drop_privs(new_uid, new_gid, caps) == -1) {
		exit(1);
	}
	if (use_proc) {
		fd = open("/proc/kmsg", O_RDONLY);
		if (fd == -1) {
			perror("open");
			exit(1);
		}
		rc = read(fd, buf, sizeof(buf));
		if (rc == -1) {
			perror("read");
			exit(1);
		}
	} else {
		rc = syslog(2, buf, sizeof(buf));
		if (rc == -1) {
			perror("syslog");
			exit(1);
		}
	}
	printf("%s\n", buf);
}

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: linux capabilities ?
  2005-01-20 21:49 ` Chris Wright
@ 2005-01-20 22:54   ` jnf
  2005-01-21  0:23     ` Chris Wright
  2005-01-21 23:19     ` Olaf Dietsche
  0 siblings, 2 replies; 5+ messages in thread
From: jnf @ 2005-01-20 22:54 UTC (permalink / raw)
  To: Chris Wright; +Cc: linux-kernel

Hi Chris, thank you for the response.

>
> This is not exactly safe.  It was removed on purpose.  See this paper:
> http://www.cs.berkeley.edu/~daw/papers/setuid-usenix02.pdf

I will read the paper before commenting on it further, however I cannot
see what dangers it would really provide that a setuid program doesnt
already have- other than the ability to give another non-root process root
like abilities. However, the more I ponder it, it seems as if you could
accomplish a lot of things with a set of ACL's and Capabilities (think
compartmentalizing everything from each other where no one thing has full
control of anything other than its particular subsystem).

>
> BTW, CAP_SYS_ADMIN is a lot of privileges, so even this would not be as
> secure as you might hope.

Yes, I am fully aware of that, I had previously written in a current->uid
check as well to get around the capabilities problem, however it didn't
work so I took it out. Portability isn't as much as an issue as 'making it
work on this box'.

>
> 3 doesn't require any permissions.  It's like doing 'dmesg.'

Hrm, am I missing something? Oh wait, duh, I misread that line. ;]

> Since /proc/kmsg is 0400 you need CAP_DAC_READ_SEARCH (don't necessarily
> need full override).  Otherwise, you are right, you do need CAP_SYS_ADMIN.
> Or just use syslog(2) directly, and you'll avoid the DAC requirement.

Hrm, even a chmod of it didn't appear to really affect things?
I will investigate the CAP_DAC_READ_SEARCH and see how that works, I
appreciate the response.


> The best way is to drop the caps from within the syslogd.  Otherwise
> you will gain/lose all caps on execve() due to the way caps actually
> effectively follow uids.  Here, I threw together an example of some
> other bits of code I have laying around (run it as root).

Thank you, when I get a second I will take a look through it. I've already
written a couple programs to set/get capabilities, so I am aware of the
interface/api, it was just that even with the capabilities it was not
working ;]
Either way I will take a look through the code, I appreciate the reply.



> thanks,
> -chris
> --
> Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net
>

cheers,

jnf

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: linux capabilities ?
  2005-01-20 22:54   ` jnf
@ 2005-01-21  0:23     ` Chris Wright
  2005-01-21 23:19     ` Olaf Dietsche
  1 sibling, 0 replies; 5+ messages in thread
From: Chris Wright @ 2005-01-21  0:23 UTC (permalink / raw)
  To: jnf; +Cc: Chris Wright, linux-kernel

* jnf (jnf@innocence-lost.us) wrote:
> I will read the paper before commenting on it further, however I cannot
> see what dangers it would really provide that a setuid program doesnt
> already have- other than the ability to give another non-root process root
> like abilities. However, the more I ponder it, it seems as if you could

It was a dangerous failure mode when a capability isn't present that hit
sendmail.

> accomplish a lot of things with a set of ACL's and Capabilities (think
> compartmentalizing everything from each other where no one thing has full
> control of anything other than its particular subsystem).

Yes, that's the ideal.  Unfortunately it doesn't work out quite so
neatly ;-/

> > Since /proc/kmsg is 0400 you need CAP_DAC_READ_SEARCH (don't necessarily
> > need full override).  Otherwise, you are right, you do need CAP_SYS_ADMIN.
> > Or just use syslog(2) directly, and you'll avoid the DAC requirement.
> 
> Hrm, even a chmod of it didn't appear to really affect things?

Should, and it makes a difference for me.

thanks,
-chris
-- 
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: linux capabilities ?
  2005-01-20 22:54   ` jnf
  2005-01-21  0:23     ` Chris Wright
@ 2005-01-21 23:19     ` Olaf Dietsche
  1 sibling, 0 replies; 5+ messages in thread
From: Olaf Dietsche @ 2005-01-21 23:19 UTC (permalink / raw)
  To: jnf; +Cc: Chris Wright, linux-kernel

jnf <jnf@innocence-lost.us> writes:

> Thank you, when I get a second I will take a look through it. I've already
> written a couple programs to set/get capabilities, so I am aware of the
> interface/api, it was just that even with the capabilities it was not
> working ;]
> Either way I will take a look through the code, I appreciate the reply.

You might want to look at
<http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/capfaq-0.2.txt>

And in
<http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.4/libcap-1.10.tar.bz2>,
you will find some example programs: execcap, setpcaps and sucap.

Regards, Olaf.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-01-21 23:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-20 18:02 linux capabilities ? jnf
2005-01-20 21:49 ` Chris Wright
2005-01-20 22:54   ` jnf
2005-01-21  0:23     ` Chris Wright
2005-01-21 23:19     ` Olaf Dietsche

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).