/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/plymouth.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:
2
2
/*
3
3
 * Plymouth - Read a password from Plymouth and output it
4
4
 * 
5
 
 * Copyright © 2010-2018 Teddy Hogeborn
6
 
 * Copyright © 2010-2018 Björn Påhlsson
7
 
 * 
8
 
 * This file is part of Mandos.
9
 
 * 
10
 
 * Mandos is free software: you can redistribute it and/or modify it
11
 
 * under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 * 
15
 
 * Mandos is distributed in the hope that it will be useful, but
 
5
 * Copyright © 2010-2016 Teddy Hogeborn
 
6
 * Copyright © 2010-2016 Björn Påhlsson
 
7
 * 
 
8
 * This program is free software: you can redistribute it and/or
 
9
 * modify it under the terms of the GNU General Public License as
 
10
 * published by the Free Software Foundation, either version 3 of the
 
11
 * License, or (at your option) any later version.
 
12
 * 
 
13
 * This program is distributed in the hope that it will be useful, but
16
14
 * WITHOUT ANY WARRANTY; without even the implied warranty of
17
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
16
 * General Public License for more details.
19
17
 * 
20
18
 * You should have received a copy of the GNU General Public License
21
 
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
 
19
 * along with this program.  If not, see
 
20
 * <http://www.gnu.org/licenses/>.
22
21
 * 
23
22
 * Contact the authors at <mandos@recompile.se>.
24
23
 */
57
56
sig_atomic_t interrupted_by_signal = 0;
58
57
 
59
58
/* Used by Ubuntu 11.04 (Natty Narwahl) */
60
 
const char plymouth_old_old_pid[] = "/dev/.initramfs/plymouth.pid";
 
59
const char plymouth_old_pid[] = "/dev/.initramfs/plymouth.pid";
61
60
/* Used by Ubuntu 11.10 (Oneiric Ocelot) */
62
 
const char plymouth_old_pid[] = "/run/initramfs/plymouth.pid";
63
 
/* Used by Debian 9 (stretch) */
64
 
const char plymouth_pid[] = "/run/plymouth/pid";
 
61
const char plymouth_pid[] = "/run/initramfs/plymouth.pid";
65
62
 
66
63
const char plymouth_path[] = "/bin/plymouth";
67
64
const char plymouthd_path[] = "/sbin/plymouthd";
184
181
    }
185
182
    char **tmp;
186
183
    int i = 0;
187
 
    for (; argv[i] != NULL; i++){
 
184
    for (; argv[i]!=NULL; i++){
188
185
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 2));
189
186
      if(tmp == NULL){
190
187
        error_plus(0, errno, "realloc");
284
281
  }
285
282
  /* Try the old pid file location */
286
283
  if(proc_id == 0){
287
 
    pidfile = fopen(plymouth_old_pid, "r");
288
 
    if(pidfile != NULL){
289
 
      ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
290
 
      if(ret != 1){
291
 
        proc_id = 0;
292
 
      }
293
 
      fclose(pidfile);
294
 
    }
295
 
  }
296
 
  /* Try the old old pid file location */
297
 
  if(proc_id == 0){
298
 
    pidfile = fopen(plymouth_old_old_pid, "r");
 
284
    pidfile = fopen(plymouth_pid, "r");
299
285
    if(pidfile != NULL){
300
286
      ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
301
287
      if(ret != 1){
312
298
      error_plus(0, errno, "scandir");
313
299
    }
314
300
    if(ret > 0){
315
 
      for(int i = ret-1; i >= 0; i--){
316
 
        if(proc_id == 0){
317
 
          ret = sscanf(direntries[i]->d_name, "%" SCNuMAX, &proc_id);
318
 
          if(ret < 0){
319
 
            error_plus(0, errno, "sscanf");
320
 
          }
321
 
        }
322
 
        free(direntries[i]);
 
301
      ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &proc_id);
 
302
      if(ret < 0){
 
303
        error_plus(0, errno, "sscanf");
323
304
      }
324
305
    }
325
306
    /* scandir might preallocate for this variable (man page unclear).
335
316
  return 0;
336
317
}
337
318
 
338
 
char **getargv(pid_t pid){
 
319
const char * const * getargv(pid_t pid){
339
320
  int cl_fd;
340
321
  char *cmdline_filename;
341
322
  ssize_t sret;
402
383
    return NULL;
403
384
  }
404
385
  argz_extract(cmdline, cmdline_len, argv); /* Create argv */
405
 
  return argv;
 
386
  return (const char * const *)argv;
406
387
}
407
388
 
408
389
int main(__attribute__((unused))int argc,
483
464
  }
484
465
  kill_and_wait(plymouth_command_pid);
485
466
  
486
 
  char **plymouthd_argv = NULL;
 
467
  const char * const *plymouthd_argv;
487
468
  pid_t pid = get_pid();
488
469
  if(pid == 0){
489
470
    error_plus(0, 0, "plymouthd pid not found");
 
471
    plymouthd_argv = plymouthd_default_argv;
490
472
  } else {
491
473
    plymouthd_argv = getargv(pid);
492
474
  }
495
477
                       { plymouth_path, "quit", NULL },
496
478
                       false, false);
497
479
  if(not bret){
498
 
    if(plymouthd_argv != NULL){
499
 
      free(*plymouthd_argv);
500
 
      free(plymouthd_argv);
501
 
    }
502
480
    exit(EXIT_FAILURE);
503
481
  }
504
 
  bret = exec_and_wait(NULL, plymouthd_path,
505
 
                       (plymouthd_argv != NULL)
506
 
                       ? (const char * const *)plymouthd_argv
507
 
                       : plymouthd_default_argv,
 
482
  bret = exec_and_wait(NULL, plymouthd_path, plymouthd_argv,
508
483
                       false, true);
509
 
  if(plymouthd_argv != NULL){
510
 
    free(*plymouthd_argv);
511
 
    free(plymouthd_argv);
512
 
  }
513
484
  if(not bret){
514
485
    exit(EXIT_FAILURE);
515
486
  }