In the static mode, drop the privileges after opening the clocks. In the automatic mode, drop the privileges before opening the UDS port, which is required to get the list of interfaces, but is the part of the operation that needs to be protected most. The non-root user must have permissions to open the clocks.
Add special handling of the NTPSHM servo, which requires root. Create the servo before creating clocks (which happens after dropping root in the automatic mode) and share it amongst all clocks. Signed-off-by: Miroslav Lichvar <mlich...@redhat.com> --- phc2sys.8 | 10 ++++++++++ phc2sys.c | 29 +++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/phc2sys.8 b/phc2sys.8 index 99fc937..a829874 100644 --- a/phc2sys.8 +++ b/phc2sys.8 @@ -393,6 +393,16 @@ Same as option .B \-z (see above). +.TP +.B user +The name of the user to which should +.B phc2sys +switch in order to drop the root privileges. By default, +.B phc2sys +will keep the identity of the user under which it is started. With the +.B \-a +option the non-root user must have permissions to open the PHC devices. + .SH TIME SCALE USAGE .B Ptp4l diff --git a/phc2sys.c b/phc2sys.c index b428b9f..35e56d7 100644 --- a/phc2sys.c +++ b/phc2sys.c @@ -108,6 +108,7 @@ struct phc2sys_private { LIST_HEAD(clock_head, clock) clocks; LIST_HEAD(dst_clock_head, clock) dst_clocks; struct clock *master; + struct servo *shared_servo; }; static struct config *phc2sys_config; @@ -125,6 +126,10 @@ static struct servo *servo_add(struct phc2sys_private *priv, int max_ppb; struct servo *servo; + if (priv->shared_servo) { + return priv->shared_servo; + } + clockadj_init(clock->clkid); ppb = clockadj_get_freq(clock->clkid); /* The reading may silently fail and return 0, reset the frequency to @@ -214,7 +219,7 @@ static void clock_cleanup(struct phc2sys_private *priv) struct clock *c, *tmp; LIST_FOREACH_SAFE(c, &priv->clocks, list, tmp) { - if (c->servo) { + if (c->servo && !priv->shared_servo) { servo_destroy(c->servo); } if (c->sanity_check) { @@ -234,6 +239,9 @@ static void clock_cleanup(struct phc2sys_private *priv) } free(c); } + + if (priv->shared_servo) + servo_destroy(priv->shared_servo); } static void port_cleanup(struct phc2sys_private *priv) @@ -329,7 +337,8 @@ static void clock_reinit(struct phc2sys_private *priv, struct clock *clock, clock->phc_index = phc_index; if (clock->servo) { - servo_destroy(clock->servo); + if (clock->servo != priv->shared_servo) + servo_destroy(clock->servo); clock->servo = NULL; } @@ -1301,14 +1310,23 @@ int main(int argc, char *argv[]) if (priv.servo_type == CLOCK_SERVO_NTPSHM) { config_set_int(cfg, "kernel_leap", 0); config_set_int(cfg, "sanity_freq_limit", 0); + + /* The servo needs to be created before dropping root and it + will be shared among all clocks */ + priv.shared_servo = servo_create(phc2sys_config, + priv.servo_type, 0, 0, 0); + if (!priv.shared_servo) + goto end; } priv.kernel_leap = config_get_int(cfg, NULL, "kernel_leap"); priv.sanity_freq_limit = config_get_int(cfg, NULL, "sanity_freq_limit"); - snprintf(uds_local, sizeof(uds_local), "/var/run/phc2sys.%d", - getpid()); + /* Directory will be copied from ptp4l address */ + snprintf(uds_local, sizeof(uds_local), "phc2sys.%d", getpid()); if (autocfg) { + if (drop_root_privileges(config_get_string(cfg, NULL, "user"))) + goto end; if (init_pmc_node(cfg, priv.agent, uds_local, phc2sys_recv_subscribed, &priv)) goto end; @@ -1323,6 +1341,9 @@ int main(int argc, char *argv[]) goto end; } + if (drop_root_privileges(config_get_string(cfg, NULL, "user"))) + goto end; + r = -1; if (wait_sync) { -- 2.26.3 _______________________________________________ Linuxptp-devel mailing list Linuxptp-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linuxptp-devel