1
0
mirror of https://github.com/systemd/systemd synced 2025-10-07 12:44:45 +02:00

Compare commits

..

8 Commits

Author SHA1 Message Date
Lennart Poettering
e2e40e9a9e sd-device: fix error code returned by sd_device_get_sysattr_value() for non-existing attributes
lstat() returns the error in errno, not as return value. Let's propagate
this correctly.

This broke the bolt test suite, as @gicmo discovered.

Follow-up for acfc2a1d15560084e077ffb3be472cd117e9020a.
2021-04-09 19:41:43 +01:00
gaoyi
5b1375035b gpt-auto-generator: don't generate systemd-cryptsetup@.service when --Dlibcryptsetup=false 2021-04-09 17:18:09 +02:00
Zbigniew Jędrzejewski-Szmek
22344fcfb9
Merge pull request #19243 from bluca/lgtm
Fix various issues reported by LGTM
2021-04-09 13:12:41 +02:00
Luca Boccassi
a0cc411724 in-addr-util: suppress LGTM warning about htobe32
We are not calling it directly, it's coming from a standard library
macro, so just suppress it.
2021-04-08 13:08:38 +01:00
Luca Boccassi
82cdb75b8d errno-util: suppress LGTM warning about strerror 2021-04-08 13:08:38 +01:00
Luca Boccassi
a9a49d2fea scsi_id: modernize and use extract_many_words instead of strsep
Also use standard error loggin/return pattern.

Only cursory tested, by checking that with a simple config file
the array is the same before/after. Not tested with actual scsi
rules and devices, due to missing hardware.
2021-04-08 13:07:31 +01:00
Luca Boccassi
b01339f74f test-extract-word: add a couple more corner cases 2021-04-08 13:07:31 +01:00
Luca Boccassi
dfc5c4f26d timedated: use format_timestamp instead of ctime
Some static analyzers (lgtm) warn against using non-re-entrant functions,
even though at the moment this code is not multi-threaded, just switch to
format_timestamp.
2021-04-08 13:07:31 +01:00
7 changed files with 83 additions and 132 deletions

View File

