Subject: [alpine-devel] a few abuild oddities

From: Dubiousjim <[email-masked]>
Date: Sun, 1 Dec 2013 12:45:54 -0500

I'm puzzled about a few things with abuild.

First, a long-standing issue has been that if you do:

   abuild -r -i pkg1 -i pkg2

then the .makedepends-foo package doesn't get deleted.

Second, I don't understand how abuild is acquiring sufficient
permissions to do what it seems to be doing in these cases.

My user belongs to the "abuild" group, but normally isn't able to even
acquire a lock on the apk database, much less add or del packages,
without raising privileges via sudo or su. Also, my /etc/apk/world file
lists as:

-rw-r--r--    1 root     root           885 Dec  1 11:58 /etc/apk/world

However, I can be sure that sudo hasn't cached any privileges (sudo -k)
and go into an aports directory and type `abuild -r -i pkg1` (supplying
an appropriate package name), and then WITHOUT EVER ASKING FOR A
PASSWORD, abuild will:

* download and install the necessary dependencies: I assume it shouldn't
  be able to do this without privileges, although possibly the packages
  are getting installed in an overlay or some-such ... I know that
  didn't use to be the case, but I haven't kept close tabs on how the
  code has developed over the past year or so. Even if the packages
  weren't really getting installed to /, where the user running abuild
  lacks sufficient privileges, still how can abuild update
  /etc/apk/world? which one can see it does because the .makedepends-foo
  virtual package never gets deleted (see first issue above)

* if the build completes successfully, then install the relevant local
  package, again which it shouldn't be able to do without prompting for
  a password

Perhaps the issue here isn't with abuild, but rather with one or the
other of fakeroot and sudo?

Third question: In my local aports clone, I have some separate branches
for my local additions and tweaks. Some of that stuff goes into
$APORTS/local, when there is no corresponding package already in the
tree. But other stuff goes into $APORTS/main and $APORTS/testing; this
helps me keep track of when the master branch and my local branches have
diverged, and makes it easier to merge them. I assume other Alpine
developers and hackers have a similar workflow.

Now, suppose I happen to have built a local copy of foo-1.2-3.apk on my
machine. Then the official repositories get foo-1.2-4.apk, and suppose I
happen to install that. Then when I get around to housekeeping my
machine properly, I'll sync my local aports branch with master, and
build my own version of the new foo-1.2-4, with my custom build
instructions. My habit is to just name this foo-1.2-4, as well, since we
don't have any conventions for handling additional release suffixes. And
I don't want to name my custom version foo-1.2-5, since that may also be
released in the official repositories later and be rather different. So
I just name my custom version foo-1.2-4 as well, and make sure that my
local package folder comes before the official repositories in
/etc/apk/repositories. This works fine.

The only tricky thing is, how now to tell Alpine that I want to install
the new, custom-build package in place of the already-installed package
with the same version and release from the official repositories. There
are at least two ways one can do this:

   sudo apk add $REPODEST/main/x86/foo-1.2-4.apk

or:

   # inside $APORTS/main/foo/
   abuild -r -i foo

I think the latter works even if the package has already been built and
locally indexed. (Plus as I pointed out above, it seems to avoid the
nuisance of supplying a su/sudo password. :-)) But in either of these
cases, I then tend to:

   sudo vim /etc/apk/world

find the "foo><123456789..." line, and then either delete it (if foo is
already a dependency of another package in world) or modify it to just
read "foo". This is the only way to ensure that future updates to foo in
the official repositories show up when I say "apk upgrade --sim" or
such.

What I'm leading up to is that it'd be nice if there was some easier way
to get the newly built local package to be preferred to the
already-installed package from the official repositories. Then I
wouldn't have to manually poke around in /etc/apk/world.
As I said, the directory that the newly-built package resides in is getting indexed
properly by abuild, and it comes before the official repositories in my
/etc/apk/repositories. But neither of these:

  apk fix -u foo

nor:

  apk fix -r foo

will use the newly-built package, not even if I do "apk update" first.

I'm not sure if:

  apk upgrade -a

will use the newly-built package. Even if it does, though, this isn't
super-helpful to me because I'm often trying to juggle these package
replacements when I've got a queue of not-yet-applied (and
not-yet-ready-to-apply) upgrades.

Any thoughts/ideas/suggestions?

-- 
Dubiousjim
[email-masked]

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---

---

From: Dubiousjim <[email-masked]>
Date: Sun, 1 Dec 2013 18:56:59 -0500

> other of fakeroot and sudo?

I've figured out the answer to this question. The answer is that we have
a binary abuild-sudo, which is installed suid, and can be invoked by
anyone in the "abuild" group (via the symlinks abuild-apk,
abuild-addgroup, and abuild-adduser) to run the corresponding commands
as root, without needing any sudo/su authentication.

Thus if your user belongs to the "abuild" group, then you can always do
all your apk-ing, with full permissions, just by invoking apk as
"abuild-apk" instead of just bare "apk".

The merits of this design may be debatable, but I'm at least relieved
that this *is* by design, and that I can now understand where and why
it's happening, and what the limits to this security opening are.
 
-- 
Dubiousjim
[email-masked]

---

---

From: Natanael Copa <[email-masked]>
Date: Mon, 2 Dec 2013 14:29:14 +0100

On Sun, 1 Dec 2013 18:56:59 -0500

> as root, without needing any sudo/su authentication.

Correct.
 
> "abuild-apk" instead of just bare "apk".

