/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: 2019-07-14 22:39:15 UTC
  • Revision ID: teddy@recompile.se-20190714223915-aqjkms3t3taa6tye
Only use sanitizing options when debugging

The C compiler's sanitizing options introduce code in the output
binary which is fragile and not very security conscious.  It has
become clear that sanitizing is only really meant for use while
debugging.

As a side effect, this makes compilation faster, as the Makefile, for
production builds, no longer runs the compiler repeatedly to find all
its currently supported sanitizing options.

* Makefile (DEBUG): Add "$(SANITIZE)".
  (SANITIZE): Comment out.
  (CFLAGS): Remove "$(SANITIZE)".
  (plugins.d/mandos-client): Revert back to use plain $(LINK.c), since
                             we no longer need to remove the leak
                             sanitizer by overriding CFLAGS.

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-2011 Teddy Hogeborn
6
 
 * Copyright © 2010-2011 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
 
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
14
16
 * WITHOUT ANY WARRANTY; without even the implied warranty of
15
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
18
 * General Public License for more details.
17
19
 * 
18
20
 * You should have received a copy of the GNU General Public License
19
 
 * along with this program.  If not, see
20
 
 * <http://www.gnu.org/licenses/>.
 
21
 * along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
21
22
 * 
22
23
 * Contact the authors at <mandos@recompile.se>.
23
24
 */
56
57
sig_atomic_t interrupted_by_signal = 0;
57
58
 
58
59
/* Used by Ubuntu 11.04 (Natty Narwahl) */
59
 
const char plymouth_old_pid[] = "/dev/.initramfs/plymouth.pid";
 
60
const char plymouth_old_old_pid[] = "/dev/.initramfs/plymouth.pid";
60
61
/* Used by Ubuntu 11.10 (Oneiric Ocelot) */
61
 
const char plymouth_pid[] = "/run/initramfs/plymouth.pid";
 
62
const char plymouth_old_pid[] = "/run/initramfs/plymouth.pid";
 
63
/* Used by Debian 9 (stretch) */
 
64
const char plymouth_pid[] = "/run/plymouth/pid";
62
65
 
63
66
const char plymouth_path[] = "/bin/plymouth";
64
67
const char plymouthd_path[] = "/sbin/plymouthd";
84
87
  
85
88
  va_start(ap, formatstring);
86
89
  ret = vasprintf(&text, formatstring, ap);
87
 
  if (ret == -1){
 
90
  if(ret == -1){
88
91
    fprintf(stderr, "Mandos plugin %s: ",
89
92
            program_invocation_short_name);
90
93
    vfprintf(stderr, formatstring, ap);
156
159
 
157
160
__attribute__((nonnull (2, 3)))
158
161
bool exec_and_wait(pid_t *pid_return, const char *path,
159
 
                   const char **argv, bool interruptable,
 
162
                   const char * const *argv, bool interruptable,
160
163
                   bool daemonize){
161
164
  int status;
162
165
  int ret;
174
177
      }
175
178
    }
176
179
    
177
 
    char **new_argv = NULL;
 
180
    char **new_argv = malloc(sizeof(const char *));
 
181
    if(new_argv == NULL){
 
182
      error_plus(0, errno, "malloc");
 
183
      _exit(EX_OSERR);
 
184
    }
178
185
    char **tmp;
179
186
    int i = 0;
180
 
    for (; argv[i]!=NULL; i++){
181
 
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 1));
182
 
      if (tmp == NULL){
 
187
    for (; argv[i] != NULL; i++){
 
188
      tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 2));
 
