Skip to contentSkip to conversation

capable open_port() check wrong for kmem

DISCUSSION carbonated beverage 5 participants 9 messages Dec 10, 2002 – Dec 12, 2002 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

hi all,

I found that I can't open /dev/kmem O_RDONLY. The open_mem
and open_kmem calls (open_port()) in drivers/char/mem.c checks for CAP_SYS_RAWIO.

Is there a possibility of splitting that off into a read and
write pair, i.e. CAP_SYS_RAWIO_WRITE, CAP_SYS_RAWIO_READ?

If not, is there a way to grant read-only access to /dev/kmem?

-- DN
Daniel

#1 lore raw
Quoted 6 lines · carbonated beverage

I found that I can't open /dev/kmem O_RDONLY. The open_mem
and open_kmem calls (open_port()) in drivers/char/mem.c checks for CAP_SYS_RAWIO.

Is there a possibility of splitting that off into a read and
write pair, i.e. CAP_SYS_RAWIO_WRITE, CAP_SYS_RAWIO_READ?

Read-only access to /dev/kmem is probably enough to get root access (maybe you can snoop root's password, for instance). This would make the power of the two capabilities roughly equivalent, so if this is true, I'm not sure I understand the point of splitting them in two this way.

#2 lore raw
Quoted 6 lines · David Wagner
Quoted 3 lines · carbonated beverage

I found that I can't open /dev/kmem O_RDONLY. The open_mem
and open_kmem calls (open_port()) in drivers/char/mem.c checks for CAP_SYS_RAWIO.

Quoted 7 lines
Quoted 2 lines

Is there a possibility of splitting that off into a read and
write pair, i.e. CAP_SYS_RAWIO_WRITE, CAP_SYS_RAWIO_READ?

Read-only access to /dev/kmem is probably enough to get root access (maybe you can snoop root's password, for instance). This would make the power of the two capabilities roughly equivalent, so if this is true, I'm not sure I understand the point of splitting them in two this way.

Many capabilities can be leveraged into root access with sufficient
cleverness. If this were considered a sufficient argument for merging capabilities, we'd have far fewer of them.

DS

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw

forgot to cc: linux-kernel:

Hi,

Quoted 4 lines · David Wagner

Read-only access to /dev/kmem is probably enough to get root access (maybe you can snoop root's password, for instance). This would make the power of the two capabilities roughly equivalent, so if this is true, I'm not sure I understand the point of splitting them in two this way.

It's rather annoying and counter-intuitive to have:

crw-r----- 1 root kmem 1, 2 Sep 8 21:56 /dev/kmem

but to have the following code fragment give:

int fd;
	fd = open("/dev/kmem", O_RDONLY);
	if(fd == -1) {
		fprintf(stderr, "Can't open /dev/kmem: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}

Can't open /dev/kmem: Operation not permitted

with a user in the kmem group.

Also, the utility I'm writing doesn't need write access, so why give it to the process in the first place?

-- DN
Daniel

#5 lore raw
Quoted 14 lines · * carbonated beverage ([email protected]) wrote:

It's rather annoying and counter-intuitive to have:

crw-r----- 1 root kmem 1, 2 Sep 8 21:56 /dev/kmem

but to have the following code fragment give:

int fd;
	fd = open("/dev/kmem", O_RDONLY);
	if(fd == -1) {
		fprintf(stderr, "Can't open /dev/kmem: %s\n", strerror(errno));
		exit(EXIT_FAILURE);
	}
Quoted 6 lines

Can't open /dev/kmem: Operation not permitted

with a user in the kmem group.

Also, the utility I'm writing doesn't need write access, so why give it to the process in the first place?

Then open O_RDONLY (with CAP_SYS_RAWIO). Then the utility won't have write access. If that's all you are worried about.

or.

If you have only one capability (CAP_SYS_RAWIO), you are not owner of /dev/kmem, you are in group kmem, and /dev/kmem is 0640, then all you will get is read-only access to /dev/kmem. This does not require kernel changes.

thanks,
-chris

Signature · 1 line
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net
#6 lore raw

On Wed, Dec 11, 2002 at 04:43:48PM -0800, Chris Wright wrote:
[snip]

Quoted 3 lines

If you have only one capability (CAP_SYS_RAWIO), you are not owner of /dev/kmem, you are in group kmem, and /dev/kmem is 0640, then all you will get is read-only access to /dev/kmem. This does not require kernel changes.

So if I want to have a generic utility that can be used by any user (and I'm not granting CAP_SYS_RAWIO to every process), then I can:

1) make it suid root
2) drop all caps other than cap_sys_rawio

or

1) add the capability to the executable, assuming it worked...

Script started on Wed Dec 11 17:29:14 2002

UB6IB9:/home/ramune/src/hack# setcap 'cap_sys_rawio=eip' ./a.out
Failed to set capabilities on file `./a.out'
 (Function not implemented)
usage: setcap [-q] (-|<caps>) <filename> [ ... (-|<capsN>) <filenameN> ]
UB6IB9:/home/ramune/src/hack# mount
/dev/hda1 on / type ext3 (rw)
proc on /proc type proc (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
UB6IB9:/home/ramune/src/hack# uname -a
Linux UB6IB9 2.4.20 #1 Sat Nov 30 20:51:01 PST 2002 i586 unknown
UB6IB9:/home/ramune/src/hack#
Script done on Wed Dec 11 17:29:31 2002

So, what am I missing?

I just have to make it suid root if I wanna use it on 2.4.x? Or is there a problem with my setup causing setcap to fail?

-- DN
Daniel

#7 lore raw
Quoted 10 lines · * carbonated beverage ([email protected]) wrote:

So if I want to have a generic utility that can be used by any user (and I'm not granting CAP_SYS_RAWIO to every process), then I can:

1) make it suid root
2) drop all caps other than cap_sys_rawio

or

1) add the capability to the executable, assuming it worked...

this is not supported without kernel patches. in general you have to start with full capabilities and shed the ones you don't need.

thanks,
-chris

Signature · 1 line
Linux Security Modules     http://lsm.immunix.org     http://lsm.bkbits.net
#8 lore raw
In reply to carbonated beverage
Quoted 8 lines · carbonated beverage

I found that I can't open /dev/kmem O_RDONLY. The open_mem
and open_kmem calls (open_port()) in drivers/char/mem.c checks for CAP_SYS_RAWIO.

Is there a possibility of splitting that off into a read and
write pair, i.e. CAP_SYS_RAWIO_WRITE, CAP_SYS_RAWIO_READ?

If not, is there a way to grant read-only access to /dev/kmem?

You may want to look at this thread:
<http://groups.google.com/groups?threadm=87smza1p7f.fsf%40goat.bogus.local>

Regards, Olaf.

#9 lore raw

On Tue, Dec 10, 2002 at 12:33:04PM +0100, Olaf Dietsche wrote:
[snip]

Quoted 2 lines

You may want to look at this thread:
<http://groups.google.com/groups?threadm=87smza1p7f.fsf%40goat.bogus.local>

Hmm.

Okay, which approach is generally accpetible for inclusion into the kernel?
1) Nuke CAP_SYS_RAWIO check. If the permissions on /dev/kmem is wrong, tough. It shouldn't be root:root 0666 in the first place anyways.
2) Add CAP_SYS_KMEM for read-only access, check for CAP_SYS_RAWIO for the write case.
3) Special case /dev/kmem in open_port.

or:

4) Even if an application doesn't need write access to /dev/kmem, require it to open /dev/kmem O_RDWR, as it makes life easier for many people, especially when modifying the kernel at run-time to hijack sysca... um, do creative updates. :)

I'd prefer #1 or #2, but the discussion seems to have ended during the last time the issue was brought up.

-- DN
Daniel