/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:
9
9
 * "browse_callback", and parts of "main".
10
10
 * 
11
11
 * Everything else is
12
 
 * Copyright © 2008-2018 Teddy Hogeborn
13
 
 * Copyright © 2008-2018 Björn Påhlsson
14
 
 * 
15
 
 * This file is part of Mandos.
16
 
 * 
17
 
 * Mandos is free software: you can redistribute it and/or modify it
18
 
 * under the terms of the GNU General Public License as published by
19
 
 * the Free Software Foundation, either version 3 of the License, or
20
 
 * (at your option) any later version.
21
 
 * 
22
 
 * Mandos is distributed in the hope that it will be useful, but
 
12
 * Copyright © 2008-2016 Teddy Hogeborn
 
13
 * Copyright © 2008-2016 Björn Påhlsson
 
14
 * 
 
15
 * This program is free software: you can redistribute it and/or
 
16
 * modify it under the terms of the GNU General Public License as
 
17
 * published by the Free Software Foundation, either version 3 of the
 
18
 * License, or (at your option) any later version.
 
19
 * 
 
20
 * This program is distributed in the hope that it will be useful, but
23
21
 * WITHOUT ANY WARRANTY; without even the implied warranty of
24
22
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25
23
 * General Public License for more details.
26
24
 * 
27
25
 * You should have received a copy of the GNU General Public License
28
 
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
 
26
 * along with this program.  If not, see
 
27
 * <http://www.gnu.org/licenses/>.
29
28
 * 
30
29
 * Contact the authors at <mandos@recompile.se>.
31
30
 */
48
47
                                   strtof(), abort() */
49
48
#include <stdbool.h>            /* bool, false, true */
50
49
#include <string.h>             /* strcmp(), strlen(), strerror(),
51
 
                                   asprintf(), strncpy(), strsignal()
52
 
                                */
 
50
                                   asprintf(), strncpy() */
53
51
#include <sys/ioctl.h>          /* ioctl */
54
52
#include <sys/types.h>          /* socket(), inet_pton(), sockaddr,
55
53
                                   sockaddr_in6, PF_INET6,
627
625
                     safer_gnutls_strerror(ret));
628
626
        dhparamsfilename = NULL;
629
627
      }
630
 
      free(params.data);
631
628
    } while(false);
632
629
  }
