aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux
diff options
context:
space:
mode:
authorOldřich Jedlička <oldium.pro@gmail.com>2019-09-25 21:45:42 +0200
committerPetr Štetiar <ynezz@true.cz>2019-10-09 21:05:08 +0200
commit5e9aae9ef069912edea21f807be5512249971127 (patch)
tree35f7fcf80f858e6f84442a976163760db07d4e8d /target/linux
parent4abf456b4a828b2aa4094f8fd505741541bbacb7 (diff)
downloadupstream-5e9aae9ef069912edea21f807be5512249971127.tar.gz
upstream-5e9aae9ef069912edea21f807be5512249971127.tar.bz2
upstream-5e9aae9ef069912edea21f807be5512249971127.zip
kernel: Fix off-by-one error in FIT mtd partition search.
This fixes off-by-one error introduced in commit dc76900021b8 ("kernel: Correctly search for the FIT image in mtd partition.") Function `mtd_read` starts reading at `offset` and needs `hdr_len` number of bytes to be available. Suppose the easiest case when `offset` is `0` and `hdr_len` equals to `mtd->size` - the `for` loop will not be entered even when enough bytes are available to be read. Same happens for any non-zero `offset`, when `hdr_len` is just enough bytes to be read until `mtd->size` is reached. Imagine that for example `mtd->size=5`, `offset=4` and `hdr_len=1`. Then `offset+hdr_len=5` and the check has to be `offset+hdr_len <= mtd->size`, i.e. `5 <= 5`. The check for `offset + hdr_len` value needs to be inclusive, therefore use `<=`. Fixes: dc76900021b8 ("kernel: Correctly search for the FIT image in mtd partition.") Signed-off-by: Oldřich Jedlička <oldium.pro@gmail.com> [adjusted commit ref, fixes tag] Signed-off-by: Petr Štetiar <ynezz@true.cz> (cherry picked from commit e0ce80d42ace6feba509da16795ab0eb81cf5bf4)
Diffstat (limited to 'target/linux')
-rw-r--r--target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
index d206fecd5b1..67ee33d085c 100644
--- a/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
+++ b/target/linux/generic/files/drivers/mtd/mtdsplit/mtdsplit_fit.c
@@ -60,7 +60,7 @@ mtdsplit_fit_parse(struct mtd_info *mtd,
hdr_len = sizeof(struct fdt_header);
/* Parse the MTD device & search for the FIT image location */
- for(offset = 0; offset + hdr_len < mtd->size; offset += mtd->erasesize) {
+ for(offset = 0; offset + hdr_len <= mtd->size; offset += mtd->erasesize) {
ret = mtd_read(mtd, offset, hdr_len, &retlen, (void*) &hdr);
if (ret) {
pr_err("read error in \"%s\" at offset 0x%llx\n",
: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#ifndef __XEN_PERFC_H__
#define __XEN_PERFC_H__

#ifdef PERF_COUNTERS

#include <xen/lib.h>
#include <xen/smp.h>
#include <xen/percpu.h>

/*
 * NOTE: new counters must be defined in perfc_defn.h
 * 
 * Counter declarations:
 * PERFCOUNTER (counter, string)              define a new performance counter
 * PERFCOUNTER_ARRAY (counter, string, size)  define an array of counters
 * 
 * Unlike counters, status variables do not reset:
 * PERFSTATUS (counter, string)               define a new performance stauts
 * PERFSTATUS_ARRAY (counter, string, size)   define an array of status vars
 * 
 * unsigned long perfc_value  (counter)        get value of a counter  
 * unsigned long perfc_valuea (counter, index) get value of an array counter
 * unsigned long perfc_set  (counter, val)     set value of a counter  
 * unsigned long perfc_seta (counter, index, val) set value of an array counter
 * void perfc_incr  (counter)                  increment a counter          
 * void perfc_decr  (counter)                  decrement a status
 * void perfc_incra (counter, index)           increment an array counter   
 * void perfc_add   (counter, value)           add a value to a counter     
 * void perfc_adda  (counter, index, value)    add a value to array counter 
 * void perfc_print (counter)                  print out the counter
 */

#define PERFCOUNTER( name, descr ) \
  PERFC_##name,
#define PERFCOUNTER_ARRAY( name, descr, size ) \
  PERFC_##name,                                \
  PERFC_LAST_##name = PERFC_ ## name + (size) - sizeof(char[2 * !!(size) - 1]),

#define PERFSTATUS       PERFCOUNTER
#define PERFSTATUS_ARRAY PERFCOUNTER_ARRAY

enum perfcounter {
#include <xen/perfc_defn.h>
	NUM_PERFCOUNTERS
};

#undef PERFCOUNTER
#undef PERFCOUNTER_ARRAY
#undef PERFSTATUS
#undef PERFSTATUS_ARRAY

typedef unsigned perfc_t;
#define PRIperfc ""

DECLARE_PER_CPU(perfc_t[NUM_PERFCOUNTERS], perfcounters);

#define perfc_value(x)    this_cpu(perfcounters)[PERFC_ ## x]
#define perfc_valuea(x,y)                                               \
    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
	 this_cpu(perfcounters)[PERFC_ ## x + (y)] : 0 )
#define perfc_set(x,v)    (this_cpu(perfcounters)[PERFC_ ## x] = (v))
#define perfc_seta(x,y,v)                                               \
    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
	 this_cpu(perfcounters)[PERFC_ ## x + (y)] = (v) : (v) )
#define perfc_incr(x)     (++this_cpu(perfcounters)[PERFC_ ## x])
#define perfc_decr(x)     (--this_cpu(perfcounters)[PERFC_ ## x])
#define perfc_incra(x,y)                                                \
    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
	 ++this_cpu(perfcounters)[PERFC_ ## x + (y)] : 0 )
#define perfc_add(x,v)    (this_cpu(perfcounters)[PERFC_ ## x] += (v))
#define perfc_adda(x,y,v)                                               \
    ( (y) <= PERFC_LAST_ ## x - PERFC_ ## x ?                           \
	 this_cpu(perfcounters)[PERFC_ ## x + (y)] = (v) : (v) )

/*
 * Histogram: special treatment for 0 and 1 count. After that equally spaced 
 * with last bucket taking the rest.
 */
#ifdef PERF_ARRAYS
#define perfc_incr_histo(x,v)                                           \
    do {                                                                \
        if ( (v) == 0 )                                                 \
            perfc_incra(x, 0);                                          \
        else if ( (v) == 1 )                                            \
            perfc_incra(x, 1);                                          \
        else if ( (((v) - 2) / PERFC_ ## x ## _BUCKET_SIZE) <           \
                  (PERFC_LAST_ ## x - PERFC_ ## x - 2) )                \
            perfc_incra(x, (((v) - 2) / PERFC_ ## x ## _BUCKET_SIZE) + 2); \
        else                                                            \
            perfc_incra(x, PERFC_LAST_ ## x - PERFC_ ## x);             \
    } while ( 0 )
#else
#define perfc_incr_histo(x,v) ((void)0)
#endif

struct xen_sysctl_perfc_op;
int perfc_control(struct xen_sysctl_perfc_op *);
    
#else /* PERF_COUNTERS */

#define perfc_value(x)    (0)
#define perfc_valuea(x,y) (0)
#define perfc_set(x,v)    ((void)0)
#define perfc_seta(x,y,v) ((void)0)
#define perfc_incr(x)     ((void)0)
#define perfc_decr(x)     ((void)0)
#define perfc_incra(x,y)  ((void)0)
#define perfc_decra(x,y)  ((void)0)
#define perfc_add(x,y)    ((void)0)
#define perfc_adda(x,y,z) ((void)0)
#define perfc_incr_histo(x,y,z) ((void)0)

#endif /* PERF_COUNTERS */

#endif /* __XEN_PERFC_H__ */