/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to plugins.d/mandos-client.c

  • Committer: Teddy Hogeborn
  • Date: 2016-03-17 20:40:55 UTC
  • Revision ID: teddy@recompile.se-20160317204055-bhsh5xsidq7w5cxu
Client: Fix plymouth agent; broken since 1.7.2.

Fix an very old memory bug in the plymouth agent (which has been
present since its apperance in version 1.2), but which was only
recently detected at run time due to the new -fsanitize=address
compile- time flag, which has been used since version 1.7.2.  This
detection of a memory access violation causes the program to abort,
making the Plymouth graphical boot system unable to accept interactive
input of passwords when using the Mandos client.

* plugins.d/plymouth.c (exec_and_wait): Fix memory allocation bug when
  allocating new_argv.  Also tolerate a zero-length argv.

Show diffs side-by-side

added added

removed removed

Lines of Context:
817
817
 
818
818
/* Set effective uid to 0, return errno */
819
819
__attribute__((warn_unused_result))
820
 
error_t raise_privileges(void){
821
 
  error_t old_errno = errno;
822
 
  error_t ret_errno = 0;
 
820
int raise_privileges(void){
 
821
  int old_errno = errno;
 
822
  int ret = 0;
823
823
  if(seteuid(0) == -1){
824
 
    ret_errno = errno;
 
824
    ret = errno;
825
825
  }
826
826
  errno = old_errno;
827
 
  return ret_errno;
 
827
  return ret;
828
828
}
829
829
 
830
830
/* Set effective and real user ID to 0.  Return errno. */
831
831
__attribute__((warn_unused_result))
832
 
error_t raise_privileges_permanently(void){
833
 
  error_t old_errno = errno;
834
 
  error_t ret_errno = raise_privileges();
835
 
  if(ret_errno != 0){
 
832
int raise_privileges_permanently(void){
 
833
  int old_errno = errno;
 
834
  int ret = raise_privileges();
 
835
  if(ret != 0){
836
836
    errno = old_errno;
837
 
    return ret_errno;
 
837
    return ret;
838
838
  }
839
839
  if(setuid(0) == -1){
840
 
    ret_errno = errno;
 
840
    ret = errno;
841
841
  }
842
842
  errno = old_errno;
843
 
  return ret_errno;
 
843
  return ret;
844
844
}
845
845
 
846
846
/* Set effective user ID to unprivileged saved user ID */
847
847
__attribute__((warn_unused_result))
848
 
error_t lower_privileges(void){
849
 
  error_t old_errno = errno;
850
 
  error_t ret_errno = 0;
 
848
int lower_privileges(void){
 
849
  int old_errno = errno;
 
850
  int ret = 0;
851
851
  if(seteuid(uid) == -1){
852
 
    ret_errno = errno;
 
852
    ret = errno;
853
853
  }
854
854
  errno = old_errno;
855
 
  return ret_errno;
 
855
  return ret;
856
856
}
857
857
 
858
858
/* Lower privileges permanently */
859
859
__attribute__((warn_unused_result))
860
 
error_t lower_privileges_permanently(void){
861
 
  error_t old_errno = errno;
862
 
  error_t ret_errno = 0;
 
860
int lower_privileges_permanently(void){
 
861
  int old_errno = errno;
 
862
  int ret = 0;
863
863
  if(setuid(uid) == -1){
864
 
    ret_errno = errno;
 
864
    ret = errno;
865
865
  }
866
866
  errno = old_errno;
867
 
  return ret_errno;
 
867
  return ret;
868
868
}
869
869
 
870
870
/* Helper function to add_local_route() and delete_local_route() */
1623
1623
__attribute__((nonnull, warn_unused_result))
1624
1624
bool get_flags(const char *ifname, struct ifreq *ifr){
1625
1625
  int ret;
1626
 
  error_t ret_errno;
 
1626
  int old_errno;
1627
1627
  
1628
1628
  int s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
1629
1629
  if(s < 0){
1630
 
    ret_errno = errno;
 
1630
    old_errno = errno;
1631
1631
    perror_plus("socket");
1632
 
    errno = ret_errno;
 
1632
    errno = old_errno;
1633
1633
    return false;
1634
1634
  }
1635
1635
  strncpy(ifr->ifr_name, ifname, IF_NAMESIZE);
1637
1637
  ret = ioctl(s, SIOCGIFFLAGS, ifr);
1638
1638
  if(ret == -1){
1639
1639
    if(debug){
1640
 
      ret_errno = errno;
 
1640
      old_errno = errno;
1641
1641
      perror_plus("ioctl SIOCGIFFLAGS");
1642
 
      errno = ret_errno;
 
1642
      errno = old_errno;
1643
1643
    }
1644
1644
    return false;
1645
1645
  }
2071
2071
}
2072
2072
 
2073
2073
__attribute__((nonnull, warn_unused_result))
2074
 
error_t bring_up_interface(const char *const interface,
2075
 
                           const float delay){
2076
 
  error_t old_errno = errno;
 
2074
int bring_up_interface(const char *const interface,
 
2075
                       const float delay){
 
2076
  int old_errno = errno;
2077
2077
  int ret;
2078
2078
  struct ifreq network;
2079
2079
  unsigned int if_index = if_nametoindex(interface);
2089
2089
  }
2090
2090
  
2091
2091
  if(not interface_is_up(interface)){
2092
 
    error_t ret_errno = 0, ioctl_errno = 0;
 
2092
    int ret_errno = 0;
 
2093
    int ioctl_errno = 0;
2093
2094
    if(not get_flags(interface, &network)){
2094
2095
      ret_errno = errno;
2095
2096
      fprintf_plus(stderr, "Failed to get flags for interface "
2198
2199
}
2199
2200
 
2200
2201
__attribute__((nonnull, warn_unused_result))
2201
 
error_t take_down_interface(const char *const interface){
2202
 
  error_t old_errno = errno;
 
2202
int take_down_interface(const char *const interface){
 
2203
  int old_errno = errno;
2203
2204
  struct ifreq network;
2204
2205
  unsigned int if_index = if_nametoindex(interface);
2205
2206
  if(if_index == 0){
2208
2209
    return ENXIO;
2209
2210
  }
2210
2211
  if(interface_is_up(interface)){
2211
 
    error_t ret_errno = 0, ioctl_errno = 0;
 
2212
    int ret_errno = 0;
 
2213
    int ioctl_errno = 0;
2212
2214
    if(not get_flags(interface, &network) and debug){
2213
2215
      ret_errno = errno;
2214
2216
      fprintf_plus(stderr, "Failed to get flags for interface "
2464
2466
                         .args_doc = "",
2465
2467
                         .doc = "Mandos client -- Get and decrypt"
2466
2468
                         " passwords from a Mandos server" };
2467
 
    ret = argp_parse(&argp, argc, argv,
2468
 
                     ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
2469
 
    switch(ret){
 
2469
    ret_errno = argp_parse(&argp, argc, argv,
 
2470
                           ARGP_IN_ORDER | ARGP_NO_HELP, 0, NULL);
 
2471
    switch(ret_errno){
2470
2472
    case 0:
2471
2473
      break;
2472
2474
    case ENOMEM:
2473
2475
    default:
2474
 
      errno = ret;
 
2476
      errno = ret_errno;
2475
2477
      perror_plus("argp_parse");
2476
2478
      exitcode = EX_OSERR;
2477
2479
      goto end;
2486
2488
       <http://bugs.debian.org/633582> */
2487
2489
    
2488
2490
    /* Re-raise privileges */
2489
 
    ret_errno = raise_privileges();
2490
 
    if(ret_errno != 0){
2491
 
      errno = ret_errno;
 
2491
    ret = raise_privileges();
 
2492
    if(ret != 0){
 
2493
      errno = ret;
2492
2494
      perror_plus("Failed to raise privileges");
2493
2495
    } else {
2494
2496
      struct stat st;
2558
2560
      }
2559
2561
      
2560
2562
      /* Lower privileges */
2561
 
      ret_errno = lower_privileges();
2562
 
      if(ret_errno != 0){
2563
 
        errno = ret_errno;
 
2563
      ret = lower_privileges();
 
2564
      if(ret != 0){
 
2565
        errno = ret;
2564
2566
        perror_plus("Failed to lower privileges");
2565
2567
      }
2566
2568
    }
2894
2896
    
2895
2897
    /* Allocate a new server */
2896
2898
    mc.server = avahi_server_new(avahi_simple_poll_get(simple_poll),
2897
 
                                 &config, NULL, NULL, &ret_errno);
 
2899
                                 &config, NULL, NULL, &ret);
2898
2900
    
2899
2901
    /* Free the Avahi configuration data */
2900
2902
    avahi_server_config_free(&config);
2903
2905
  /* Check if creating the Avahi server object succeeded */
2904
2906
  if(mc.server == NULL){
2905
2907
    fprintf_plus(stderr, "Failed to create Avahi server: %s\n",
2906
 
                 avahi_strerror(ret_errno));
 
2908
                 avahi_strerror(ret));
2907
2909
    exitcode = EX_UNAVAILABLE;
2908
2910
    goto end;
2909
2911
  }
2989
2991
  
2990
2992
  /* Re-raise privileges */
2991
2993
  {
2992
 
    ret_errno = raise_privileges();
2993
 
    if(ret_errno != 0){
2994
 
      errno = ret_errno;
 
2994
    ret = raise_privileges();
 
2995
    if(ret != 0){
 
2996
      errno = ret;
2995
2997
      perror_plus("Failed to raise privileges");
2996
2998
    } else {
2997
2999
      
3005
3007
        while((interface=argz_next(interfaces_to_take_down,
3006
3008
                                   interfaces_to_take_down_size,
3007
3009
                                   interface))){
3008
 
          ret_errno = take_down_interface(interface);
3009
 
          if(ret_errno != 0){
3010
 
            errno = ret_errno;
 
3010
          ret = take_down_interface(interface);
 
3011
          if(ret != 0){
 
3012
            errno = ret;
3011
3013
            perror_plus("Failed to take down interface");
3012
3014
          }
3013
3015
        }
3018
3020
      }
3019
3021
    }
3020
3022
    
3021
 
    ret_errno = lower_privileges_permanently();
3022
 
    if(ret_errno != 0){
3023
 
      errno = ret_errno;
 
3023
    ret = lower_privileges_permanently();
 
3024
    if(ret != 0){
 
3025
      errno = ret;
3024
3026
      perror_plus("Failed to lower privileges permanently");
3025
3027
    }
3026
3028
  }