Re: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-26 Thread Miroslav Lichvar
On Sat, Jan 23, 2021 at 05:41:12AM -0800, Richard Cochran wrote:
> We'll have to do something about the port numbering.  The "real" ports
> must start with 1, 2, 3, ... as this is part of the standard.
> 
> Also, there is some code in port_open() and maybe elsewhere that
> treats zero as a special case (meaning UDS), for example:

I guess we should make that more clear.

> Maybe we can have two [!] ports with number zero?

It seems to work, but I suspect it might be confusing, especically if
there are faults reported for one of the ports.

I'll send the whole patchset for review.

Thanks,

-- 
Miroslav Lichvar



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-23 Thread Richard Cochran
On Wed, Jan 20, 2021 at 04:15:21PM +0100, Miroslav Lichvar wrote:
> Add a second UDS port to allow unprivileged applications to monitor
> ptp4l. On this "read-only" port, disable non-GET actions, forwarding,
> and access to subscriptions.
> 
> Ignore non-management messages on both UDS ports to prevent them from
> changing the clock or port state. (This should be a separate patch?)

Yes, please!
 
> TODO:
> - add option to configure the UDS address (default /var/run/ptp4ro?)
> - chmod(0666) ?

I think this sort of policy can be left to the admin via scripting.

> - update man page
> 
> Signed-off-by: Miroslav Lichvar 
> ---
>  clock.c | 122 +++-
>  port.c  |   3 ++
>  2 files changed, 89 insertions(+), 36 deletions(-)
> 
> diff --git a/clock.c b/clock.c
> index 08c61eb..475aa3d 100644
> --- a/clock.c
> +++ b/clock.c
> @@ -95,10 +95,11 @@ struct clock {
>   struct foreign_clock *best;
>   struct ClockIdentity best_id;
>   LIST_HEAD(ports_head, port) ports;
> - struct port *uds_port;
> + struct port *uds_rw_port;

Part of this series is simply renaming the existing port.  It would
ease review to have that in a patch by itself.

> @@ -1173,27 +1201,36 @@ struct clock *clock_create(enum clock_type type, 
> struct config *config,
>  
>   LIST_INIT(>subscribers);
>   LIST_INIT(>ports);
> - c->last_port_number = 0;
> + c->last_port_number = -1;
>  
>   if (clock_resize_pollfd(c, 0)) {
>   pr_err("failed to allocate pollfd");
>   return NULL;
>   }
>  
> - /* Create the UDS interface. */
> - c->uds_port = port_open(phc_device, phc_index, timestamping, 0, 
> c->udsif, c);
> - if (!c->uds_port) {
> - pr_err("failed to open the UDS port");
> + /* Create the UDS interfaces. */
> + c->uds_rw_port = port_open(phc_device, phc_index, timestamping,
> +++c->last_port_number, c->uds_rw_if, c);
> + if (!c->uds_rw_port) {
> + pr_err("failed to open the UDS RW port");
>   return NULL;
>   }
>   clock_fda_changed(c);
>  
> - c->slave_event_monitor = monitor_create(config, c->uds_port);
> + c->slave_event_monitor = monitor_create(config, c->uds_rw_port);
>   if (!c->slave_event_monitor) {
>   pr_err("failed to create slave event monitor");
>   return NULL;
>   }
>  
> + c->uds_ro_port = port_open(phc_device, phc_index, timestamping,
> +++c->last_port_number, c->uds_ro_if, c);

We'll have to do something about the port numbering.  The "real" ports
must start with 1, 2, 3, ... as this is part of the standard.

Also, there is some code in port_open() and maybe elsewhere that
treats zero as a special case (meaning UDS), for example:

p->fault_fd = -1;
if (number) {
p->fault_fd = timerfd_create(CLOCK_MONOTONIC, 0);
...
}

Maybe we can have two [!] ports with number zero?

Thanks,
Richard


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-21 Thread Jacob Keller



On 1/21/2021 12:31 AM, Miroslav Lichvar wrote:
> On Wed, Jan 20, 2021 at 10:13:25PM +, Keller, Jacob E wrote:
>> It makes sense to remove forwarding, but I am not sure I understand the 
>> justification for removing access to subscriptions.. if the subscription is 
>> for read only data, why doesn't it make sense to allow that over the read 
>> only socket?
> 
> The subscription itself requires some state. If we say the new socket
> is safe to be accessed by untrusted applications, we need to be really
> sure they cannot do anything bad, e.g. create a large number of
> subscriptions to crash ptp4l or break subscriptions on the "rw"
> socket. Such issues would become security issues.
> 
> There might be a way to provide subscriptions on the "ro" socket, but
> they need to be separate from the "rw" subscriptions and have some
> limiting implemented.
> 
> I'd like to start with a minimal feature set that we can be
> comfortable with and maybe add other features later if there is a
> demand for them.
> 

Right. This makes sense. We can obviously extend the RO sockets in the
future, but I think it makes sense to limit it. To me, it seems good to
have some condensed version of this explanation in the commit message or
somewhere, since it may not be obvious why it is limited to those on the
outside.


___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-21 Thread Miroslav Lichvar
On Wed, Jan 20, 2021 at 10:13:25PM +, Keller, Jacob E wrote:
> It makes sense to remove forwarding, but I am not sure I understand the 
> justification for removing access to subscriptions.. if the subscription is 
> for read only data, why doesn't it make sense to allow that over the read 
> only socket?

The subscription itself requires some state. If we say the new socket
is safe to be accessed by untrusted applications, we need to be really
sure they cannot do anything bad, e.g. create a large number of
subscriptions to crash ptp4l or break subscriptions on the "rw"
socket. Such issues would become security issues.

There might be a way to provide subscriptions on the "ro" socket, but
they need to be separate from the "rw" subscriptions and have some
limiting implemented.

I'd like to start with a minimal feature set that we can be
comfortable with and maybe add other features later if there is a
demand for them.

-- 
Miroslav Lichvar



___
Linuxptp-devel mailing list
Linuxptp-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linuxptp-devel


Re: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-20 Thread Keller, Jacob E



> -Original Message-
> From: Miroslav Lichvar 
> Sent: Wednesday, January 20, 2021 7:15 AM
> To: linuxptp-devel@lists.sourceforge.net
> Subject: [Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for
> monitoring.
> 
> Add a second UDS port to allow unprivileged applications to monitor
> ptp4l. On this "read-only" port, disable non-GET actions, forwarding,
> and access to subscriptions.
> 

It makes sense to remove forwarding, but I am not sure I understand the 
justification for removing access to subscriptions.. if the subscription is for 
read only data, why doesn't it make sense to allow that over the read only 
socket?

Thanks,
Jake

> Ignore non-management messages on both UDS ports to prevent them from
> changing the clock or port state. (This should be a separate patch?)
> 
> TODO:
> - add option to configure the UDS address (default /var/run/ptp4ro?)
> - chmod(0666) ?
> - update man page
> 
> Signed-off-by: Miroslav Lichvar 
> ---
>  clock.c | 122 +++-
>  port.c  |   3 ++
>  2 files changed, 89 insertions(+), 36 deletions(-)
> 
> diff --git a/clock.c b/clock.c
> index 08c61eb..475aa3d 100644
> --- a/clock.c
> +++ b/clock.c
> @@ -95,10 +95,11 @@ struct clock {
>   struct foreign_clock *best;
>   struct ClockIdentity best_id;
>   LIST_HEAD(ports_head, port) ports;
> - struct port *uds_port;
> + struct port *uds_rw_port;
> + struct port *uds_ro_port;
>   struct pollfd *pollfd;
>   int pollfd_valid;
> - int nports; /* does not include the UDS port */
> + int nports; /* does not include the two UDS ports */
>   int last_port_number;
>   int sde;
>   int free_running;
> @@ -129,7 +130,8 @@ struct clock {
>   struct clock_stats stats;
>   int stats_interval;
>   struct clockcheck *sanity_check;
> - struct interface *udsif;
> + struct interface *uds_rw_if;
> + struct interface *uds_ro_if;
>   LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
>   struct monitor *slave_event_monitor;
>  };
> @@ -245,7 +247,7 @@ void clock_send_notification(struct clock *c, struct
> ptp_message *msg,
>  {
>   unsigned int event_pos = event / 8;
>   uint8_t mask = 1 << (event % 8);
> - struct port *uds = c->uds_port;
> + struct port *uds = c->uds_rw_port;
>   struct clock_subscriber *s;
> 
>   LIST_FOREACH(s, >subscribers, list) {
> @@ -267,13 +269,15 @@ void clock_destroy(struct clock *c)
>  {
>   struct port *p, *tmp;
> 
> - interface_destroy(c->udsif);
> + interface_destroy(c->uds_rw_if);
> + interface_destroy(c->uds_ro_if);
>   clock_flush_subscriptions(c);
>   LIST_FOREACH_SAFE(p, >ports, list, tmp) {
>   clock_remove_port(c, p);
>   }
>   monitor_destroy(c->slave_event_monitor);
> - port_close(c->uds_port);
> + port_close(c->uds_rw_port);
> + port_close(c->uds_ro_port);
>   free(c->pollfd);
>   if (c->clkid != CLOCK_REALTIME) {
>   phc_close(c->clkid);
> @@ -442,8 +446,8 @@ static int clock_management_fill_response(struct clock
> *c, struct port *p,
>   datalen = sizeof(*gsn);
>   break;
>   case TLV_SUBSCRIBE_EVENTS_NP:
> - if (p != c->uds_port) {
> - /* Only the UDS port allowed. */
> + if (p != c->uds_rw_port) {
> + /* Only the UDS RW port allowed. */
>   break;
>   }
>   sen = (struct subscribe_events_np *)tlv->data;
> @@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t
> ingress)
>  static int forwarding(struct clock *c, struct port *p)
>  {
>   enum port_state ps = port_state(p);
> +
> + if (p == c->uds_ro_port)
> + return 0;
> +
>   switch (ps) {
>   case PS_MASTER:
>   case PS_GRAND_MASTER:
> @@ -784,7 +792,7 @@ static int forwarding(struct clock *c, struct port *p)
>   default:
>   break;
>   }
> - if (p == c->uds_port && ps != PS_FAULTY) {
> + if (p == c->uds_rw_port && ps != PS_FAULTY) {
>   return 1;
>   }
>   return 0;
> @@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char
> *phc_device,
>  {
>   struct port *p, *piter, *lastp = NULL;
> 
> - if (clock_resize_pollfd(c, c->nports + 1)) {
> + if (clock_resize_pollfd(c, c->nports + 2)) {
>   return -1;
>   }
>   p = port_open(phc_device, p

[Linuxptp-devel] [RFC PATCH] clock: Add read-only UDS port for monitoring.

2021-01-20 Thread Miroslav Lichvar
Add a second UDS port to allow unprivileged applications to monitor
ptp4l. On this "read-only" port, disable non-GET actions, forwarding,
and access to subscriptions.

Ignore non-management messages on both UDS ports to prevent them from
changing the clock or port state. (This should be a separate patch?)

TODO:
- add option to configure the UDS address (default /var/run/ptp4ro?)
- chmod(0666) ?
- update man page

Signed-off-by: Miroslav Lichvar 
---
 clock.c | 122 +++-
 port.c  |   3 ++
 2 files changed, 89 insertions(+), 36 deletions(-)

diff --git a/clock.c b/clock.c
index 08c61eb..475aa3d 100644
--- a/clock.c
+++ b/clock.c
@@ -95,10 +95,11 @@ struct clock {
struct foreign_clock *best;
struct ClockIdentity best_id;
LIST_HEAD(ports_head, port) ports;
-   struct port *uds_port;
+   struct port *uds_rw_port;
+   struct port *uds_ro_port;
struct pollfd *pollfd;
int pollfd_valid;
-   int nports; /* does not include the UDS port */
+   int nports; /* does not include the two UDS ports */
int last_port_number;
int sde;
int free_running;
@@ -129,7 +130,8 @@ struct clock {
struct clock_stats stats;
int stats_interval;
struct clockcheck *sanity_check;
-   struct interface *udsif;
+   struct interface *uds_rw_if;
+   struct interface *uds_ro_if;
LIST_HEAD(clock_subscribers_head, clock_subscriber) subscribers;
struct monitor *slave_event_monitor;
 };
@@ -245,7 +247,7 @@ void clock_send_notification(struct clock *c, struct 
ptp_message *msg,
 {
unsigned int event_pos = event / 8;
uint8_t mask = 1 << (event % 8);
-   struct port *uds = c->uds_port;
+   struct port *uds = c->uds_rw_port;
struct clock_subscriber *s;
 
LIST_FOREACH(s, >subscribers, list) {
@@ -267,13 +269,15 @@ void clock_destroy(struct clock *c)
 {
struct port *p, *tmp;
 
-   interface_destroy(c->udsif);
+   interface_destroy(c->uds_rw_if);
+   interface_destroy(c->uds_ro_if);
clock_flush_subscriptions(c);
LIST_FOREACH_SAFE(p, >ports, list, tmp) {
clock_remove_port(c, p);
}
monitor_destroy(c->slave_event_monitor);
-   port_close(c->uds_port);
+   port_close(c->uds_rw_port);
+   port_close(c->uds_ro_port);
free(c->pollfd);
if (c->clkid != CLOCK_REALTIME) {
phc_close(c->clkid);
@@ -442,8 +446,8 @@ static int clock_management_fill_response(struct clock *c, 
struct port *p,
datalen = sizeof(*gsn);
break;
case TLV_SUBSCRIBE_EVENTS_NP:
-   if (p != c->uds_port) {
-   /* Only the UDS port allowed. */
+   if (p != c->uds_rw_port) {
+   /* Only the UDS RW port allowed. */
break;
}
sen = (struct subscribe_events_np *)tlv->data;
@@ -774,6 +778,10 @@ static int clock_utc_correct(struct clock *c, tmv_t 
ingress)
 static int forwarding(struct clock *c, struct port *p)
 {
enum port_state ps = port_state(p);
+
+   if (p == c->uds_ro_port)
+   return 0;
+
switch (ps) {
case PS_MASTER:
case PS_GRAND_MASTER:
@@ -784,7 +792,7 @@ static int forwarding(struct clock *c, struct port *p)
default:
break;
}
-   if (p == c->uds_port && ps != PS_FAULTY) {
+   if (p == c->uds_rw_port && ps != PS_FAULTY) {
return 1;
}
return 0;
@@ -818,7 +826,7 @@ static int clock_add_port(struct clock *c, const char 
*phc_device,
 {
struct port *p, *piter, *lastp = NULL;
 
-   if (clock_resize_pollfd(c, c->nports + 1)) {
+   if (clock_resize_pollfd(c, c->nports + 2)) {
return -1;
}
p = port_open(phc_device, phc_index, timestamping,
@@ -1044,20 +1052,40 @@ struct clock *clock_create(enum clock_type type, struct 
config *config,
 
/* Configure the UDS. */
uds_ifname = config_get_string(config, NULL, "uds_address");
-   c->udsif = interface_create(uds_ifname);
-   if (config_set_section_int(config, interface_name(c->udsif),
+   c->uds_rw_if = interface_create(uds_ifname);
+   if (config_set_section_int(config, interface_name(c->uds_rw_if),
   "announceReceiptTimeout", 0)) {
return NULL;
}
-   if (config_set_section_int(config, interface_name(c->udsif),
+   if (config_set_section_int(config, interface_name(c->uds_rw_if),
"delay_mechanism", DM_AUTO)) {
return NULL;
}
-   if (config_set_section_int(config, interface_name(c->udsif),
+   if (config_set_section_int(config, interface_name(c->uds_rw_if),
"network_transport", TRANS_UDS)) {