Managing time, date and timezone in Ubuntu Core

@zyga-snapd Do you think the denial I have will be fixed in this new version?

The only mention of /proc/.../environ that I can see is in the greengrass support interface. CCing @jdstrand – my guesstimate says “no”.

I checked the status of this with the latest version from the stable channel.

admin@1TXPB02:~$ snap list
Name Version Rev Developer Notes
core 16-2.28.5 3247 canonical core

Still getting following denials :


= AppArmor =
Time: Nov 1 09:36:02
Log: apparmor=“ALLOWED” operation=“open” profile=“snap.epi-gateway.main” name="/proc/1/environ" pid=9069 comm=“timedatectl.rea” requested_mask=“r” denied_mask=“r” fsuid=0 ouid=0
File: /proc/1/environ (read)
Suggestion:
* adjust program to not access ‘@{PROC}/@{pid}/environ’

= AppArmor =
Time: Nov 1 09:36:02
Log: apparmor=“ALLOWED” operation=“ptrace” profile=“snap.epi-gateway.main” pid=9069 comm=“timedatectl.rea” requested_mask=“trace” denied_mask=“trace” peer=“unconfined”
Ptrace: peer=unconfined (trace)
Suggestions:
* adjust program to not trace processes
* do nothing if program otherwise works properly


Why is invoking timedatectl from the program resulting in the first one?

Is it still ok to get the second one?

There are no interfaces to allow the second denial (it would allow breaking out of confinement). systemd itself is not designed for application isolation and it will try to interact with its processes in various ways.

We could allow this rule though: @{PROC}/1/environ r, (there isn’t anything sensitive in there), but I don’t see either denial on a Ubuntu 16.04 LTS classic or an Ubuntu Core 16 system. I tried various timedatectl invocations. How are you calling it?

note that the timedatectl is a shell wrapper in the core snap calling out to timedatectl.real … could that be the issue here ?

Actually, up above @jenny.murphy mentioned that she is calling ‘timedatectl set-ntp true’ from a java process. Do you have a small reproducer for this that is representative of how you are using java to invoke the program? A simple .java file is fine (I can put it in a snap easy enough).

Hi,
Yes I will produce a code snippet for you over the coming days.
Thanks a lot.
Jenny

name: hello-world-time-java # you probably want to 'snapcraft register ’
version: ‘0.1’ # just for humans, typically ‘1.2+git’ or ‘1.3.2’
summary: Hello World Java Program
description: Simple Hello World Java Program which also uses timedatectl
grade: devel # must be ‘stable’ to release into candidate/stable channels
confinement: devmode # use ‘strict’ once you have the right plugs and slots

apps:
hello-world-java:
command: bin/wrapper
plugs: [time-control, timezone-control, timeserver-control, home, network-control]

parts:
hello:
plugin: ant
source: .
wrapper:
plugin: make
source: .


package oata;

public class HelloWorld {
public static void main(String[] args) {
System.out.println(“Hello World from Java!”);

    try {
    // Disable NTP
    String[] command = new String[]{
       "timedatectl",
        "set-ntp",
        "false"};

Runtime rt = Runtime.getRuntime();
Process p = rt.exec(command);
int exitCode = p.waitFor();

System.out.println(
    	"Command 'timedatectl set-ntp false "
        + " exit code: "
	+ exitCode);
    } catch (Exception e) {
       System.out.println(
    	"Exception caught : "
	+ e.getMessage());
    }
}

}

I posted the snapcraft file and the java code above.
However I don’t get the @{PROC}/1/environ r warning with this program.

How I am calling timedatectl is exactly the same.

The only difference my real snap runs as a service as opposed to command line and has a lot of other interfaces connected.

Does your sample code still trigger the ptrace warning? Also, aside from the warning, does this affect the outcome of your call to ‘timedatectl set-ntp’ (ie. does it function properly)?

Yes the outcome of the call is always as expected , in the sample program and the real program. No I do not get any ptrace warning from the sample code.

I modified some sample Go daemon code to execute timedatectl and wasn’t able to reproduce the error at first. I tried using a full path for the executable /usr/bin/timedatectl and just using the name of the binary.