633
630
  if(dhparamsfilename == NULL){
1080
1077
    bool match = false;
1081
1078
    {
1082
1079
      char *interface = NULL;
1083
 
      while((interface = argz_next(mc->interfaces,
1084
 
                                   mc->interfaces_size,
1085
 
                                   interface))){
 
1080
      while((interface=argz_next(mc->interfaces, mc->interfaces_size,
 
1081
                                 interface))){
1086
1082
        if(if_nametoindex(interface) == (unsigned int)if_index){
1087
1083
          match = true;
1088
1084
          break;
1241
1237
           with an explicit route added with the server's address.
1242
1238
           
1243
1239
           Avahi bug reference:
1244
 
           https://lists.freedesktop.org/archives/avahi/2010-February/001833.html
 
1240
           http://lists.freedesktop.org/archives/avahi/2010-February/001833.html
1245
1241
           https://bugs.debian.org/587961
1246
1242
        */
1247
1243
        if(debug){
1427
1423
                                               &decrypted_buffer, mc);
1428
1424
    if(decrypted_buffer_size >= 0){
1429
1425
      
1430
 
      clearerr(stdout);
1431
1426
      written = 0;
1432
1427
      while(written < (size_t) decrypted_buffer_size){
1433
1428
        if(quit_now){
1449
1444
        }
1450
1445
        written += (size_t)ret;
1451
1446
      }
1452
 
      ret = fflush(stdout);
1453
 
      if(ret != 0){
1454
 
        int e = errno;
1455
 
        if(debug){
1456
 
          fprintf_plus(stderr, "Error writing encrypted data: %s\n",
1457
 
                       strerror(errno));
1458
 
        }
1459
 
        errno = e;
1460
 
        goto mandos_end;
1461
 
      }
1462
1447
      retval = 0;
1463
1448
    }
1464
1449
  }
1495
1480
  return retval;
1496
1481
}
1497
1482
 
 
1483
__attribute__((nonnull))
1498
1484
static void resolve_callback(AvahiSServiceResolver *r,
1499
1485
                             AvahiIfIndex interface,
1500
1486
                             AvahiProtocol proto,
1923
1909
      return;
1924
1910
    }
1925
1911
  }
1926
 
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
1927
 
  if(devnull == -1){
1928
 
    perror_plus("open(\"/dev/null\", O_RDONLY)");
1929
 
    return;
1930
 
  }
1931
1912
  int numhooks = scandirat(hookdir_fd, ".", &direntries,
1932
1913
                           runnable_hook, alphasort);
1933
1914
  if(numhooks == -1){
1934
1915
    perror_plus("scandir");
1935
 
    close(devnull);
1936
1916
    return;
1937
1917
  }
1938
1918
  struct dirent *direntry;
1939
1919
  int ret;
 
1920
  int devnull = (int)TEMP_FAILURE_RETRY(open("/dev/null", O_RDONLY));
 
1921
  if(devnull == -1){
 
1922
    perror_plus("open(\"/dev/null\", O_RDONLY)");
 
1923
    return;
 
1924
  }
1940
1925
  for(int i = 0; i < numhooks; i++){
1941
1926
    direntry = direntries[i];
1942
1927
    if(debug){
2198
2183
  
2199
2184
  /* Sleep checking until interface is running.
2200
2185
     Check every 0.25s, up to total time of delay */
2201
 
  for(int i = 0; i < delay * 4; i++){
 
2186
  for(int i=0; i < delay * 4; i++){
2202
2187
    if(interface_is_running(interface)){
2203
2188
      break;
2204
2189
    }
2500
2485
  
2501
2486
  {
2502
2487
    /* Work around Debian bug #633582:
2503
 
       <https://bugs.debian.org/633582> */
 
2488
       <http://bugs.debian.org/633582> */
2504
2489
    
2505
2490
    /* Re-raise privileges */
2506
2491
    ret = raise_privileges();
2961
2946
 end:
2962
2947
  
2963
2948
  if(debug){
2964
 
    if(signal_received){
2965
 
      fprintf_plus(stderr, "%s exiting due to signal %d: %s\n",
2966
 
                   argv[0], signal_received,
2967
 
                   strsignal(signal_received));
2968
 
    } else {
2969
 
      fprintf_plus(stderr, "%s exiting\n", argv[0]);
2970
 
    }
 
2949
    fprintf_plus(stderr, "%s exiting\n", argv[0]);
2971
2950
  }
2972
2951
  
2973
2952
  /* Cleanup things */
3025
3004
      /* Take down the network interfaces which were brought up */
3026
3005
      {
3027
3006
        char *interface = NULL;
3028
 
        while((interface = argz_next(interfaces_to_take_down,
3029
 
                                     interfaces_to_take_down_size,
3030
 
                                     interface))){
 
3007
        while((interface=argz_next(interfaces_to_take_down,
 
3008
                                   interfaces_to_take_down_size,
 
3009
                                   interface))){
3031
3010
          ret = take_down_interface(interface);
3032
3011
          if(ret != 0){
3033
3012
            errno = ret;
3062
3041
                                                | O_PATH));
3063
3042
    if(dir_fd == -1){
3064
3043
      perror_plus("open");
3065
 
      return;
3066
3044
    }
3067
3045
    int numentries = scandirat(dir_fd, ".", &direntries,
3068
3046
                               notdotentries, alphasort);
3085
3063
            clean_dir_at(dir_fd, direntries[i]->d_name, level+1);
3086
3064
            dret = 0;
3087
3065
          }
3088
 
          if((dret == -1) and (errno != ENOENT)){
 
3066
          if(dret == -1){
3089
3067
            fprintf_plus(stderr, "unlink(\"%s/%s\"): %s\n", dirname,
3090
3068
                         direntries[i]->d_name, strerror(errno));
3091
3069
          }
3095
3073
      
3096
3074
      /* need to clean even if 0 because man page doesn't specify */
3097
3075
      free(direntries);
 
3076
      if(numentries == -1){
 
3077
        perror_plus("scandirat");
 
3078
      }
3098
3079
      dret = unlinkat(base, dirname, AT_REMOVEDIR);
3099
3080
      if(dret == -1 and errno != ENOENT){
3100
3081
        perror_plus("rmdir");