~ubuntu-branches/ubuntu/trusty/grub2/trusty-updates

« back to all changes in this revision

Viewing changes to grub-core/partmap/msdos.c

  • Committer: Package Import Robot
  • Author(s): Colin Watson
  • Date: 2012-09-13 18:02:04 UTC
  • mfrom: (1.17.15 upstream)
  • mto: (17.6.27 experimental)
  • mto: This revision was merged to the branch mainline in revision 145.
  • Revision ID: package-import@ubuntu.com-20120913180204-mojnmocbimlom4im
Tags: upstream-2.00
ImportĀ upstreamĀ versionĀ 2.00

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <grub/mm.h>
24
24
#include <grub/misc.h>
25
25
#include <grub/dl.h>
 
26
#include <grub/i18n.h>
26
27
 
27
28
GRUB_MOD_LICENSE ("GPLv3+");
28
29
 
29
30
static struct grub_partition_map grub_msdos_partition_map;
30
31
 
31
32
 
 
33
#ifdef GRUB_UTIL
 
34
#include <grub/emu/misc.h>
 
35
 
 
36
struct embed_signature
 
37
{
 
38
  const char *name;
 
39
  const char *signature;
 
40
  int signature_len;
 
41
  enum { TYPE_SOFTWARE, TYPE_RAID } type;
 
42
};
 
43
 
 
44
const char message_warn[][200] = {
 
45
  /* TRANSLATORS: MBR gap and boot track is the same thing and is the space
 
46
     between MBR and first partitition. If your language translates well only
 
47
     "boot track", you can just use it everywhere. Next two messages are about
 
48
     RAID controllers/software bugs which GRUB has to live with. Please spread
 
49
     the message that these are bugs in other software and not merely
 
50
     suboptimal behaviour.  */
 
51
  [TYPE_RAID] = N_("Sector %llu is already in use by raid controller `%s';"
 
52
                   " avoiding it.  "
 
53
                   "Please ask the manufacturer not to store data in MBR gap"),
 
54
  [TYPE_SOFTWARE] = N_("Sector %llu is already in use by the program `%s';"
 
55
                       " avoiding it.  "
 
56
                       "This software may cause boot or other problems in "
 
57
                       "future.  Please ask its authors not to store data "
 
58
                       "in the boot track") 
 
59
};
 
60
 
 
61
 
 
62
/* Signatures of other software that may be using sectors in the embedding
 
63
   area.  */
 
64
struct embed_signature embed_signatures[] =
 
65
  {
 
66
    {
 
67
      .name = "ZISD",
 
68
      .signature = "ZISD",
 
69
      .signature_len = 4,
 
70
      .type = TYPE_SOFTWARE
 
71
    },
 
72
    {
 
73
      .name = "FlexNet",
 
74
      .signature = "\xd4\x41\xa0\xf5\x03\x00\x03\x00",
 
75
      .signature_len = 8,
 
76
      .type = TYPE_SOFTWARE
 
77
    },
 
78
    {
 
79
      .name = "FlexNet",
 
80
      .signature = "\xd8\x41\xa0\xf5\x02\x00\x02\x00",
 
81
      .signature_len = 8,
 
82
      .type = TYPE_SOFTWARE
 
83
    },
 
84
    {
 
85
      /* from Ryan Perkins */
 
86
      .name = "HP Backup and Recovery Manager (?)",
 
87
      .signature = "\x70\x8a\x5d\x46\x35\xc5\x1b\x93"
 
88
                   "\xae\x3d\x86\xfd\xb1\x55\x3e\xe0",
 
89
      .signature_len = 16,
 
90
      .type = TYPE_SOFTWARE
 
91
    },
 
92
    {
 
93
      .name = "HighPoint RAID controller",
 
94
      .signature = "ycgl",
 
95
      .signature_len = 4,
 
96
      .type = TYPE_RAID
 
97
    }
 
98
  };
 
99
#endif
 
100
 