@ -33,7 +33,7 @@ static inline int negative_errno(void) {
static inline const char *strerror_safe(int error) { static inline const char *strerror_safe(int error) {
/* 'safe' here does NOT mean thread safety. */ /* 'safe' here does NOT mean thread safety. */
return strerror(abs(error)); return strerror(abs(error)); /* lgtm [cpp/potentially-dangerous-function] */
} }
static inline int errno_or_else(int fallback) { static inline int errno_or_else(int fallback) {

View File

@ -51,7 +51,7 @@ bool in4_addr_is_link_local(const struct in_addr *a) {
bool in6_addr_is_link_local(const struct in6_addr *a) { bool in6_addr_is_link_local(const struct in6_addr *a) {
assert(a); assert(a);
return IN6_IS_ADDR_LINKLOCAL(a); return IN6_IS_ADDR_LINKLOCAL(a); /* lgtm [cpp/potentially-dangerous-function] */
} }
int in_addr_is_link_local(int family, const union in_addr_union *u) { int in_addr_is_link_local(int family, const union in_addr_union *u) {
@ -116,7 +116,7 @@ int in_addr_is_localhost(int family, const union in_addr_union *u) {
return in4_addr_is_localhost(&u->in); return in4_addr_is_localhost(&u->in);
if (family == AF_INET6) if (family == AF_INET6)
return IN6_IS_ADDR_LOOPBACK(&u->in6); return IN6_IS_ADDR_LOOPBACK(&u->in6); /* lgtm [cpp/potentially-dangerous-function] */
return -EAFNOSUPPORT; return -EAFNOSUPPORT;
} }

View File

@ -105,6 +105,7 @@ static int open_parent_block_device(dev_t devnum, int *ret_fd) {
} }
static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) { static int add_cryptsetup(const char *id, const char *what, bool rw, bool require, char **device) {
#if HAVE_LIBCRYPTSETUP
_cleanup_free_ char *e = NULL, *n = NULL, *d = NULL; _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
int r; int r;
@ -182,6 +183,9 @@ static int add_cryptsetup(const char *id, const char *what, bool rw, bool requir
} }
return 0; return 0;
#else
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Partition is encrypted, but the project was compiled without libcryptsetup support");
#endif
} }
static int add_mount( static int add_mount(

View File

@ -1893,10 +1893,11 @@ _public_ int sd_device_get_sysattr_value(sd_device *device, const char *sysattr,
return r; return r;
path = prefix_roota(syspath, sysattr); path = prefix_roota(syspath, sysattr);
r = lstat(path, &statbuf); if (lstat(path, &statbuf) < 0) {
if (r < 0) {
int k; int k;
r = -errno;
/* remember that we could not access the sysattr */ /* remember that we could not access the sysattr */
k = device_cache_sysattr_value(device, sysattr, NULL); k = device_cache_sysattr_value(device, sysattr, NULL);
if (k < 0) if (k < 0)

View File

@ -428,6 +428,20 @@ static void test_extract_first_word(void) {
assert_se(streq(t, "c")); assert_se(streq(t, "c"));
free(t); free(t);
assert_se(p == NULL); assert_se(p == NULL);
p = original = "foobar=\"waldo\"maldo, baldo";
assert_se(extract_first_word(&p, &t, "=\", ", 0) > 0);
assert_se(streq(t, "foobar"));
free(t);
assert_se(extract_first_word(&p, &t, "=\", ", 0) > 0);
assert_se(streq(t, "waldo"));
free(t);
assert_se(extract_first_word(&p, &t, "=\", ", 0) > 0);
assert_se(streq(t, "maldo"));
free(t);
assert_se(extract_first_word(&p, &t, "=\", ", 0) > 0);
assert_se(streq(t, "baldo"));
free(t);
} }
static void test_extract_first_word_and_warn(void) { static void test_extract_first_word_and_warn(void) {

View File

@ -801,6 +801,7 @@ static int method_set_local_rtc(sd_bus_message *m, void *userdata, sd_bus_error
static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *error) { static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *error) {
sd_bus *bus = sd_bus_message_get_bus(m); sd_bus *bus = sd_bus_message_get_bus(m);
char buf[FORMAT_TIMESTAMP_MAX];
int relative, interactive, r; int relative, interactive, r;
Context *c = userdata; Context *c = userdata;
int64_t utc; int64_t utc;
@ -886,7 +887,7 @@ static int method_set_time(sd_bus_message *m, void *userdata, sd_bus_error *erro
log_struct(LOG_INFO, log_struct(LOG_INFO,
"MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR, "MESSAGE_ID=" SD_MESSAGE_TIME_CHANGE_STR,
"REALTIME="USEC_FMT, timespec_load(&ts), "REALTIME="USEC_FMT, timespec_load(&ts),
LOG_MESSAGE("Changed local time to %s", ctime(&ts.tv_sec))); LOG_MESSAGE("Changed local time to %s", strnull(format_timestamp(buf, sizeof(buf), timespec_load(&ts)))));
return sd_bus_reply_method_return(m, NULL); return sd_bus_reply_method_return(m, NULL);
} }

View File

@ -19,9 +19,11 @@
#include "alloc-util.h" #include "alloc-util.h"
#include "build.h" #include "build.h"
#include "device-nodes.h" #include "device-nodes.h"
#include "extract-word.h"
#include "fd-util.h" #include "fd-util.h"
#include "scsi_id.h" #include "scsi_id.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h"
#include "strxcpyx.h" #include "strxcpyx.h"
#include "udev-util.h" #include "udev-util.h"
@ -90,50 +92,6 @@ static void set_type(const char *from, char *to, size_t len) {
strscpy(to, len, type); strscpy(to, len, type);
} }
/*
* get_value:
*
* buf points to an '=' followed by a quoted string ("foo") or a string ending
* with a space or ','.
*
* Return a pointer to the NUL terminated string, returns NULL if no
* matches.
*/
static char *get_value(char **buffer) {
static const char *quote_string = "\"\n";
static const char *comma_string = ",\n";
char *val;
const char *end;
if (**buffer == '"') {
/*
* skip leading quote, terminate when quote seen
*/
(*buffer)++;
end = quote_string;
} else
end = comma_string;
val = strsep(buffer, end);
if (val && end == quote_string)
/*
* skip trailing quote
*/
(*buffer)++;
while (isspace(**buffer))
(*buffer)++;
return val;
}
static int argc_count(char *opts) {
int i = 0;
while (*opts != '\0')
if (*opts++ == ' ')
i++;
return i;
}
/* /*
* get_file_options: * get_file_options:
* *
@ -145,14 +103,12 @@ static int argc_count(char *opts) {
*/ */
static int get_file_options(const char *vendor, const char *model, static int get_file_options(const char *vendor, const char *model,
int *argc, char ***newargv) { int *argc, char ***newargv) {
_cleanup_free_ char *buffer = NULL; _cleanup_free_ char *buffer = NULL,
*vendor_in = NULL, *model_in = NULL, *options_in = NULL; /* read in from file */
_cleanup_strv_free_ char **options_argv = NULL;
_cleanup_fclose_ FILE *f; _cleanup_fclose_ FILE *f;
char *buf; const char *buf;
char *str1; int lineno, r;
char *vendor_in, *model_in, *options_in; /* read in from file */
int lineno;
int c;
int retval = 0;
f = fopen(config_file, "re"); f = fopen(config_file, "re");
if (!f) { if (!f) {
@ -176,16 +132,16 @@ static int get_file_options(const char *vendor, const char *model,
*newargv = NULL; *newargv = NULL;
lineno = 0; lineno = 0;
for (;;) { for (;;) {
_cleanup_free_ char *key = NULL, *value = NULL;
vendor_in = model_in = options_in = NULL; vendor_in = model_in = options_in = NULL;
buf = fgets(buffer, MAX_BUFFER_LEN, f); buf = fgets(buffer, MAX_BUFFER_LEN, f);
if (!buf) if (!buf)
break; break;
lineno++; lineno++;
if (buf[strlen(buffer) - 1] != '\n') { if (buf[strlen(buffer) - 1] != '\n')
log_error("Config file line %d too long", lineno); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Config file line %d too long", lineno);
break;
}
while (isspace(*buf)) while (isspace(*buf))
buf++; buf++;
@ -198,44 +154,36 @@ static int get_file_options(const char *vendor, const char *model,
if (*buf == '#') if (*buf == '#')
continue; continue;
str1 = strsep(&buf, "="); r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL);
if (str1 && strcaseeq(str1, "VENDOR")) { if (r < 2)
str1 = get_value(&buf); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer);
if (!str1) {
retval = log_oom();
break;
}
vendor_in = str1;
str1 = strsep(&buf, "="); if (strcaseeq(key, "VENDOR")) {
if (str1 && strcaseeq(str1, "MODEL")) { vendor_in = TAKE_PTR(value);
str1 = get_value(&buf);
if (!str1) { key = mfree(key);
retval = log_oom(); r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL);
break; if (r < 2)
} return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer);
model_in = str1;
str1 = strsep(&buf, "="); if (strcaseeq(key, "MODEL")) {
model_in = TAKE_PTR(value);
key = mfree(key);
r = extract_many_words(&buf, "=\",\n", 0, &key, &value, NULL);
if (r < 2)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer);
} }
} }
if (str1 && strcaseeq(str1, "OPTIONS")) { if (strcaseeq(key, "OPTIONS"))
str1 = get_value(&buf); options_in = TAKE_PTR(value);
if (!str1) {
retval = log_oom();
break;
}
options_in = str1;
}
/* /*
* Only allow: [vendor=foo[,model=bar]]options=stuff * Only allow: [vendor=foo[,model=bar]]options=stuff
*/ */
if (!options_in || (!vendor_in && model_in)) { if (!options_in || (!vendor_in && model_in))
log_error("Error parsing config file line %d '%s'", lineno, buffer); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Error parsing config file line %d '%s'", lineno, buffer);
retval = -1;
break;
}
if (!vendor) { if (!vendor) {
if (!vendor_in) if (!vendor_in)
break; break;
@ -251,39 +199,30 @@ static int get_file_options(const char *vendor, const char *model,
*/ */
break; break;
} }
vendor_in = mfree(vendor_in);
model_in = mfree(model_in);
options_in = mfree(options_in);
} }
if (retval == 0) { if (vendor_in == NULL && model_in == NULL && options_in == NULL)
if (vendor_in != NULL || model_in != NULL || return 1; /* No matches */
options_in != NULL) {
/* /*
* Something matched. Allocate newargv, and store * Something matched. Allocate newargv, and store
* values found in options_in. * values found in options_in.
*/ */
strcpy(buffer, options_in); options_argv = strv_split(options_in, " \t");
c = argc_count(buffer) + 2; if (!options_argv)
*newargv = calloc(c, sizeof(**newargv)); return log_oom();
if (!*newargv) r = strv_prepend(&options_argv, ""); /* getopt skips over argv[0] */
retval = log_oom(); if (r < 0)
else { return r;
*argc = c; *newargv = TAKE_PTR(options_argv);
c = 0; *argc = strv_length(*newargv);
/*
* argv[0] at 0 is skipped by getopt, but return 0;
* store the buffer address there for
* later freeing
*/
(*newargv)[c] = buffer;
for (c = 1; c < *argc; c++)
(*newargv)[c] = strsep(&buffer, " \t");
buffer = NULL;
}
} else {
/* No matches */
retval = 1;
}
}
return retval;
} }
static void help(void) { static void help(void) {
@ -391,9 +330,9 @@ static int set_options(int argc, char **argv,
} }
static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) { static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) {
_cleanup_strv_free_ char **newargv = NULL;
int retval; int retval;
int newargc; int newargc;
char **newargv = NULL;
int option; int option;
*good_bad = all_good; *good_bad = all_good;
@ -436,10 +375,6 @@ static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *
} }
} }
if (newargv) {
free(newargv[0]);
free(newargv);
}
return retval; return retval;
} }
@ -543,10 +478,10 @@ out:
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
_cleanup_strv_free_ char **newargv = NULL;
int retval = 0; int retval = 0;
char maj_min_dev[MAX_PATH_LEN]; char maj_min_dev[MAX_PATH_LEN];
int newargc; int newargc;
char **newargv = NULL;
log_set_target(LOG_TARGET_AUTO); log_set_target(LOG_TARGET_AUTO);
udev_parse_config(); udev_parse_config();
@ -585,10 +520,6 @@ int main(int argc, char **argv) {
retval = scsi_id(maj_min_dev); retval = scsi_id(maj_min_dev);
exit: exit:
if (newargv) {
free(newargv[0]);
free(newargv);
}
log_close(); log_close();
return retval; return retval;
} }