Correct. This also means that if you are in abuild-apk group you in
practice has full sudo access. So you should never put anyone in this
group unless you would also give full sudo (without asking for
password) access to this user.
 
> it's happening, and what the limits to this security opening are.

Agree, this is debatable and I am definitively open for ideas here.

What I wanted to achieve with this was to make it easier to set up a
build env. You now can just apk alpine-sdk and add the user to the
abuild group and you are basically set. This is also easier/cleaner
than editing sudoers from script. (think: set up a temp build
environment for a chroot build)

One thing we could do to improve the security a bit is to ban the
--allow-untrusted option with the suid abuild-apk. That would allow the
users in abuild group to install signed packages only. Adding the user
to 'abuild' group and the users key to /etc/apk/keys would then be
equivalent as give full root access.

Other ideas is welcome too.

-nc

---

---

From: Jim Pryor <[email-masked]>
Date: Mon, 02 Dec 2013 11:04:25 -0500

> equivalent as give full root access.

I do think this would be a good improvement, if only for people who put
users in the abuild group without fully understanding the consequences.
In practice, though, anyone who knows what they're doing is going to
also put a key in /etc/apk/keys, and then any vulnerabilities in that
account will give full root access.

Is it possible to use abuild for the full range of activities without
being in the abuild group? Do we just prompt with sudo or su in those
cases when needed? In that case the security-conscious solution will
just be don't add your users to the "abuild" group. The costs and
benefits of this would just need to be more clearly documented.

-- 
[email-masked]

---

---

From: Natanael Copa <[email-masked]>
Date: Tue, 3 Dec 2013 16:34:09 +0100

On Mon, 02 Dec 2013 11:04:25 -0500

> account will give full root access.

Ok. I will look into this.
 
> benefits of this would just need to be more clearly documented.

You need either be in abuild group or have sudo permissions to use
abuild -r for letting abuild install the deps for you.

To use sudo instead of abuild-apk you can set SUDO_APK="sudo apk"
in /etc/abuild.conf (or just export SUDO_APK="sudo apk").

You can still build packages with abuild without needing sudo but then
all the dependencies needs to be installed already:
  SUDO_APK=apk abuild

The motivation behind abuild group was to make it convenient to set up
a build server. Might be we want change the default back to sudo.

-nc

---

---

From: Jim Pryor <[email-masked]>
Date: Tue, 3 Dec 2013 22:47:11 -0500

> abuild -r for letting abuild install the deps for you.

Ok, but they don't have to be permissions to use "sudo abuild -r ..."
WITHOUT PASSWORD, correct? That's the behavior I expect.
> in /etc/abuild.conf (or just export SUDO_APK="sudo apk").

Great, thanks.

-- 
Dubiousjim
[email-masked]

---

---

From: Natanael Copa <[email-masked]>
Date: Fri, 6 Dec 2013 11:41:50 +0100

On Tue, 3 Dec 2013 22:47:11 -0500

> WITHOUT PASSWORD, correct? That's the behavior I expect.

I don't understand the question. Sorry.

abuild will slap you in the face if you run abuild as root (sudo abuild)

The point was that you on buildservers don't need to add user to
sudoers (with NOPASSWD). Build servers cannot prompt for passwords.

> > in /etc/abuild.conf (or just export SUDO_APK="sudo apk").

The problem is actually worse than I originally thought. abuild also
needs to create users and groups (for pkgusers/pkggroups). This means
that if you are in 'abuild' group you can create any user or group and
add any user to any group.

We only need the user within fakeroot so you from package() function
can set permissions of files and dirs within the package.

To solve this, we could either create fake users for fakeroot (so
fakeroot belives that user exists) or we would need to have a tar-fork
that could set ownership on given files when creating the archive. That
way, the user don't need exist on the building system.

---

---

From: Jim Pryor <[email-masked]>
Date: Tue, 10 Dec 2013 22:13:45 -0500

> sudoers (with NOPASSWD). Build servers cannot prompt for passwords.

Sorry I wasn't clear. If I'm understanding right, here is how things
stand:

One can't run abuild as root, or using "sudo abuild" (unless one
supplies the -F switch?).

One option is to add the current user to the abuild group (log out and
log back in as needed). Then abuild can do everything it needs to do,
without prompting for any passwords.

> > > in /etc/abuild.conf (or just export SUDO_APK="sudo apk").

Then the user in question needs to have permissions to run the commands
abuilds wants to run in the /etc/sudoers file. If we're talking about a
build server, then those have to be NOPASSWD permissions. But if it's an
interactive machine, then the NOPASSWD permissions aren't needed, right?
Abuild will just invoke whatever you gave it as a SUDO_APK, and if that
in turn wants to demand passwords from the user, so be it. No problem
there, correct?

> way, the user don't need exist on the building system.

I don't have any insights or suggestions to make about this.
-- 
[email-masked]

---

---

From: Natanael Copa <[email-masked]>
Date: Fri, 13 Dec 2013 16:23:24 +0100

On Tue, 10 Dec 2013 22:13:45 -0500

Correct.
> without prompting for any passwords.

Correct. This would be equivalent to giving the user NOPASSWD sudo
permissions for running apk, adduser and addgroup. (In practice it
means full root privileges)

Correct.

> in turn wants to demand passwords from the user, so be it. No problem

As long as the APKBUILD does not set pkgusers or pkggroups it should be
ok. I think you then have to set:

ADDUSER="sudo adduser"
ADDGROUP="sudo addgroup"

-nc

---