My code used the status, set-ntp, set-timezone, and set-time functions. One thing I did discover is that if you use the set-time operation, it fails due to a quoting problem in the timedatectl wrapper script. You have a pass the time as a quoted string like this:

sudo timedatectl set-time "2012-10-30 18:17:16"

…and the quotes get dropped in the wrapper script which if the command isn’t “set-timezone”, just does:

$TIMEDATECTL $@

I’ll file a bug for this.

When running my daemon snap, I did see some apparmor errors for timedatectl, but I never saw any for timedatectl.real until I modified the snap to declare plugs for timezone-control, time-control, and timeserver-control. At this point, I started seeing apparmor errors for the various libraries that timedatectl.real actually uses, however I still didn’t see the ptrace error or the /proc/1/environ error. It wasn’t until I actually connected the plugs for the three time interfaces that these errors were logged.

So, to trigger these errors:

  1. Ensure the snap declares plugs for time*-control
  2. Ensure that the snap app that uses timedatectl is a simple daemon
  3. Ensure that the snap daemon calls timedatectl set-ntp true
  4. Ensure that all the time* plugs are connected
3 Likes

@pstolowski Would you mind to have a look into this quoting issue?

Sure, will look at this shortly.

1 Like

could you link the bug please?

@chipaca There’s no bug yet because I haven’t created one. My description above is all that currently exists. I’ll add a bug tomorrow, if you’d like.

I pushed a fix to https://github.com/snapcore/core/pull/64 - I don’t think we need a LP bug for this, this forum topic seems sufficient. Once this is reviewed it will be in the edge core snap for further testing.

@jdstrand Any thoughts on my results above wrt to the apparmor behavior and the errors @jenny.murphy reported? Wondering also if we should go ahead and make the change you suggested and allow access to @{PROC}/1/environ in one of the time* interfaces?

As mentioned from time to time, systemd and its utilities aren’t designed for application isolation and we’ll see issues like this from time to time.

The ‘capability net_admin’ denial is caused because timedatectl is setting ‘SO_RCVBUFFORCE’ and ‘SO_SNDBUFFORCE’ with setsockopt on the systemd socket: /var/run/dbus/system_bus_socket. Reading src/core/socket.c (and confirmed with strace), the EPERM denials are non-fatal because it will then try SO_RCVBUF and SO_SNDBUF which don’t require net_admin.

Reading /proc/1/environ is restricted by the upstream kernel and it manifests iself via the LSMs as a ptrace policy denial. The rules to make these all go away are:

capability net_admin,
@{PROC}/1/environ r,
ptrace (trace) peer=unconfined,

The first net_admin denial is unfortunate, the /proc/1/environ would likely be ‘ok’ for this interface but the ptrace rule is completely unacceptable, since it would all the snap to ptrace any unconfined process on the system. You cannot access @{PROC}/1/environ without the ptrace rule.

Reading src/basic/virt.c from systemd, /proc/1/environ is being read to detect if the process is running in a container (in this specific case, an nspawn’d container). The denials are non-fatal since systemd will assume it isn’t running in a container if it can’t read it (later versions of systemd continue to read /proc/1/sched to determine if running in a container). Snaps are not started via an nspawn container so systemd assuming it isn’t running in a container is just fine. Furthermore, there is nothing in /proc/1/environ that is interesting to the snap, which is why everything works in the face of these denials.

The question then becomes what to do about the denials. I think the best we could do would be to have an explicit deny rule in the timeserver-control and timezone-control interfaces:

deny @{PROC}/1/environ r,

Since we don’t allow reading @{PROC}/*/environ anywhere, I think this is ok. I do not think we should add a deny rule for net_admin though since these interfaces could then not be used with interfaces that grant the capability (deny rules take precedence over allow rules).

I plan to update snappy-debug to discuss these denials within the context of systemd to help alleviate developer confusion.

Bottom line: there is nothing that @jenny.murphy’s snap needs to do. The denials are benign.

FYI, snappy-debug is updated and I created https://github.com/snapcore/snapd/pull/4216