32
101
grub_err_t
33
102
grub_partition_msdos_iterate (grub_disk_t disk,
34
103
                              int (*hook) (grub_disk_t disk,
67
136
      if (grub_disk_read (disk, p.offset, 0, sizeof (mbr), &mbr))
68
137
        goto finish;
69
138
 
 
139
      /* If this is a GPT partition, this MBR is just a dummy.  */
 
140
      if (p.offset == 0)
 
141
        for (i = 0; i < 4; i++)
 
142
          if (mbr.entries[i].type == GRUB_PC_PARTITION_TYPE_GPT_DISK)
 
143
            return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
 
144
 
70
145
      /* This is our loop-detection algorithm. It works the following way:
71
146
         It saves last position which was a power of two. Then it compares the
72
147
         saved value with a current one. This way it's guaranteed that the loop
92
167
        {
93
168
          e = mbr.entries + p.index;
94
169
 
95
 
          p.start = p.offset + grub_le_to_cpu32 (e->start) - delta;
96
 
          p.len = grub_le_to_cpu32 (e->length);
 
170
          p.start = p.offset
 
171
            + (grub_le_to_cpu32 (e->start)
 
172
               << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)) - delta;
 
173
          p.len = grub_le_to_cpu32 (e->length)
 
174
            << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS);
97
175
          p.msdostype = e->type;
98
176
 
99
177
          grub_dprintf ("partition",
102
180
                        (unsigned long long) p.start,
103
181
                        (unsigned long long) p.len);
104
182
 
105
 
          /* If this is a GPT partition, this MBR is just a dummy.  */
106
 
          if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && p.index == 0)
107
 
            return grub_error (GRUB_ERR_BAD_PART_TABLE, "dummy mbr");
108
 
 
109
183
          /* If this partition is a normal one, call the hook.  */
110
184
          if (! grub_msdos_partition_is_empty (e->type)
111
185
              && ! grub_msdos_partition_is_extended (e->type))
128
202
 
129
203
          if (grub_msdos_partition_is_extended (e->type))
130
204
            {
131
 
              p.offset = ext_offset + grub_le_to_cpu32 (e->start);
 
205
              p.offset = ext_offset
 
206
                + (grub_le_to_cpu32 (e->start)
 
207
                   << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
132
208
              if (! ext_offset)
133
209
                ext_offset = p.offset;
134
210
 
148
224
#ifdef GRUB_UTIL
149
225
static grub_err_t
150
226
pc_partition_map_embed (struct grub_disk *disk, unsigned int *nsectors,
 
227
                        unsigned int max_nsectors,
151
228
                        grub_embed_type_t embed_type,
152
229
                        grub_disk_addr_t **sectors)
153
230
{
206
283
          e = mbr.entries + i;
207
284
 
208
285
          if (!grub_msdos_partition_is_empty (e->type)
209
 
              && end > offset + grub_le_to_cpu32 (e->start))
210
 
            end = offset + grub_le_to_cpu32 (e->start);
 
286
              && end > offset
 
287
              + (grub_le_to_cpu32 (e->start)
 
288
                 << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS)))
 
289
            end = offset + (grub_le_to_cpu32 (e->start)
 
290
                            << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
211
291
 
212
292
          /* If this is a GPT partition, this MBR is just a dummy.  */
213
293
          if (e->type == GRUB_PC_PARTITION_TYPE_GPT_DISK && i == 0)
221
301
 
222
302
          if (grub_msdos_partition_is_extended (e->type))
223
303
            {
224
 
              offset = ext_offset + grub_le_to_cpu32 (e->start);
 
304
              offset = ext_offset 
 
305
                + (grub_le_to_cpu32 (e->start) 
 
306
                   << (disk->log_sector_size - GRUB_DISK_SECTOR_BITS));
225
307
              if (! ext_offset)
226
308
                ext_offset = offset;
227
309
 
236
318
 
237
319
  if (end >= *nsectors + 2)
238
320
    {
239
 
      unsigned i;
 
321
      unsigned i, j;
 
322
      char *embed_signature_check;
 
323
      unsigned int orig_nsectors, avail_nsectors;
 
324
 
 
325
      orig_nsectors = *nsectors;
240
326
      *nsectors = end - 2;
 
327
      avail_nsectors = *nsectors;
 
328
      if (*nsectors > max_nsectors)
 
329
        *nsectors = max_nsectors;
241
330
      *sectors = grub_malloc (*nsectors * sizeof (**sectors));
242
331
      if (!*sectors)
243
332
        return grub_errno;
244
333
      for (i = 0; i < *nsectors; i++)
245
334
        (*sectors)[i] = 1 + i;
 
335
 
 
336
      /* Check for software that is already using parts of the embedding
 
337
       * area.
 
338
       */
 
339
      embed_signature_check = grub_malloc (GRUB_DISK_SECTOR_SIZE);
 
340
      for (i = 0; i < *nsectors; i++)
 
341
        {
 
342
          if (grub_disk_read (disk, (*sectors)[i], 0, GRUB_DISK_SECTOR_SIZE,
 
343
                              embed_signature_check))
 
344
            continue;
 
345
 
 
346
          for (j = 0; j < ARRAY_SIZE (embed_signatures); j++)
 
347
            if (! grub_memcmp (embed_signatures[j].signature,
 
348
                               embed_signature_check,
 
349
                               embed_signatures[j].signature_len))
 
350
              break;
 
351
          if (j == ARRAY_SIZE (embed_signatures))
 
352
            continue;
 
353
          grub_util_warn (_(message_warn[embed_signatures[j].type]),
 
354
                          (*sectors)[i], embed_signatures[j].name);
 
355
          avail_nsectors--;
 
356
          if (avail_nsectors < *nsectors)
 
357
            *nsectors = avail_nsectors;
 
358
 
 
359
          /* Avoid this sector.  */
 
360
          for (j = i; j < *nsectors; j++)
 
361
            (*sectors)[j]++;
 
362
 
 
363
          /* Have we run out of space?  */
 
364
          if (avail_nsectors < orig_nsectors)
 
365
            break;
 
366
 
 
367
          /* Make sure to check the next sector.  */
 
368
          i--;
 
369
        }
 
370
      grub_free (embed_signature_check);
 
371
 
 
372
      if (*nsectors < orig_nsectors)
 
373
        return grub_error (GRUB_ERR_OUT_OF_RANGE,
 
374
                           N_("other software is using the embedding area, and "
 
375
                              "there is not enough room for core.img.  Such "
 
376
                              "software is often trying to store data in a way "
 
377
                              "that avoids detection.  We recommend you "
 
378
                              "investigate"));
 
379
 
246
380
      return GRUB_ERR_NONE;
247
381
    }
248
382
 
249
383
  if (end <= 1)
250
384
    return grub_error (GRUB_ERR_FILE_NOT_FOUND,
251
 
                       "This msdos-style partition label has no "
252
 
                       "post-MBR gap; embedding won't be possible!");
 
385
                       N_("this msdos-style partition label has no "
 
386
                          "post-MBR gap; embedding won't be possible"));
253
387
 
254
388
  if (*nsectors > 62)
255
389
    return grub_error (GRUB_ERR_OUT_OF_RANGE,
256
 
                       "Your core.img is unusually large.  "
257
 
                       "It won't fit in the embedding area.");
 
390
                       N_("your core.img is unusually large.  "
 
391
                          "It won't fit in the embedding area"));
258
392
 
259
393
  return grub_error (GRUB_ERR_OUT_OF_RANGE,
260
 
                     "Your embedding area is unusually small.  "
261
 
                     "core.img won't fit in it.");
 
394
                     N_("your embedding area is unusually small.  "
 
395
                        "core.img won't fit in it."));
262
396
}
263
397
#endif
264
398