From c37a28e59ff0194ef71c6b1f6d6c4ca33ca72b2c Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 26 Mar 2020 00:16:04 +0900 Subject: Don't enumerate interfaces if no interfaces were found. When dnsmasq receives a list of interfaces, but cannot find any of them (e.g., because they have all been deleted), it enters the default non-Android codepath where it listens on all interfaces. Then, if any of the interfaces on the system is deleted while it is starting up on all interfaces, it can enter a codepath where it gets stuck for 20(!) seconds for DAD to complete on an interface that no longer exists. Bug: 152695206 Test: new test coverage in netd_integration_test Change-Id: Id9289e5a22dddceb53782d75e3caa4f6a88c6fb1 --- src/network.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network.c b/src/network.c index 34d821d..98b4f68 100644 --- a/src/network.c +++ b/src/network.c @@ -833,8 +833,11 @@ void set_interfaces(const char* interfaces) { * Enumerate IP addresses (via RTM_GETADDR), adding IP entries to * daemon->interfaces for interface names listed in daemon->if_names. * The sockets are created by the create_bound_listener call below. + * Only do this if at least one interface was found. Otherwise, + * enumerate_interfaces will start listening on all interfaces on + * the system. */ - if (!enumerate_interfaces()) { + if (daemon->if_names != NULL && !enumerate_interfaces()) { die(_("enumerate interfaces error in set_interfaces: %s"), NULL, EC_BADNET); } -- cgit v1.2.3 From e7f7704cd1279976b5775bc1ddcb8dfbe8798ab6 Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Tue, 28 Apr 2020 10:32:31 -0700 Subject: Add METADATA to dnsmasq: GPL=RESTRICTED Bug: 68860345 Bug: 69058154 Bug: 151953481 Test: no code changes Change-Id: I891f3b85c9aa6f7e923c9ab5ba0a21f474aa4178 --- METADATA | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 METADATA diff --git a/METADATA b/METADATA new file mode 100644 index 0000000..6d8601b --- /dev/null +++ b/METADATA @@ -0,0 +1,3 @@ +third_party { + license_type: RESTRICTED +} -- cgit v1.2.3 From 97c6e4a8837a7d1c7f7bdf8b27670db6c72c9cd5 Mon Sep 17 00:00:00 2001 From: chenbruce Date: Thu, 3 Sep 2020 17:16:53 +0800 Subject: =?UTF-8?q?Update=20language=20to=20comply=20with=20Android?= =?UTF-8?q?=E2=80=99s=20inclusive=20language=20guidance?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See https://source.android.com/setup/contribute/respectful-code for reference inclusivefixit Bug: 166529523 Test: m Change-Id: Ib436cde848335813528f49207dee88a92a128929 --- src/dnsmasq.c | 6 +++--- src/helper.c | 4 ++-- src/log.c | 2 +- src/network.c | 2 +- src/util.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dnsmasq.c b/src/dnsmasq.c index 27ad864..46d15ee 100644 --- a/src/dnsmasq.c +++ b/src/dnsmasq.c @@ -350,10 +350,10 @@ int main(int argc, char** argv) { if (!(daemon->options & OPT_DEBUG) && getuid() == 0) { int bad_capabilities = 0; - gid_t dummy; + gid_t unused; /* remove all supplimentary groups */ - if (gp && (setgroups(0, &dummy) == -1 || setgid(gp->gr_gid) == -1)) { + if (gp && (setgroups(0, &unused) == -1 || setgid(gp->gr_gid) == -1)) { send_event(err_pipe[1], EVENT_GROUP_ERR, errno); _exit(0); } @@ -571,7 +571,7 @@ static void sig_handler(int sig) { /* alarm is used to kill TCP children after a fixed time. */ if (sig == SIGALRM) _exit(0); } else { - /* master process */ + /* main process */ const int errsave = errno; int event; diff --git a/src/helper.c b/src/helper.c index eb6614a..3e414b2 100644 --- a/src/helper.c +++ b/src/helper.c @@ -75,8 +75,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd) { sigaction(SIGALRM, &sigact, NULL); if (!(daemon->options & OPT_DEBUG) && uid != 0) { - gid_t dummy; - if (setgroups(0, &dummy) == -1 || setgid(gid) == -1 || setuid(uid) == -1) { + gid_t unused; + if (setgroups(0, &unused) == -1 || setgid(gid) == -1 || setuid(uid) == -1) { if (daemon->options & OPT_NO_FORK) /* send error to daemon process if no-fork */ send_event(event_fd, EVENT_HUSER_ERR, errno); else { diff --git a/src/log.c b/src/log.c index d1fcfb9..1cc4745 100644 --- a/src/log.c +++ b/src/log.c @@ -104,7 +104,7 @@ int log_reopen(char* log_file) { return log_fd != -1; } else #if defined(__ANDROID__) -#define _PATH_LOG "" /* dummy */ +#define _PATH_LOG "" /* unused */ log_fd = -1; #else { diff --git a/src/network.c b/src/network.c index 98b4f68..d542c94 100644 --- a/src/network.c +++ b/src/network.c @@ -180,7 +180,7 @@ static int iface_allowed(struct irec** irecp, int if_index, union mysockaddr* ad #ifdef HAVE_IPV6 static int iface_allowed_v6(struct in6_addr* local, int scope, int if_index, void* vparam) { union mysockaddr addr; - struct in_addr netmask; /* dummy */ + struct in_addr netmask; /* unused */ netmask.s_addr = 0; diff --git a/src/util.c b/src/util.c index 53e3137..b188bce 100644 --- a/src/util.c +++ b/src/util.c @@ -266,12 +266,12 @@ int hostname_isequal(char* a, char* b) { time_t dnsmasq_time(void) { #ifdef HAVE_BROKEN_RTC - struct tms dummy; + struct tms unused; static long tps = 0; if (tps == 0) tps = sysconf(_SC_CLK_TCK); - return (time_t)(times(&dummy) / tps); + return (time_t)(times(&unused) / tps); #else return time(NULL); #endif -- cgit v1.2.3 From b7ae3453bfcc139be75c8dec5cdb8a1453eb6e16 Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 5 Oct 2020 18:37:47 +0800 Subject: dnsmasq: fix heap overflow Backport CVE-2017-14491. (http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=0549c73b7ea6b22a3c49beb4d432f185a81efcbc) Bug: 158221622 Test: 1. Manual testing - build dnsmasq with asan enabled and test the corresponding functionalities. 2. Test tethering still worked fine Change-Id: I90390535198fe0a7b8084879d39f813d8de51ab3 --- src/dnsmasq.h | 2 +- src/rfc1035.c | 28 +++++++++++++++++++++++++--- src/rfc2131.c | 4 ++-- src/util.c | 11 +++++++++-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 2c5f964..9af3a2c 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -684,7 +684,7 @@ void rand_init(void); unsigned short rand16(void); int legal_hostname(char* c); char* canonicalise(char* s, int* nomem); -unsigned char* do_rfc1035_name(unsigned char* p, char* sval); +unsigned char* do_rfc1035_name(unsigned char* p, char* sval, char *limit); void* safe_malloc(size_t size); void safe_pipe(int* fd, int read_noblock); void* whine_malloc(size_t size); diff --git a/src/rfc1035.c b/src/rfc1035.c index 0f883e1..47479ab 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -847,9 +847,19 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne unsigned short usval; long lval; char* sval; +#define CHECK_LIMIT(size) \ + if (limit && p + (size) > (unsigned char*)limit) { \ + va_end(ap); \ + goto truncated; \ + } if (truncp && *truncp) return 0; + va_start(ap, format); /* make ap point to 1st unamed argument */ + + /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ + CHECK_LIMIT(12); + PUTSHORT(nameoffset | 0xc000, p); PUTSHORT(type, p); PUTSHORT(class, p); @@ -858,11 +868,10 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne sav = p; /* Save pointer to RDLength field */ PUTSHORT(0, p); /* Placeholder RDLength */ - va_start(ap, format); /* make ap point to 1st unamed argument */ - for (; *format; format++) switch (*format) { #ifdef HAVE_IPV6 case '6': + CHECK_LIMIT(IN6ADDRSZ); sval = va_arg(ap, char*); memcpy(p, sval, IN6ADDRSZ); p += IN6ADDRSZ; @@ -870,17 +879,20 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne #endif case '4': + CHECK_LIMIT(INADDRSZ); sval = va_arg(ap, char*); memcpy(p, sval, INADDRSZ); p += INADDRSZ; break; case 's': + CHECK_LIMIT(2); usval = va_arg(ap, int); PUTSHORT(usval, p); break; case 'l': + CHECK_LIMIT(4); lval = va_arg(ap, long); PUTLONG(lval, p); break; @@ -888,12 +900,18 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne case 'd': /* get domain-name answer arg and store it in RDATA field */ if (offset) *offset = p - (unsigned char*) header; - p = do_rfc1035_name(p, va_arg(ap, char*)); + p = do_rfc1035_name(p, va_arg(ap, char*), limit); + if (!p) { + va_end(ap); + goto truncated; + } + CHECK_LIMIT(1); *p++ = 0; break; case 't': usval = va_arg(ap, int); + CHECK_LIMIT(usval); sval = va_arg(ap, char*); memcpy(p, sval, usval); p += usval; @@ -903,19 +921,23 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne sval = va_arg(ap, char*); usval = sval ? strlen(sval) : 0; if (usval > 255) usval = 255; + CHECK_LIMIT(usval + 1); *p++ = (unsigned char) usval; memcpy(p, sval, usval); p += usval; break; } +#undef CHECK_LIMIT va_end(ap); /* clean up variable argument pointer */ j = p - sav - 2; + /* this has already been checked against limit before */ PUTSHORT(j, sav); /* Now, store real RDLength */ /* check for overflow of buffer */ if (limit && ((unsigned char*) limit - p) < 0) { +truncated: if (truncp) *truncp = 1; return 0; } diff --git a/src/rfc2131.c b/src/rfc2131.c index f74ecb9..c0f649a 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -1889,8 +1889,8 @@ static void do_options(struct dhcp_context* context, struct dhcp_packet* mess, u *(p++) = 255; if (fqdn_flags & 0x04) { - p = do_rfc1035_name(p, hostname); - if (domain) p = do_rfc1035_name(p, domain); + p = do_rfc1035_name(p, hostname, NULL); + if (domain) p = do_rfc1035_name(p, domain, NULL); *p++ = 0; } else { memcpy(p, hostname, strlen(hostname)); diff --git a/src/util.c b/src/util.c index b188bce..175b7bb 100644 --- a/src/util.c +++ b/src/util.c @@ -190,12 +190,19 @@ char* canonicalise(char* in, int* nomem) { return ret; } -unsigned char* do_rfc1035_name(unsigned char* p, char* sval) { +unsigned char* do_rfc1035_name(unsigned char* p, char* sval, char *limit) { int j; while (sval && *sval) { + if (limit && p + 1 > (unsigned char*)limit) + return p; + unsigned char* cp = p++; - for (j = 0; *sval && (*sval != '.'); sval++, j++) *p++ = *sval; + for (j = 0; *sval && (*sval != '.'); sval++, j++) { + if (limit && p + 1 > (unsigned char*)limit) + return p; + *p++ = *sval; + } *cp = j; if (*sval) sval++; } -- cgit v1.2.3 From 8898837825af095f6bb9923d0ea5211fdeb9f3b7 Mon Sep 17 00:00:00 2001 From: Tyler Wear Date: Wed, 11 Nov 2020 09:20:58 -0800 Subject: dnsmasq: Remove DAD Retry DAD is disabled in TetherController, which sets accept_dad and dad_transmits to zero, so the the retry here doesn't help wrt DAD. The loop will lock dnsmasq for up to 20 seconds in error scenario's though, which is undesirable. Since IFA_F_NODAD is not set on address loop will be reduced to 1 second for now. When bind fails die() should not be called since dnsmasq is never restarted as long as tethering is enabled. Cleaning up and returning should suffice while not impacting on going tethering. Bug: 171409363 Change-Id: Id0c065c75c869d7bd241390682b7e5d932a74a22 --- src/config.h | 2 +- src/network.c | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/config.h b/src/config.h index 05d74ae..14b5c98 100644 --- a/src/config.h +++ b/src/config.h @@ -69,7 +69,7 @@ #define DHCP_CLIENT_ALTPORT 1068 #define LOG_MAX 5 /* log-queue length */ #define RANDFILE "/dev/urandom" -#define DAD_WAIT 20 /* retry binding IPv6 sockets for this long */ +#define DAD_WAIT 1 /* retry binding IPv6 sockets for this long */ /* A small collection of RR-types which are missing on some platforms */ diff --git a/src/network.c b/src/network.c index d542c94..1bc3c21 100644 --- a/src/network.c +++ b/src/network.c @@ -360,7 +360,6 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { new->next = *listeners; new->tcpfd = -1; new->fd = -1; - *listeners = new; if (daemon->port != 0) { if ((new->tcpfd = socket(iface->addr.sa.sa_family, SOCK_STREAM, 0)) == -1 || @@ -378,12 +377,17 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { } #endif + /* Unless the IPv6 address is added with IFA_F_NODAD, bind() can fail even if DAD + is disabled on the interface. This is because without IFA_F_NODAD the IPv6 + address creation call moves the IPv6 address to tentative. A timer will + fire to immediately remove the tentative flag, but this is not sufficient to + avoid a race condition (see comments in tun_interface.cpp and iproute.py). */ while (1) { if ((rc = bind(new->fd, &iface->addr.sa, sa_len(&iface->addr))) != -1) break; #ifdef HAVE_IPV6 /* An interface may have an IPv6 address which is still undergoing DAD. - If so, the bind will fail until the DAD completes, so we try over 20 seconds + If so, the bind will fail until the DAD completes, so we try again before failing. */ /* TODO: What to do here? 20 seconds is way too long. We use optimistic addresses, so bind() will only fail if the address has already failed DAD, in which case retrying @@ -399,7 +403,11 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { if (rc == -1 || bind(new->tcpfd, &iface->addr.sa, sa_len(&iface->addr)) == -1) { prettyprint_addr(&iface->addr, daemon->namebuff); - die(_("failed to bind listening socket for %s: %s"), daemon->namebuff, EC_BADNET); + close(new->fd); + close(new->tcpfd); + free(new); + syslog(LOG_ERR, _("failed to bind listening socket for %s"), daemon->namebuff); + return; } uint32_t mark = daemon->listen_mark; @@ -409,6 +417,7 @@ void create_bound_listener(struct listener** listeners, struct irec* iface) { if (listen(new->tcpfd, 5) == -1) die(_("failed to listen on socket: %s"), NULL, EC_BADNET); } + *listeners = new; } /** -- cgit v1.2.3 From 10ba39da6b98043989b1a604f533d5b647ee7bda Mon Sep 17 00:00:00 2001 From: Luke Huang Date: Mon, 5 Oct 2020 18:37:47 +0800 Subject: dnsmasq: fix heap overflow Backport CVE-2017-14491. (http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=commit;h=0549c73b7ea6b22a3c49beb4d432f185a81efcbc) Bug: 158221622 Test: 1. Manual testing - build dnsmasq with asan enabled and test the corresponding functionalities. 2. Test tethering still worked fine Change-Id: I90390535198fe0a7b8084879d39f813d8de51ab3 (cherry picked from commit b7ae3453bfcc139be75c8dec5cdb8a1453eb6e16) (cherry picked from commit 2c415e570aed0b955698238a274a50f3ffa4892e) --- src/dnsmasq.h | 2 +- src/rfc1035.c | 28 +++++++++++++++++++++++++--- src/rfc2131.c | 4 ++-- src/util.c | 11 +++++++++-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 2c5f964..9af3a2c 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -684,7 +684,7 @@ void rand_init(void); unsigned short rand16(void); int legal_hostname(char* c); char* canonicalise(char* s, int* nomem); -unsigned char* do_rfc1035_name(unsigned char* p, char* sval); +unsigned char* do_rfc1035_name(unsigned char* p, char* sval, char *limit); void* safe_malloc(size_t size); void safe_pipe(int* fd, int read_noblock); void* whine_malloc(size_t size); diff --git a/src/rfc1035.c b/src/rfc1035.c index 0f883e1..47479ab 100644 --- a/src/rfc1035.c +++ b/src/rfc1035.c @@ -847,9 +847,19 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne unsigned short usval; long lval; char* sval; +#define CHECK_LIMIT(size) \ + if (limit && p + (size) > (unsigned char*)limit) { \ + va_end(ap); \ + goto truncated; \ + } if (truncp && *truncp) return 0; + va_start(ap, format); /* make ap point to 1st unamed argument */ + + /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */ + CHECK_LIMIT(12); + PUTSHORT(nameoffset | 0xc000, p); PUTSHORT(type, p); PUTSHORT(class, p); @@ -858,11 +868,10 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne sav = p; /* Save pointer to RDLength field */ PUTSHORT(0, p); /* Placeholder RDLength */ - va_start(ap, format); /* make ap point to 1st unamed argument */ - for (; *format; format++) switch (*format) { #ifdef HAVE_IPV6 case '6': + CHECK_LIMIT(IN6ADDRSZ); sval = va_arg(ap, char*); memcpy(p, sval, IN6ADDRSZ); p += IN6ADDRSZ; @@ -870,17 +879,20 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne #endif case '4': + CHECK_LIMIT(INADDRSZ); sval = va_arg(ap, char*); memcpy(p, sval, INADDRSZ); p += INADDRSZ; break; case 's': + CHECK_LIMIT(2); usval = va_arg(ap, int); PUTSHORT(usval, p); break; case 'l': + CHECK_LIMIT(4); lval = va_arg(ap, long); PUTLONG(lval, p); break; @@ -888,12 +900,18 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne case 'd': /* get domain-name answer arg and store it in RDATA field */ if (offset) *offset = p - (unsigned char*) header; - p = do_rfc1035_name(p, va_arg(ap, char*)); + p = do_rfc1035_name(p, va_arg(ap, char*), limit); + if (!p) { + va_end(ap); + goto truncated; + } + CHECK_LIMIT(1); *p++ = 0; break; case 't': usval = va_arg(ap, int); + CHECK_LIMIT(usval); sval = va_arg(ap, char*); memcpy(p, sval, usval); p += usval; @@ -903,19 +921,23 @@ static int add_resource_record(HEADER* header, char* limit, int* truncp, unsigne sval = va_arg(ap, char*); usval = sval ? strlen(sval) : 0; if (usval > 255) usval = 255; + CHECK_LIMIT(usval + 1); *p++ = (unsigned char) usval; memcpy(p, sval, usval); p += usval; break; } +#undef CHECK_LIMIT va_end(ap); /* clean up variable argument pointer */ j = p - sav - 2; + /* this has already been checked against limit before */ PUTSHORT(j, sav); /* Now, store real RDLength */ /* check for overflow of buffer */ if (limit && ((unsigned char*) limit - p) < 0) { +truncated: if (truncp) *truncp = 1; return 0; } diff --git a/src/rfc2131.c b/src/rfc2131.c index f74ecb9..c0f649a 100644 --- a/src/rfc2131.c +++ b/src/rfc2131.c @@ -1889,8 +1889,8 @@ static void do_options(struct dhcp_context* context, struct dhcp_packet* mess, u *(p++) = 255; if (fqdn_flags & 0x04) { - p = do_rfc1035_name(p, hostname); - if (domain) p = do_rfc1035_name(p, domain); + p = do_rfc1035_name(p, hostname, NULL); + if (domain) p = do_rfc1035_name(p, domain, NULL); *p++ = 0; } else { memcpy(p, hostname, strlen(hostname)); diff --git a/src/util.c b/src/util.c index 53e3137..11b43a0 100644 --- a/src/util.c +++ b/src/util.c @@ -190,12 +190,19 @@ char* canonicalise(char* in, int* nomem) { return ret; } -unsigned char* do_rfc1035_name(unsigned char* p, char* sval) { +unsigned char* do_rfc1035_name(unsigned char* p, char* sval, char *limit) { int j; while (sval && *sval) { + if (limit && p + 1 > (unsigned char*)limit) + return p; + unsigned char* cp = p++; - for (j = 0; *sval && (*sval != '.'); sval++, j++) *p++ = *sval; + for (j = 0; *sval && (*sval != '.'); sval++, j++) { + if (limit && p + 1 > (unsigned char*)limit) + return p; + *p++ = *sval; + } *cp = j; if (*sval) sval++; } -- cgit v1.2.3 From fe5c6adf43b3a754b093292ac4409dc87778ca5b Mon Sep 17 00:00:00 2001 From: Bob Badour Date: Fri, 12 Feb 2021 15:35:46 -0800 Subject: [LSC] Add LOCAL_LICENSE_KINDS to external/dnsmasq Added SPDX-license-identifier-BSD SPDX-license-identifier-GPL SPDX-license-identifier-GPL-2.0 SPDX-license-identifier-LGPL SPDX-license-identifier-MIT legacy_unencumbered to: src/Android.bp Bug: 68860345 Bug: 151177513 Bug: 151953481 Test: m all Exempt-From-Owner-Approval: janitorial work Change-Id: I910cb218b69e54a56cd9d51b655021fc7115e583 --- src/Android.bp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/Android.bp b/src/Android.bp index c764039..052e3e6 100644 --- a/src/Android.bp +++ b/src/Android.bp @@ -1,3 +1,37 @@ +package { + default_applicable_licenses: ["external_dnsmasq_src_license"], +} + +// Added automatically by a large-scale-change that took the approach of +// 'apply every license found to every target'. While this makes sure we respect +// every license restriction, it may not be entirely correct. +// +// e.g. GPL in an MIT project might only apply to the contrib/ directory. +// +// Please consider splitting the single license below into multiple licenses, +// taking care not to lose any license_kind information, and overriding the +// default license using the 'licenses: [...]' property on targets as needed. +// +// For unused files, consider creating a 'fileGroup' with "//visibility:private" +// to attach the license to, and including a comment whether the files may be +// used in the current project. +// See: http://go/android-license-faq +license { + name: "external_dnsmasq_src_license", + visibility: [":__subpackages__"], + license_kinds: [ + "SPDX-license-identifier-BSD", + "SPDX-license-identifier-GPL", + "SPDX-license-identifier-GPL-2.0", + "SPDX-license-identifier-LGPL", + "SPDX-license-identifier-MIT", + "legacy_unencumbered", + ], + license_text: [ + "NOTICE", + ], +} + cc_binary { name: "dnsmasq", srcs: [ -- cgit v1.2.3