You are not logged in.

#1 2013-04-07 12:17:51

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Paccache and su -c

Hello,

i am using paccache to clear old package archives. I don't have sudo installed, so paccache uses su -c for privilege escalation. Since the upgrade to pacman 4.1 this doesn't work anymore. I can't properly type in my root passwort, because (a) it is printed to the screen and (b) won't be accepted by su anyway, because (i think) the keystrokes are not passed to the su command properly.
I have looked at the code but found no explanation. Is anyone having the same problem?

Greetings

Last edited by Sunday87 (2013-04-07 20:22:41)

Offline

#2 2013-04-07 12:20:38

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,452
Website

Re: Paccache and su -c

I may be missing something as I don't use paccache, but is this some sort of su mechanism built into that tool, or are you just doing `su` first to start a root shell, then using pac{man,cache}?  If it's the later, then how do paccache or pacman relate to the issue, you just can't log in to su.  If the former, it would help to have the exact commands you used.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#3 2013-04-07 12:25:00

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Re: Paccache and su -c

Paccache does the privilege escalation internally, so it is run as a normal user with "paccache -r", looks for packages which should be deleted and then runs something like xargs -0 mv ....  through su -c which presents a password prompt. In any other case su works fine, for example if i run it in any normal shell session.

the deletion command is run as

printf '%s\0' "${candidates[@]}" | runcmd xargs -0 rm "${cmdopts[@]}"

and uses the function runcmd which is defined as

runcmd() {
	if (( needsroot && EUID != 0 )); then
		msg "Privilege escalation required"
		if sudo -v &>/dev/null && sudo -l &>/dev/null; then
			sudo "$@"
		else
			printf '%s ' 'root'
			su -c "$(printf '%q ' "$@")"
		fi
	else
		"$@"
	fi
}

cmdopts may contain "-f" and/or "-v" and candidates is the list of files that should be deleted. I am not sure about the effects of all the quoting and printf calls.

Last edited by Sunday87 (2013-04-07 12:32:37)

Offline

#4 2013-04-07 12:39:38

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Re: Paccache and su -c

Ok,  i think i have found the cause. This seems to be caused by this patch: http://archlinux.2023198.n4.nabble.com/ … 84182.html. I reverted it in a local copy of paccache and now it works again. I don't know if it is the same with sudo, but i think this is enough to file a bug report about this.

Offline

#5 2013-04-07 12:43:51

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,452
Website

Re: Paccache and su -c

Thanks for the details - great research into the problem.

Since this is specific to paccache, I can't replicate or fail to replicate it - but until another paccache user comes in, I'd suggest tinkering with that su line.  I tried the following "unit test" and it worked as expected:

#!/bin/bash

function run() {
	printf '%s ' 'root'
	su -c "$(printf '%s ' "$@")"
}

run vim /etc/pacman.conf

You could try something similar to see if there is something wrong with that invocation of su, or if the problem lies elsewhere.

If the problem lies elsewhere, and I had to hunt it down, I'd look for any input/output redirection that came before those lines.


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#6 2013-04-07 12:49:10

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Re: Paccache and su -c

Yeah... this doesn't work, because the pipe won't allow for the passwort to reach su:

#!/bin/bash

run() {
        printf '%s ' 'root'
        su -c "$(printf '%s ' "$@")"
}

echo "/etc/pacman.conf\0" | run xargs -0 nano

Last edited by Sunday87 (2013-04-07 12:54:23)

Offline

#7 2013-04-07 12:55:52

Trilby
Inspector Parrot
Registered: 2011-11-29
Posts: 29,452
Website

Re: Paccache and su -c

Ah, I forgot that part of it.  With that change (pipe and xargs), I do replicate the problem you describe: my password is echoed to the screen, and nothing happens after it is entered.

I don't know if it'd be a suitable long-term solution, but you could rewrite that xargs line to just be a call to runcmd.

It seems xargs hasn't changed in a while (27 Jan here), so perhaps there was a revision in paccache that lead to this.

Last edited by Trilby (2013-04-07 12:56:56)


"UNIX is simple and coherent..." - Dennis Ritchie, "GNU's Not UNIX" -  Richard Stallman

Offline

#8 2013-04-07 14:25:57

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: Paccache and su -c

Trilby wrote:

Ah, I forgot that part of it.  With that change (pipe and xargs), I do replicate the problem you describe: my password is echoed to the screen, and nothing happens after it is entered.

I don't know if it'd be a suitable long-term solution, but you could rewrite that xargs line to just be a call to runcmd.

Which would essentially revert the patch that he linked to and reintroduce the same problem it fixed.

Trilby wrote:

It seems xargs hasn't changed in a while (27 Jan here), so perhaps there was a revision in paccache that lead to this.

See above...

Regardless, this won't be fixed without a bug report. Not sure why you can't use just sudo instead. It's a far better tool than su for a huge number of reasons.

edit: just an idea...

diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in
index c331273..0eba69c 100644
--- a/contrib/paccache.sh.in
+++ b/contrib/paccache.sh.in
@@ -308,9 +308,9 @@ totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }
 # crush. kill. destroy.
 (( verbose )) && cmdopts+=(-v)
 if (( delete )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 rm "${cmdopts[@]}"
+       runcmd xargs -a <(printf '%s\0' "${candidates[@]}") rm "${cmdopts[@]}"
 elif (( move )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 mv "${cmdopts[@]}" -t "$movedir"
+       runcmd xargs -a <(printf '%s\0' "${candidates[@]}") mv "${cmdopts[@]}" -t "$movedir"
 fi
 
 summarize "$pkgcount" "${candidates[@]}"

This means that stdin won't be redirected from /dev/null and it should preserve the terminal for su. This really should be fixed in su so that it opens /dev/tty explicitly for input when stdin isn't a terminal. The behavior is easily shown with:

$ </dev/null su root -c bash

Last edited by falconindy (2013-04-07 14:36:44)

Offline

#9 2013-04-07 16:15:57

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Re: Paccache and su -c

I posted a bug report on this (https://bugs.archlinux.org/task/34656) but because i didn't know better at the time i posted it to the "arch linux" project and not the "pacman" project. Can i do anything about that mistake?

Offline

#10 2013-04-07 16:18:47

KaiSforza
Member
Registered: 2012-04-22
Posts: 133
Website

Re: Paccache and su -c

I don't think that runcmd should even escelate to root. It just seems like a generally bad idea to me. Make the user run it as

sudo paccache ...

or

su -c "paccache..."

I don't think this should even be taken care of in paccache, but instead by the user or script calling paccache.


Thinkpad T420 | Intel 3000 | systemd {,--user}
PKGBUILDs I use | pywer AUR helper

Offline

#11 2013-04-07 19:08:10

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: Paccache and su -c

KaiSforza wrote:

I don't think that runcmd should even escelate to root. It just seems like a generally bad idea to me. Make the user run it as

sudo paccache ...

or

su -c "paccache..."

I don't think this should even be taken care of in paccache, but instead by the user or script calling paccache.

But makepkg doing this is fine?

Offline

#12 2013-04-07 19:39:42

KaiSforza
Member
Registered: 2012-04-22
Posts: 133
Website

Re: Paccache and su -c

falconindy wrote:

But makepkg doing this is fine?

makepkg does that for a reason. You could do everything in a fakeroot (besides -i, I guess), install all of the dependencies you need there, etc., but it's there for convenience and security.

Doing this in paccache seems to be unneeded. Yes, it makes it minimally more convenient, but what in paccache is going to be insecure when run directly as root? Is there any real reason to only do this for that single part, and not for the whole thing? I see nothing in paccache besides the removal/moving of packages that could be potentially destructive.


Thinkpad T420 | Intel 3000 | systemd {,--user}
PKGBUILDs I use | pywer AUR helper

Offline

#13 2013-04-07 19:52:20

falconindy
Developer
From: New York, USA
Registered: 2009-10-22
Posts: 4,111
Website

Re: Paccache and su -c

KaiSforza wrote:
falconindy wrote:

But makepkg doing this is fine?

but it's there for convenience and security.

And here it is again for convenience. Unlike makepkg, paccache isn't going to stop you from running it directly as root if that's what you really want.

Offline

#14 2013-04-07 20:00:14

KaiSforza
Member
Registered: 2012-04-22
Posts: 133
Website

Re: Paccache and su -c

falconindy wrote:
KaiSforza wrote:
falconindy wrote:

But makepkg doing this is fine?

but it's there for convenience and security.

And here it is again for convenience. Unlike makepkg, paccache isn't going to stop you from running it directly as root if that's what you really want.

The point of makepkg's convenience is for security (yes, you can run as root fully, but it's a bad idea). Trying to make it convenient for paccache is just trying to save a few keystrokes.


Thinkpad T420 | Intel 3000 | systemd {,--user}
PKGBUILDs I use | pywer AUR helper

Offline

#15 2013-04-11 07:21:22

Sunday87
Member
Registered: 2013-01-17
Posts: 31

Re: Paccache and su -c

I have just tried your idea

diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in
index c331273..0eba69c 100644
--- a/contrib/paccache.sh.in
+++ b/contrib/paccache.sh.in
@@ -308,9 +308,9 @@ totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }
 # crush. kill. destroy.
 (( verbose )) && cmdopts+=(-v)
 if (( delete )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 rm "${cmdopts[@]}"
+       runcmd xargs -a <(printf '%s\0' "${candidates[@]}") rm "${cmdopts[@]}"
 elif (( move )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 mv "${cmdopts[@]}" -t "$movedir"
+       runcmd xargs -a <(printf '%s\0' "${candidates[@]}") mv "${cmdopts[@]}" -t "$movedir"
 fi
 
 summarize "$pkgcount" "${candidates[@]}"

and I found that xargs is missing the option "-0", so the patch should be

diff --git a/contrib/paccache.sh.in b/contrib/paccache.sh.in
index c331273..0eba69c 100644
--- a/contrib/paccache.sh.in
+++ b/contrib/paccache.sh.in
@@ -308,9 +308,9 @@ totalsaved=$(@SIZECMD@ "${candidates[@]}" | awk '{ sum += $1 } END { print sum }
 # crush. kill. destroy.
 (( verbose )) && cmdopts+=(-v)
 if (( delete )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 rm "${cmdopts[@]}"
+       runcmd xargs -0a <(printf '%s\0' "${candidates[@]}") rm "${cmdopts[@]}"
 elif (( move )); then
-       printf '%s\0' "${candidates[@]}" | runcmd xargs -0 mv "${cmdopts[@]}" -t "$movedir"
+       runcmd xargs -0a <(printf '%s\0' "${candidates[@]}") mv "${cmdopts[@]}" -t "$movedir"
 fi
 
 summarize "$pkgcount" "${candidates[@]}"

Greetings

Offline

Board footer

Powered by FluxBB