diff mbox series

[v2,2/9] uci: maintain option position in uci_set

Message ID 20221120010828.23765-3-jan@venekamp.net
State Accepted
Delegated to: Hauke Mehrtens
Headers show
Series [v2,1/9] uci: fix use-after-free uci_set on update option | expand

Commit Message

Jan Venekamp Nov. 20, 2022, 1:08 a.m. UTC
Maintain the position of an option in the list when updating an option
in uci_set.

Signed-off-by: Jan Venekamp <jan@venekamp.net>
---
 list.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Paul Oranje Nov. 21, 2022, 3:44 p.m. UTC | #1
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
Op 20 nov. 2022, om 02:08 heeft Jan Venekamp <jan@venekamp.net> het volgende geschreven:
> 
> Maintain the position of an option in the list when updating an option
> in uci_set.
> 
> Signed-off-by: Jan Venekamp <jan@venekamp.net>
> ---
> list.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/list.c b/list.c
> index ac3686c..a8f2a2c 100644
> --- a/list.c
> +++ b/list.c
> @@ -76,7 +76,7 @@ uci_free_element(struct uci_element *e)
> }
> 
> static struct uci_option *
> -uci_alloc_option(struct uci_section *s, const char *name, const char *value)
> +uci_alloc_option(struct uci_section *s, const char *name, const char *value, struct uci_list *after)
> {
> 	struct uci_package *p = s->package;
> 	struct uci_context *ctx = p->ctx;
> @@ -87,7 +87,7 @@ uci_alloc_option(struct uci_section *s, const char *name, const char *value)
> 	o->v.string = uci_dataptr(o);
> 	o->section = s;
> 	strcpy(o->v.string, value);
> -	uci_list_add(&s->options, &o->e.list);
> +	uci_list_insert(after ? after : s->options.prev, &o->e.list);
> 
> 	return o;
> }
> @@ -719,7 +719,7 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
> 
> 		return uci_delete(ctx, ptr);
> 	} else if (!ptr->o && ptr->option) { /* new option */
> -		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
> +		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, NULL);
> 		ptr->last = &ptr->o->e;
> 	} else if (!ptr->s && ptr->section) { /* new section */
> 		ptr->s = uci_alloc_section(ptr->p, ptr->value, ptr->section);
> @@ -731,7 +731,7 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
> 			!strcmp(ptr->o->v.string, ptr->value))
> 			return 0;
> 
> -		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
> +		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, &old->e.list);
> 		if (ptr->option == old->e.name)
> 			ptr->option = ptr->o->e.name;
> 		uci_free_option(old);
> -- 
> 2.32.0 (Apple Git-132)
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Nice, as this keeps tediously hand-edited config files better intact.
Paul
Paul Oranje Nov. 21, 2022, 3:44 p.m. UTC | #2
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
Op 20 nov. 2022, om 02:08 heeft Jan Venekamp <jan@venekamp.net> het volgende geschreven:
> 
> Maintain the position of an option in the list when updating an option
> in uci_set.
> 
> Signed-off-by: Jan Venekamp <jan@venekamp.net>
> ---
> list.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/list.c b/list.c
> index ac3686c..a8f2a2c 100644
> --- a/list.c
> +++ b/list.c
> @@ -76,7 +76,7 @@ uci_free_element(struct uci_element *e)
> }
> 
> static struct uci_option *
> -uci_alloc_option(struct uci_section *s, const char *name, const char *value)
> +uci_alloc_option(struct uci_section *s, const char *name, const char *value, struct uci_list *after)
> {
> 	struct uci_package *p = s->package;
> 	struct uci_context *ctx = p->ctx;
> @@ -87,7 +87,7 @@ uci_alloc_option(struct uci_section *s, const char *name, const char *value)
> 	o->v.string = uci_dataptr(o);
> 	o->section = s;
> 	strcpy(o->v.string, value);
> -	uci_list_add(&s->options, &o->e.list);
> +	uci_list_insert(after ? after : s->options.prev, &o->e.list);
> 
> 	return o;
> }
> @@ -719,7 +719,7 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
> 
> 		return uci_delete(ctx, ptr);
> 	} else if (!ptr->o && ptr->option) { /* new option */
> -		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
> +		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, NULL);
> 		ptr->last = &ptr->o->e;
> 	} else if (!ptr->s && ptr->section) { /* new section */
> 		ptr->s = uci_alloc_section(ptr->p, ptr->value, ptr->section);
> @@ -731,7 +731,7 @@ int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
> 			!strcmp(ptr->o->v.string, ptr->value))
> 			return 0;
> 
> -		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
> +		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, &old->e.list);
> 		if (ptr->option == old->e.name)
> 			ptr->option = ptr->o->e.name;
> 		uci_free_option(old);
> -- 
> 2.32.0 (Apple Git-132)
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Nice, as this keeps tediously hand-edited config files better intact.
Paul
Andre Heider Nov. 26, 2022, 10:02 a.m. UTC | #3
On 20/11/2022 02:08, Jan Venekamp wrote:
> Maintain the position of an option in the list when updating an option
> in uci_set.

