Merge branch 'maint'
authorAndre Noll <maan@tuebingen.mpg.de>
Fri, 1 Apr 2016 23:33:47 +0000 (01:33 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Fri, 1 Apr 2016 23:33:47 +0000 (01:33 +0200)
A couple of overflow bugs and a aslignment issue, all detected by ubsan. Plus
two unrelated old bugs.

* maint:
  client: Fix lsatt completer.
  playlist: Do not update score if no playlist is open.
  Avoid member access within misaligned address for ancillary data buffer.
  mood.c: Avoid overflow in update_quadratic_deviation().
  mood.c: Avoid integer underflow.
  mood.c: Avoid integer overflow.

afs.c
client.c
mood.c
net.c
playlist.c
vss.c

diff --git a/afs.c b/afs.c
index d5afc6d..ee1c6b5 100644 (file)
--- a/afs.c
+++ b/afs.c
@@ -424,7 +424,7 @@ static int pass_afd(int fd, char *buf, size_t size)
 {
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
-       char control[255];
+       char control[255] __a_aligned(8);
        int ret;
        struct iovec iov;
 
index 34cc918..31cfff0 100644 (file)
--- a/client.c
+++ b/client.c
@@ -323,11 +323,7 @@ static void lsatt_completer(struct i9e_completion_info *ci,
                struct i9e_completion_result *cr)
 {
        char *opts[] = {"-i", "-l", "-r", NULL};
-
-       if (ci->word[0] == '-')
-               i9e_complete_option(opts, ci, cr);
-       else
-               complete_attributes(ci->word, &cr->matches);
+       i9e_complete_option(opts, ci, cr);
 }
 
 static void mvatt_completer(struct i9e_completion_info *ci,
diff --git a/mood.c b/mood.c
index d29c62c..daa8196 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -446,7 +446,7 @@ static int64_t normalized_value(int64_t x, int64_t n, int64_t sum, int64_t qd)
 {
        if (!n || !qd)
                return 0;
-       return 100 * (n * x - sum) / (int64_t)int_sqrt(n * qd);
+       return 100 * (n * x - sum) / (int64_t)int_sqrt(n) / (int64_t)int_sqrt(qd);
 }
 
 static long compute_score(struct afs_info *afsi, long mood_score)
@@ -460,7 +460,7 @@ static long compute_score(struct afs_info *afsi, long mood_score)
 
 static int add_afs_statistics(const struct osl_row *row)
 {
-       uint64_t n, x, s;
+       uint64_t n, x, s, q;
        struct afs_info afsi;
        int ret;
 
@@ -470,14 +470,18 @@ static int add_afs_statistics(const struct osl_row *row)
        n = statistics.num;
        x = afsi.last_played;
        s = statistics.last_played_sum;
-       if (n > 0)
-               statistics.last_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.last_played_qd += q * q * n / (n + 1);
+       }
        statistics.last_played_sum += x;
 
        x = afsi.num_played;
        s = statistics.num_played_sum;
-       if (n > 0)
-               statistics.num_played_qd += (x - s / n) * (x - s / n) * n / (n + 1);
+       if (n > 0) {
+               q = (x > s / n)? x - s / n : s / n - x;
+               statistics.num_played_qd += q * q * n / (n + 1);
+       }
        statistics.num_played_sum += x;
        statistics.num++;
        return 1;
@@ -604,7 +608,8 @@ static int add_if_admissible(struct osl_row *aft_row, void *data)
  * the last number a_n was replaced by b) may be computed in O(1) time in terms
  * of n, q, a_n, b, and S as
  *
- *     q' = q + d * s - (2 * S + d) * d / n,
+ *     q' = q + d * s - (2 * S + d) * d / n
+ *        = q + d * (s - 2 * S / n - d /n),
  *
  * where d = b - a_n, and s = b + a_n.
  *
@@ -621,7 +626,7 @@ _static_inline_ int64_t update_quadratic_deviation(int64_t n, int64_t old_qd,
 {
        int64_t delta = new_val - old_val;
        int64_t sigma = new_val + old_val;
-       return old_qd + delta * sigma - (2 * old_sum + delta) * delta / n;
+       return old_qd + delta * (sigma - 2 * old_sum / n - delta / n);
 }
 
 static int update_afs_statistics(struct afs_info *old_afsi, struct afs_info *new_afsi)
diff --git a/net.c b/net.c
index 463033b..42418e5 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1018,7 +1018,7 @@ static void dispose_fds(int *fds, unsigned num)
  */
 int recv_cred_buffer(int fd, char *buf, size_t size)
 {
-       char control[255];
+       char control[255] __a_aligned(8);
        struct msghdr msg;
        struct cmsghdr *cmsg;
        struct iovec iov;
index 9616ed0..0139203 100644 (file)
@@ -191,8 +191,6 @@ static int handle_audio_file_event(enum afs_events event, void *data)
        char *new_path;
        const struct osl_row *row = data;
 
-       if (!current_playlist.name)
-               return 1;
        if (event == AUDIO_FILE_RENAME) {
                ret = row_belongs_to_score_table(row, NULL);
                if (ret < 0)
@@ -237,7 +235,9 @@ int playlists_event_handler(enum afs_events event,
        int ret;
        struct afsi_change_event_data *aced = data;
 
-       switch(event) {
+       if (!current_playlist.name)
+               return 1;
+       switch (event) {
        case AFSI_CHANGE:
                return playlist_update_audio_file(aced->aft_row);
        case AUDIO_FILE_RENAME:
diff --git a/vss.c b/vss.c
index cbc05d1..51db768 100644 (file)
--- a/vss.c
+++ b/vss.c
@@ -905,7 +905,7 @@ static void vss_pre_select(struct sched *s, void *context)
 
 static int recv_afs_msg(int afs_socket, int *fd, uint32_t *code, uint32_t *data)
 {
-       char control[255], buf[8];
+       char control[255] __a_aligned(8), buf[8];
        struct msghdr msg = {.msg_iov = NULL};
        struct cmsghdr *cmsg;
        struct iovec iov;