clickpreload doesn't work on armhf

Bug #1218674 reported by Loïc Minier
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
click (Ubuntu)
Fix Released
High
Colin Watson

Bug Description

Hi,

TLDR; download-manager only allows downloads to be readable by phablet (of course root can too), so that clickpkg user can't read them.

Installing Click packages from appstore (click scope) in Ubuntu Touch images is unreliable.

I couldn't figure exactly which conditions trigger this, but "pkcon install-local some.click" works, and then installation from the scope works, however if I install straight from the scope it doens't work.

I've straced packagekit doing this and spotted some click traceback being written to a .crash which ends with:
Traceback:
 Traceback (most recent call last):
   File "/usr/bin/click", line 84, in <module>
     sys.exit(main())
   File "/usr/bin/click", line 79, in main
     mod.run(args)
   File "/usr/lib/python3/dist-packages/click/commands/install.py", line 41, in run
     installer.install(package_path, user=options.user)
   File "/usr/lib/python3/dist-packages/click/install.py", line 264, in install
     env=env, **kwargs)
   File "/usr/lib/python3.3/subprocess.py", line 544, in check_call
     raise CalledProcessError(retcode, cmd)
 subprocess.CalledProcessError: Command '['dpkg', '--force-not-root', '--instdir', '/opt/click.ubuntu.com/ar.com.beuno.hello-world/0.6', '--admindir', '/opt/click.ubuntu.com/ar.com.beuno.hello-world/0.6/.click', '--path-exclude', '*/.click/*', '--log', '/opt/click.ubuntu.com/.click/log', '--no-triggers', '--install', '/home/phablet/.local/share/download_manager/{97d4efcf-34bc-4919-a9b4-a1006890128e}/ar.com.beuno.hello-world-0.6.click']' returned non-zero exit status 1

Which suggests dpkg failing; which I found in the strace started as follows:
4519 execve("/usr/bin/dpkg", ["dpkg", "--force-not-root", "--instdir", "/opt/click.ubuntu.com/ar.com.beu"..., "--admindir", "/opt/click.ubuntu.com/ar.com.beu"..., "--path-exclude", "*/.click/*", "--log", "/opt/click.ubuntu.com/.click/log", "--no-triggers", "--install", "/home/phablet/.local/share/downl"...], [/* 7 vars */] <unfinished ...>

then running dpkg-split:
4520 execve("/usr/bin/dpkg-split", ["dpkg-split", "-Qao", "/opt/click.ubuntu.com/ar.com.beu"..., "/home/phablet/.local/share/downl"...], [/* 8 vars */]) = 0

but failing to open the package:
4520 open("/home/phablet/.local/share/download_manager/{8ec430e5-a192-493a-bdb6-478fffcb7ab1}/ar.com.beuno.hello-world-0.6.click", O_RDONLY|O_LARGEFILE) = -1 EACCES (Permission denied)
4520 write(2, "dpkg-split: error: unable to rea"..., 183) = 183

Immediately before, one can see:
4520 geteuid32() = 106

which was set when launching dpkg:
4519 setresgid32(107, 107, 107) = 0
4519 setresuid32(106, 106, 106) = 0
4519 getresuid32([106], [106], [106]) = 0
4519 getresgid32([107], [107], [107]) = 0

Indeed, click install had switched to the clickpkg user:
clickpkg:x:106:107::/nonexistent:/bin/false

So the problem is that .clicks may only be read by phablet user or root, but not by clickpkg.

Cheers,

Tags: patch

Related branches

Revision history for this message
Loïc Minier (lool) wrote : Re: Need to make .click world readable before passing to click install

Moving this to click as it should be opening the .click before changing UID and then passing it to subprocesses.

affects: ubuntu-system-image → unity-scope-click (Ubuntu)
summary: - Installing clicks from click-scope is unreliable
+ Need to make .click world readable before passing to click install
description: updated
affects: unity-scope-click (Ubuntu) → click (Ubuntu)
Revision history for this message
Loïc Minier (lool) wrote :

Hmm I see this should be handled in the ldpreload code; I hope it's not strace messing with the ldpreloading?

Revision history for this message
Loïc Minier (lool) wrote :
Revision history for this message
Loïc Minier (lool) wrote :

So I don't really understand why the preloading doesn't seem work on arm; it seems to work on x86; I've run gdb on dpkg-split with:
set environment CLICK_PACKAGE_FD=0
set environment CLICK_PACKAGE_PATH=ar.com.beuno.hello-world-0.6.click
set environment LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/click/libclickpreload.so
break open
run -Qao /foobar ar.com.beuno.hello-world-0.6.click

but backtrace isn't in the right library:
Starting program: /usr/bin/dpkg-split -Qao /foobar /ar.com.beuno.hello-world-0.6.click

Breakpoint 1, 0x401c2710 in open () from /lib/arm-linux-gnueabihf/libc.so.6
(gdb) bt
#0 0x401c2710 in open () from /lib/arm-linux-gnueabihf/libc.so.6
#1 0x4018bce6 in _IO_file_open () from /lib/arm-linux-gnueabihf/libc.so.6
#2 0x4018be3c in _IO_file_fopen () from /lib/arm-linux-gnueabihf/libc.so.6
#3 0x40183df6 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6