Nice, that's really an annoyance!

I assume this doesn't fix wiping '#' comments when saving through luci? 
That's just as annoying :)

Cheers,
Andre
Paul Oranje Nov. 30, 2022, 12:36 p.m. UTC | #4
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
Op 26 nov. 2022, om 11:02 heeft Andre Heider <a.heider@gmail.com> het volgende geschreven:
> 
> On 20/11/2022 02:08, Jan Venekamp wrote:
>> Maintain the position of an option in the list when updating an option
>> in uci_set.
> 
> Nice, that's really an annoyance!
> 
> I assume this doesn't fix wiping '#' comments when saving through luci? That's just as annoying :)
An alternative for # comments is adding "option comment blabla".
These will survive any updates from (L)UCI.

> 
> Cheers,
> Andre
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
Paul Oranje Nov. 30, 2022, 12:36 p.m. UTC | #5
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
Op 26 nov. 2022, om 11:02 heeft Andre Heider <a.heider@gmail.com> het volgende geschreven:
> 
> On 20/11/2022 02:08, Jan Venekamp wrote:
>> Maintain the position of an option in the list when updating an option
>> in uci_set.
> 
> Nice, that's really an annoyance!
> 
> I assume this doesn't fix wiping '#' comments when saving through luci? That's just as annoying :)
An alternative for # comments is adding "option comment blabla".
These will survive any updates from (L)UCI.

> 
> Cheers,
> Andre
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
diff mbox series

Patch

diff --git a/list.c b/list.c
index ac3686c..a8f2a2c 100644
--- a/list.c
+++ b/list.c
@@ -76,7 +76,7 @@  uci_free_element(struct uci_element *e)
 }
 
 static struct uci_option *
-uci_alloc_option(struct uci_section *s, const char *name, const char *value)
+uci_alloc_option(struct uci_section *s, const char *name, const char *value, struct uci_list *after)
 {
 	struct uci_package *p = s->package;
 	struct uci_context *ctx = p->ctx;
@@ -87,7 +87,7 @@  uci_alloc_option(struct uci_section *s, const char *name, const char *value)
 	o->v.string = uci_dataptr(o);
 	o->section = s;
 	strcpy(o->v.string, value);
-	uci_list_add(&s->options, &o->e.list);
+	uci_list_insert(after ? after : s->options.prev, &o->e.list);
 
 	return o;
 }
@@ -719,7 +719,7 @@  int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
 
 		return uci_delete(ctx, ptr);
 	} else if (!ptr->o && ptr->option) { /* new option */
-		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
+		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, NULL);
 		ptr->last = &ptr->o->e;
 	} else if (!ptr->s && ptr->section) { /* new section */
 		ptr->s = uci_alloc_section(ptr->p, ptr->value, ptr->section);
@@ -731,7 +731,7 @@  int uci_set(struct uci_context *ctx, struct uci_ptr *ptr)
 			!strcmp(ptr->o->v.string, ptr->value))
 			return 0;
 
-		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value);
+		ptr->o = uci_alloc_option(ptr->s, ptr->option, ptr->value, &old->e.list);
 		if (ptr->option == old->e.name)
 			ptr->option = ptr->o->e.name;
 		uci_free_option(old);