189
      if(tmp == NULL){
183
190
        error_plus(0, errno, "realloc");
184
191
        free(new_argv);
185
192
        _exit(EX_OSERR);
218
225
int is_plymouth(const struct dirent *proc_entry){
219
226
  int ret;
220
227
  {
221
 
    uintmax_t maxvalue;
 
228
    uintmax_t proc_id;
222
229
    char *tmp;
223
230
    errno = 0;
224
 
    maxvalue = strtoumax(proc_entry->d_name, &tmp, 10);
 
231
    proc_id = strtoumax(proc_entry->d_name, &tmp, 10);
225
232
 
226
233
    if(errno != 0 or *tmp != '\0'
227
 
       or maxvalue != (uintmax_t)((pid_t)maxvalue)){
 
234
       or proc_id != (uintmax_t)((pid_t)proc_id)){
228
235
      return 0;
229
236
    }
230
237
  }
265
272
 
266
273
pid_t get_pid(void){
267
274
  int ret;
268
 
  uintmax_t maxvalue = 0;
 
275
  uintmax_t proc_id = 0;
269
276
  FILE *pidfile = fopen(plymouth_pid, "r");
270
277
  /* Try the new pid file location */
271
278
  if(pidfile != NULL){
272
 
    ret = fscanf(pidfile, "%" SCNuMAX, &maxvalue);
 
279
    ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
273
280
    if(ret != 1){
274
 
      maxvalue = 0;
 
281
      proc_id = 0;
275
282
    }
276
283
    fclose(pidfile);
277
284
  }
278
285
  /* Try the old pid file location */
279
 
  if(maxvalue == 0){
280
 
    pidfile = fopen(plymouth_pid, "r");
281
 
    if(pidfile != NULL){
282
 
      ret = fscanf(pidfile, "%" SCNuMAX, &maxvalue);
283
 
      if(ret != 1){
284
 
        maxvalue = 0;
 
286
  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");
 
299
    if(pidfile != NULL){
 
300
      ret = fscanf(pidfile, "%" SCNuMAX, &proc_id);
 
301
      if(ret != 1){
 
302
        proc_id = 0;
285
303
      }
286
304
      fclose(pidfile);
287
305
    }
288
306
  }
289
307
  /* Look for a plymouth process */
290
 
  if(maxvalue == 0){
 
308
  if(proc_id == 0){
291
309
    struct dirent **direntries = NULL;
292
310
    ret = scandir("/proc", &direntries, is_plymouth, alphasort);
293
 
    if (ret == -1){
 
311
    if(ret == -1){
294
312
      error_plus(0, errno, "scandir");
295
313
    }
296
 
    if (ret > 0){
297
 
      ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &maxvalue);
298
 
      if (ret < 0){
299
 
        error_plus(0, errno, "sscanf");
 
314
    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]);
300
323
      }
301
324
    }
302
325
    /* scandir might preallocate for this variable (man page unclear).
304
327
    free(direntries);
305
328
  }
306
329
  pid_t pid;
307
 
  pid = (pid_t)maxvalue;
308
 
  if((uintmax_t)pid == maxvalue){
 
330
  pid = (pid_t)proc_id;
 
331
  if((uintmax_t)pid == proc_id){
309
332
    return pid;
310
333
  }
311
334
  
312
335
  return 0;
313
336
}
314
337
 
315
 
const char **getargv(pid_t pid){
 
338
char **getargv(pid_t pid){
316
339
  int cl_fd;
317
340
  char *cmdline_filename;
318
341
  ssize_t sret;
379
402
    return NULL;
380
403
  }
381
404
  argz_extract(cmdline, cmdline_len, argv); /* Create argv */
382
 
  return (const char **)argv;
 
405
  return argv;
383
406
}
384
407
 
385
408
int main(__attribute__((unused))int argc,
460
483
  }
461
484
  kill_and_wait(plymouth_command_pid);
462
485
  
463
 
  const char **plymouthd_argv;
 
486
  char **plymouthd_argv = NULL;
464
487
  pid_t pid = get_pid();
465
488
  if(pid == 0){
466
489
    error_plus(0, 0, "plymouthd pid not found");
467
 
    plymouthd_argv = plymouthd_default_argv;
468
490
  } else {
469
491
    plymouthd_argv = getargv(pid);
470
492
  }
473
495
                       { plymouth_path, "quit", NULL },
474
496
                       false, false);
475
497
  if(not bret){
 
498
    if(plymouthd_argv != NULL){
 
499
      free(*plymouthd_argv);
 
500
      free(plymouthd_argv);
 
501
    }
476
502
    exit(EXIT_FAILURE);
477
503
  }
478
 
  bret = exec_and_wait(NULL, plymouthd_path, plymouthd_argv,
 
504
  bret = exec_and_wait(NULL, plymouthd_path,
 
505
                       (plymouthd_argv != NULL)
 
506
                       ? (const char * const *)plymouthd_argv
 
507
                       : plymouthd_default_argv,
479
508
                       false, true);
 
509
  if(plymouthd_argv != NULL){
 
510
    free(*plymouthd_argv);
 
511
    free(plymouthd_argv);
 
512
  }
480
513
  if(not bret){
481
514
    exit(EXIT_FAILURE);
482
515
  }