lede-packages-rs

git clone git://archive.git.mtrnord.blog/MTRNord/lede-packages-rs.git
Log | Files | Refs | README | LICENSE

100-linux_fixes.patch (13228B)


      1 diff --git a/.gitignore b/.gitignore
      2 new file mode 100644
      3 index 0000000..920cdfc
      4 --- /dev/null
      5 +++ b/.gitignore
      6 @@ -0,0 +1,4 @@
      7 +Clients/build
      8 +mDNSPosix/build
      9 +mDNSPosix/objects
     10 +
     11 diff --git a/Clients/Makefile b/Clients/Makefile
     12 index 383af31..925c20e 100755
     13 --- a/Clients/Makefile
     14 +++ b/Clients/Makefile
     15 @@ -34,7 +34,7 @@ TARGETS = build/dns-sd build/dns-sd64
     16  LIBS =
     17  else
     18  TARGETS = build/dns-sd
     19 -LIBS = -L../mDNSPosix/build/prod/ -ldns_sd
     20 +LIBS ?= -L../mDNSPosix/build/prod/ -ldns_sd
     21  endif
     22  
     23  all: $(TARGETS)
     24 diff --git a/mDNSPosix/PosixDaemon.c b/mDNSPosix/PosixDaemon.c
     25 index 88b3292..e86a6c7 100644
     26 --- a/mDNSPosix/PosixDaemon.c
     27 +++ b/mDNSPosix/PosixDaemon.c
     28 @@ -37,6 +37,11 @@
     29  #include <fcntl.h>
     30  #include <pwd.h>
     31  #include <sys/types.h>
     32 +#ifdef __linux__
     33 +#include <sys/capability.h> /* !!! We require libcap-dev for this. Oh well. */
     34 +/* prctl is required to enable inheriting of capabilities across setuid */
     35 +#include <sys/prctl.h>
     36 +#endif /* __linux__ */
     37  
     38  #if __APPLE__
     39  #undef daemon
     40 @@ -184,16 +189,50 @@ int main(int argc, char **argv)
     41  
     42      Reconfigure(&mDNSStorage);
     43  
     44 +#ifdef __linux__
     45 +    /*
     46 +     * SO_BINDTODEVICE is privileged operation; however, we can get
     47 +     * around it using capabilities instead of remaining root.
     48 +     */
     49 +    if (mStatus_NoError == err)
     50 +      {
     51 +        if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
     52 +          perror("prctl PR_SET_KEEPCAPS");
     53 +      }
     54 +#endif /* __linux__ */
     55 +
     56      // Now that we're finished with anything privileged, switch over to running as "nobody"
     57      if (mStatus_NoError == err)
     58      {
     59          const struct passwd *pw = getpwnam("nobody");
     60          if (pw != NULL)
     61 +          {
     62              setuid(pw->pw_uid);
     63 +#ifdef __linux__
     64 +            struct __user_cap_header_struct ch;
     65 +            struct __user_cap_data_struct cd[_LINUX_CAPABILITY_U32S_3];
     66 +
     67 +            memset(&ch, 0, sizeof(ch));
     68 +            ch.version = _LINUX_CAPABILITY_VERSION_3;
     69 +            ch.pid = getpid();
     70 +            memset(&cd[0], 0, sizeof(cd));
     71 +            /* CAP_NET_RAW is required to use SO_BINDTODEVICE */
     72 +            int caps = CAP_TO_MASK(CAP_NET_RAW);
     73 +            cd[0].permitted = caps;
     74 +            cd[0].effective = caps;
     75 +            if (capset(&ch, &cd[0]) < 0)
     76 +              perror("capset");
     77 +#endif /* __linux__ */
     78 +          }
     79          else
     80              LogMsg("WARNING: mdnsd continuing as root because user \"nobody\" does not exist");
     81      }
     82  
     83 +#ifdef __linux__
     84 +    if (mStatus_NoError == err)
     85 +      err = mDNSPlatformPosixRefreshInterfaceList(&mDNSStorage);
     86 +#endif /* __linux__ */
     87 +
     88      if (mStatus_NoError == err)
     89          err = MainLoop(&mDNSStorage);
     90  
     91 diff --git a/mDNSPosix/Responder.c b/mDNSPosix/Responder.c
     92 index 3996b7b..e58d8eb 100755
     93 --- a/mDNSPosix/Responder.c
     94 +++ b/mDNSPosix/Responder.c
     95 @@ -603,7 +603,8 @@ static mStatus RegisterServicesInFile(const char *filePath)
     96          status = mStatus_UnknownErr;
     97      }
     98  
     99 -    assert(0 == fclose(fp));
    100 +    int rv = fclose(fp);
    101 +    assert(0 == rv);
    102  
    103      return status;
    104  }
    105 diff --git a/mDNSPosix/mDNSPosix.c b/mDNSPosix/mDNSPosix.c
    106 index 6effa12..7c1d6eb 100755
    107 --- a/mDNSPosix/mDNSPosix.c
    108 +++ b/mDNSPosix/mDNSPosix.c
    109 @@ -138,7 +138,7 @@ mDNSlocal void SockAddrTomDNSAddr(const struct sockaddr *const sa, mDNSAddr *ipA
    110  
    111  // mDNS core calls this routine when it needs to send a packet.
    112  mDNSexport mStatus mDNSPlatformSendUDP(const mDNS *const m, const void *const msg, const mDNSu8 *const end,
    113 -                                       mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst, 
    114 +                                       mDNSInterfaceID InterfaceID, UDPSocket *src, const mDNSAddr *dst,
    115                                         mDNSIPPort dstPort, mDNSBool useBackgroundTrafficClass)
    116  {
    117      int err = 0;
    118 @@ -583,9 +583,17 @@ mDNSlocal void FreePosixNetworkInterface(PosixNetworkInterface *intf)
    119  {
    120      assert(intf != NULL);
    121      if (intf->intfName != NULL) free((void *)intf->intfName);
    122 -    if (intf->multicastSocket4 != -1) assert(close(intf->multicastSocket4) == 0);
    123 +    if (intf->multicastSocket4 != -1)
    124 +      {
    125 +        int rv = close(intf->multicastSocket4);
    126 +        assert(rv == 0);
    127 +      }
    128  #if HAVE_IPV6
    129 -    if (intf->multicastSocket6 != -1) assert(close(intf->multicastSocket6) == 0);
    130 +    if (intf->multicastSocket6 != -1)
    131 +      {
    132 +        int rv = close(intf->multicastSocket6);
    133 +        assert(rv == 0);
    134 +      }
    135  #endif
    136  
    137      // Move interface to the RecentInterfaces list for a minute
    138 @@ -724,6 +732,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
    139              if (err < 0) { err = errno; perror("setsockopt - IP_MULTICAST_TTL"); }
    140          }
    141  
    142 +#ifdef __linux__
    143 +#ifdef SO_BINDTODEVICE
    144 +        if (err == 0 && interfaceIndex)
    145 +        {
    146 +            char ifname[IFNAMSIZ];
    147 +            if (if_indextoname(interfaceIndex, ifname))
    148 +              {
    149 +                err = setsockopt(*sktPtr, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
    150 +                if (err < 0)
    151 +                  {
    152 +                    err = errno;
    153 +                    perror("setsockopt - SO_BINDTODEVICE");
    154 +                  }
    155 +              }
    156 +            else
    157 +              {
    158 +                err = errno;
    159 +                perror("if_indextoname");
    160 +              }
    161 +        }
    162 +#endif /* SO_BINDTODEVICE */
    163 +#endif /* __linux__ */
    164 +
    165          // And start listening for packets
    166          if (err == 0)
    167          {
    168 @@ -805,6 +836,29 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
    169              if (err < 0) { err = errno; perror("setsockopt - IPV6_MULTICAST_HOPS"); }
    170          }
    171  
    172 +#ifdef __linux__
    173 +#ifdef SO_BINDTODEVICE
    174 +        if (err == 0 && interfaceIndex)
    175 +        {
    176 +            char ifname[IFNAMSIZ];
    177 +            if (if_indextoname(interfaceIndex, ifname))
    178 +              {
    179 +                err = setsockopt(*sktPtr, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname));
    180 +                if (err < 0)
    181 +                  {
    182 +                    err = errno;
    183 +                    perror("setsockopt - SO_BINDTODEVICE");
    184 +                  }
    185 +              }
    186 +            else
    187 +              {
    188 +                err = errno;
    189 +                perror("if_indextoname");
    190 +              }
    191 +        }
    192 +#endif /* SO_BINDTODEVICE */
    193 +#endif /* __linux__ */
    194 +
    195          // And start listening for packets
    196          if (err == 0)
    197          {
    198 @@ -836,7 +890,12 @@ mDNSlocal int SetupSocket(struct sockaddr *intfAddr, mDNSIPPort port, int interf
    199      }
    200  
    201      // Clean up
    202 -    if (err != 0 && *sktPtr != -1) { assert(close(*sktPtr) == 0); *sktPtr = -1; }
    203 +    if (err != 0 && *sktPtr != -1)
    204 +      {
    205 +        int rv = close(*sktPtr);
    206 +        assert(rv == 0);
    207 +        *sktPtr = -1;
    208 +      }
    209      assert((err == 0) == (*sktPtr != -1));
    210      return err;
    211  }
    212 @@ -938,19 +997,14 @@ mDNSlocal int SetupInterfaceList(mDNS *const m)
    213      int err            = 0;
    214      struct ifi_info *intfList      = get_ifi_info(AF_INET, mDNStrue);
    215      struct ifi_info *firstLoopback = NULL;
    216 +    struct ifi_info **p = &intfList;
    217  
    218      assert(m != NULL);
    219      debugf("SetupInterfaceList");
    220  
    221 -    if (intfList == NULL) err = ENOENT;
    222 -
    223  #if HAVE_IPV6
    224 -    if (err == 0)       /* Link the IPv6 list to the end of the IPv4 list */
    225 -    {
    226 -        struct ifi_info **p = &intfList;
    227 -        while (*p) p = &(*p)->ifi_next;
    228 -        *p = get_ifi_info(AF_INET6, mDNStrue);
    229 -    }
    230 +    while (*p) p = &(*p)->ifi_next;
    231 +    *p = get_ifi_info(AF_INET6, mDNStrue);
    232  #endif
    233  
    234      if (err == 0)
    235 @@ -1026,7 +1080,7 @@ mDNSlocal mStatus OpenIfNotifySocket(int *pFD)
    236      /* Subscribe the socket to Link & IP addr notifications. */
    237      mDNSPlatformMemZero(&snl, sizeof snl);
    238      snl.nl_family = AF_NETLINK;
    239 -    snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR;
    240 +    snl.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;
    241      ret = bind(sock, (struct sockaddr *) &snl, sizeof snl);
    242      if (0 == ret)
    243          *pFD = sock;
    244 @@ -1104,11 +1158,18 @@ mDNSlocal mDNSu32       ProcessRoutingNotification(int sd)
    245          PrintNetLinkMsg(pNLMsg);
    246  #endif
    247  
    248 +        // this result isn't used anywhere as a number, just as
    249 +        // non-zero - however, I have seen devices with more than 32
    250 +        // interfaces at some point..
    251 +        // (on Linux, every tunnel increases index for example)
    252 +
    253          // Process the NetLink message
    254          if (pNLMsg->nlmsg_type == RTM_GETLINK || pNLMsg->nlmsg_type == RTM_NEWLINK)
    255 -            result |= 1 << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index;
    256 +          result |= 1;
    257 +        // << ((struct ifinfomsg*) NLMSG_DATA(pNLMsg))->ifi_index;
    258          else if (pNLMsg->nlmsg_type == RTM_DELADDR || pNLMsg->nlmsg_type == RTM_NEWADDR)
    259 -            result |= 1 << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index;
    260 +          result |= 1;
    261 +        // << ((struct ifaddrmsg*) NLMSG_DATA(pNLMsg))->ifa_index;
    262  
    263          // Advance pNLMsg to the next message in the buffer
    264          if ((pNLMsg->nlmsg_flags & NLM_F_MULTI) != 0 && pNLMsg->nlmsg_type != NLMSG_DONE)
    265 @@ -1279,8 +1340,12 @@ mDNSexport mStatus mDNSPlatformInit(mDNS *const m)
    266      if (err == mStatus_NoError) err = SetupSocket(&sa, zeroIPPort, 0, &m->p->unicastSocket6);
    267  #endif
    268  
    269 +    // In Linux case, we can't set up sockets with different owner -
    270 +    // it blows up SO_REUSEPORT. So we do this step bit later.
    271 +#ifndef __linux__
    272      // Tell mDNS core about the network interfaces on this machine.
    273      if (err == mStatus_NoError) err = SetupInterfaceList(m);
    274 +#endif /* !__linux__ */
    275  
    276      // Tell mDNS core about DNS Servers
    277      mDNS_Lock(m);
    278 @@ -1313,9 +1378,17 @@ mDNSexport void mDNSPlatformClose(mDNS *const m)
    279  {
    280      assert(m != NULL);
    281      ClearInterfaceList(m);
    282 -    if (m->p->unicastSocket4 != -1) assert(close(m->p->unicastSocket4) == 0);
    283 +    if (m->p->unicastSocket4 != -1)
    284 +      {
    285 +        int rv = close(m->p->unicastSocket4);
    286 +        assert(rv == 0);
    287 +      }
    288  #if HAVE_IPV6
    289 -    if (m->p->unicastSocket6 != -1) assert(close(m->p->unicastSocket6) == 0);
    290 +    if (m->p->unicastSocket6 != -1)
    291 +      {
    292 +        int rv = close(m->p->unicastSocket6);
    293 +        assert(rv == 0);
    294 +      }
    295  #endif
    296  }
    297  
    298 @@ -1571,14 +1644,14 @@ mDNSexport mStatus    mDNSPlatformClearSPSMACAddr(void)
    299  mDNSexport mDNSu16 mDNSPlatformGetUDPPort(UDPSocket *sock)
    300  {
    301      (void) sock; // unused
    302 - 
    303 +
    304      return (mDNSu16)-1;
    305  }
    306  
    307  mDNSexport mDNSBool mDNSPlatformInterfaceIsD2D(mDNSInterfaceID InterfaceID)
    308  {
    309      (void) InterfaceID; // unused
    310 -    
    311 +
    312      return mDNSfalse;
    313  }
    314  
    315 diff --git a/mDNSPosix/mDNSUNP.c b/mDNSPosix/mDNSUNP.c
    316 index b392fc7..f551ad5 100755
    317 --- a/mDNSPosix/mDNSUNP.c
    318 +++ b/mDNSPosix/mDNSUNP.c
    319 @@ -63,6 +63,7 @@
    320  #if defined(AF_INET6) && HAVE_IPV6 && HAVE_LINUX
    321  #include <netdb.h>
    322  #include <arpa/inet.h>
    323 +#include <linux/if_addr.h>
    324  
    325  /* Converts a prefix length to IPv6 network mask */
    326  void plen_to_mask(int plen, char *addr) {
    327 @@ -86,7 +87,7 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
    328      FILE *fp;
    329      char addr[8][5];
    330      int flags, myflags, index, plen, scope;
    331 -    char ifname[9], lastname[IFNAMSIZ];
    332 +    char ifname[IFNAMSIZ], lastname[IFNAMSIZ];
    333      char addr6[32+7+1]; /* don't forget the seven ':' */
    334      struct addrinfo hints, *res0;
    335      struct sockaddr_in6 *sin6;
    336 @@ -94,7 +95,8 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
    337      int err;
    338      int sockfd = -1;
    339      struct ifreq ifr;
    340 -
    341 +    char mask[64] = "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %";
    342 +    sprintf(mask+strlen(mask), "%ds\n", IFNAMSIZ);
    343      res0=NULL;
    344      ifihead = NULL;
    345      ifipnext = &ifihead;
    346 @@ -106,11 +108,12 @@ struct ifi_info *get_ifi_info_linuxv6(int family, int doaliases)
    347              goto gotError;
    348          }
    349          while (fscanf(fp,
    350 -                      "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %8s\n",
    351 +                      mask,
    352                        addr[0],addr[1],addr[2],addr[3],
    353                        addr[4],addr[5],addr[6],addr[7],
    354                        &index, &plen, &scope, &flags, ifname) != EOF) {
    355  
    356 +            if (flags & IFA_F_DEPRECATED) continue;
    357              myflags = 0;
    358              if (strncmp(lastname, ifname, IFNAMSIZ) == 0) {
    359                  if (doaliases == 0)
    360 @@ -204,8 +207,11 @@ gotError:
    361          res0=NULL;
    362      }
    363  done:
    364 +    if (fp)
    365 +      fclose(fp);
    366      if (sockfd != -1) {
    367 -        assert(close(sockfd) == 0);
    368 +      int rv = close(sockfd);
    369 +      assert(rv == 0);
    370      }
    371      return(ifihead);    /* pointer to first structure in linked list */
    372  }
    373 diff --git a/mDNSShared/dnsextd_parser.y b/mDNSShared/dnsextd_parser.y
    374 index 18c5990..d4b63ce 100644
    375 --- a/mDNSShared/dnsextd_parser.y
    376 +++ b/mDNSShared/dnsextd_parser.y
    377 @@ -15,6 +15,8 @@
    378   * limitations under the License.
    379   */
    380  
    381 +%parse-param { void *context }
    382 +
    383  %{
    384  #include <stdio.h>
    385  #include <stdlib.h>
    386 @@ -23,7 +25,7 @@
    387  #include "DebugServices.h"
    388  #include "dnsextd.h"
    389  
    390 -void yyerror( const char* error );
    391 +void yyerror( void *context, const char* error );
    392  int  yylex(void);
    393  
    394  
    395 @@ -378,7 +380,7 @@ int yywrap(void);
    396  
    397  extern int yylineno;
    398  
    399 -void yyerror( const char *str )
    400 +void yyerror( void *context, const char *str )
    401  {
    402          fprintf( stderr,"%s:%d: error: %s\n", g_filename, yylineno, str );
    403  }