on x86 this works:
Breakpoint 1, open64 () at ../sysdeps/unix/syscall-template.S:81
81 ../sysdeps/unix/syscall-template.S: Aucun fichier ou dossier de ce type.
(gdb) bt
#0 open64 () at ../sysdeps/unix/syscall-template.S:81
#1 0x00007ffff7ddfd0f in open_verify (name=0x7ffff7ff94a0 "/usr/lib/x86_64-linux-gnu/click/libclickpreload.so", fbp=fbp@entry=0x7fffffffdbc8, loader=<optimized out>,
    whatcode=whatcode@entry=0, found_other_class=found_other_class@entry=0x7fffffffdbb0, free_name=free_name@entry=true) at dl-load.c:1924
#2 0x00007ffff7de28e2 in _dl_map_object (loader=0x7ffff7ffe268, name=0x7fffffffe100 "/usr/lib/x86_64-linux-gnu/click/libclickpreload.so", type=type@entry=1,
    trace_mode=trace_mode@entry=0, mode=67108864, nsid=nsid@entry=0) at dl-load.c:2544
#3 0x00007ffff7ddb81e in map_doit (a=a@entry=0x7fffffffe0b0) at rtld.c:632
#4 0x00007ffff7de96e6 in _dl_catch_error (objname=objname@entry=0x7fffffffe0a0, errstring=errstring@entry=0x7fffffffe0a8, mallocedp=mallocedp@entry=0x7fffffffe09f,
    operate=operate@entry=0x7ffff7ddb800 <map_doit>, args=args@entry=0x7fffffffe0b0) at dl-error.c:177
#5 0x00007ffff7ddb087 in do_preload (fname=0x7fffffffe100 "/usr/lib/x86_64-linux-gnu/click/libclickpreload.so", main_map=<optimized out>, where=0x7ffff7df6725 "LD_PRELOAD")
    at rtld.c:821
#6 0x00007ffff7dddac2 in dl_main (phdr=<optimized out>, phnum=0, user_entry=0x0, auxv=<optimized out>) at rtld.c:1635
#7 0x00007ffff7df076e in _dl_sysdep_start (start_argptr=start_argptr@entry=0x7fffffffe340, dl_main=dl_main@entry=0x7ffff7ddbe00 <dl_main>) at ../elf/dl-sysdep.c:241
#8 0x00007ffff7ddf208 in _dl_start_final (arg=0x7fffffffe340) at rtld.c:337
#9 _dl_start (arg=0x7fffffffe340) at rtld.c:563
#10 0x00007ffff7ddb638 in _start () from /lib64/ld-linux-x86-64.so.2
#11 0x0000000000000004 in ?? ()

Revision history for this message
Loïc Minier (lool) wrote :

I made an attempt to override fopen64 in the preload as well, but that resulted in a SEGV on app startup with my naive implementation.

Revision history for this message
Loïc Minier (lool) wrote :

So the reason fopen64 SEGV is because libselinux actually fopened /proc/filesystems before libclickpreload's init had run, hence libclickpreload's fopen64 wrapper would try calling a still NULL libc_fopen64.

I did an ugly workaround in fopen64 for now to discuss the nicest approach with Colin, see attached patch.

With the patch, I could click install a .click from a protected dir.

summary: - Need to make .click world readable before passing to click install
+ clickpreload doesn't work on armhf
Revision history for this message
Loïc Minier (lool) wrote :

I also tried with the click-scope, and reverting to the old clickpreload.so, I would get the manifest error, and putting the new clickpreload.so in place, it would work.

tags: added: patch
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in click (Ubuntu):
status: New → Confirmed
Revision history for this message
Colin Watson (cjwatson) wrote :

After some cleanup elsewhere, I've committed something similar to this, although I just called the constructor directly instead as we do elsewhere. This also has the effect of ensuring that package_path is set.

Changed in click (Ubuntu):
assignee: nobody → Colin Watson (cjwatson)
importance: Undecided → High
status: Confirmed → Fix Committed
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package click - 0.4.0

---------------
click (0.4.0) saucy; urgency=low

  [ Colin Watson ]
  * Add "installed-size" as a mandatory field in the control area's
    "manifest" file; it should not be present in source manifest files, and
    is generated automatically by "click build".
  * Add an optional "icon" manifest key.
  * Consistently call clickpreload_init from preloaded functions in case
    they happen to be called before libclickpreload's constructor.
  * Run dpkg with --force-bad-path so that /sbin and /usr/sbin are not
    required to be on $PATH; we don't use the tools dpkg gets from there.

  [ Loïc Minier ]
  * Add fopen64 wrapper (LP: #1218674).
 -- Colin Watson <email address hidden> Fri, 30 Aug 2013 17:59:34 +0100

Changed in click (Ubuntu):
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.